@@ -59,7 +59,6 @@ export default function JurisdictionDetail({ jurisdiction }: JurisdictionDetailP
5959 . sort ( ( [ , a ] , [ , b ] ) => b - a )
6060 . slice ( 0 , 5 ) ;
6161
62- // Top companies by fine — include outcome
6362 const topCompanies = [ ...jCases ]
6463 . sort ( ( a , b ) => b . fineAmount - a . fineAmount )
6564 . slice ( 0 , 5 )
@@ -96,41 +95,14 @@ export default function JurisdictionDetail({ jurisdiction }: JurisdictionDetailP
9695 </ div >
9796
9897 < div className = "p-6 space-y-10" >
99- { /* Overview */ }
98+ { /* 1. Overview */ }
10099 < section >
101100 < h2 className = "text-2xl font-bold tracking-tight mb-4" > \ OVERVIEW</ h2 >
102101 < div className = "h-[3px] bg-border mb-4" />
103102 < p className = "text-[15px] leading-relaxed" > { info . overview } </ p >
104103 </ section >
105104
106- { /* Severity Snapshot — yellow detail boxes matching CaseDetail */ }
107- < section >
108- < h2 className = "text-2xl font-bold tracking-tight mb-4" > \ SEVERITY SNAPSHOT</ h2 >
109- < div className = "h-[3px] bg-border mb-4" />
110- < div className = "grid grid-cols-2 md:grid-cols-4 gap-4" >
111- < div className = "detail-yellow-box p-4" >
112- < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > Total Fines</ p >
113- < p className = "text-lg font-bold mt-1" > { formatCurrency ( stats . totalFines ) } </ p >
114- </ div >
115- < div className = "detail-yellow-box p-4" >
116- < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > Largest Fine</ p >
117- < p className = "text-lg font-bold mt-1" > { formatCurrency ( stats . maxFine ) } </ p >
118- </ div >
119- < div className = "detail-yellow-box p-4" >
120- < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > Avg Fine</ p >
121- < p className = "text-lg font-bold mt-1" > { formatCurrency ( stats . avgFine ) } </ p >
122- </ div >
123- < div className = "detail-yellow-box p-4" >
124- < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > % Monetary</ p >
125- < p className = "text-lg font-bold mt-1" > { stats . pctMonetary } %</ p >
126- </ div >
127- </ div >
128- < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mt-3" >
129- { stats . totalCases } cases · { stats . minYear } –{ stats . maxYear }
130- </ p >
131- </ section >
132-
133- { /* Enforcement Style */ }
105+ { /* 2. Enforcement Style */ }
134106 < section >
135107 < h2 className = "text-2xl font-bold tracking-tight mb-4" > \ ENFORCEMENT STYLE</ h2 >
136108 < div className = "h-[3px] bg-border mb-4" />
@@ -139,7 +111,7 @@ export default function JurisdictionDetail({ jurisdiction }: JurisdictionDetailP
139111 </ div >
140112 </ section >
141113
142- { /* Main Privacy Laws — loot-drop accordion */ }
114+ { /* 3. Main Privacy Laws — loot-drop accordion */ }
143115 < section >
144116 < button
145117 type = "button"
@@ -166,81 +138,48 @@ export default function JurisdictionDetail({ jurisdiction }: JurisdictionDetailP
166138 ) }
167139 </ section >
168140
169- { /* Stats Grid */ }
141+ < div className = "border-t-2 border-dashed border-border" />
142+
143+ { /* 4. From Our Dataset — contains severity snapshot + bar charts + table */ }
170144 < section >
171145 < h2 className = "text-2xl font-bold tracking-tight mb-4" > \ FROM OUR DATASET</ h2 >
172- < div className = "h-[3px] bg-border mb-6" />
146+ < div className = "h-[3px] bg-border mb-4" />
147+ < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mb-6" >
148+ { stats . totalCases } cases · { stats . minYear } –{ stats . maxYear }
149+ </ p >
173150
174- < div className = "grid grid-cols-1 md:grid-cols-2 gap-8" >
175- { /* Top Sectors */ }
176- < div >
177- < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mb-3" > Top Sectors Affected</ p >
178- < div className = "space-y-3" >
179- { stats . topSectors . map ( ( [ sector , count ] ) => {
180- const pct = stats . totalCases > 0 ? ( count / stats . totalCases ) * 100 : 0 ;
181- return (
182- < div key = { sector } >
183- < div className = "flex items-baseline justify-between mb-1" >
184- < span className = "text-sm font-bold truncate" > { sector } </ span >
185- < span className = "text-xs font-mono font-bold ml-2 shrink-0" > { count } </ span >
186- </ div >
187- < div className = "h-2.5 bg-border overflow-hidden" >
188- < div className = "h-full bg-black transition-all duration-500" style = { { width : `${ pct } %` } } />
189- </ div >
190- </ div >
191- ) ;
192- } ) }
193- </ div >
151+ { /* Severity Snapshot */ }
152+ < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mb-3" > Severity Snapshot</ p >
153+ < div className = "grid grid-cols-2 md:grid-cols-4 gap-4 mb-8" >
154+ < div className = "detail-yellow-box p-4" >
155+ < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > Total Fines</ p >
156+ < p className = "text-lg font-bold mt-1" > { formatCurrency ( stats . totalFines ) } </ p >
194157 </ div >
195-
196- { /* Most Common Violations */ }
197- < div >
198- < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mb-3" > Most Common Violations</ p >
199- < div className = "space-y-3" >
200- { stats . topViolations . map ( ( [ violation , count ] ) => {
201- const pct = stats . totalCases > 0 ? ( count / stats . totalCases ) * 100 : 0 ;
202- return (
203- < div key = { violation } >
204- < div className = "flex items-baseline justify-between mb-1" >
205- < span className = "text-sm font-bold truncate" > { violation } </ span >
206- < span className = "text-xs font-mono font-bold ml-2 shrink-0" > { count } </ span >
207- </ div >
208- < div className = "h-2.5 bg-border overflow-hidden" >
209- < div className = "h-full bg-black transition-all duration-500" style = { { width : `${ pct } %` } } />
210- </ div >
211- </ div >
212- ) ;
213- } ) }
214- </ div >
158+ < div className = "detail-yellow-box p-4" >
159+ < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > Largest Fine</ p >
160+ < p className = "text-lg font-bold mt-1" > { formatCurrency ( stats . maxFine ) } </ p >
161+ </ div >
162+ < div className = "detail-yellow-box p-4" >
163+ < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > Avg Fine</ p >
164+ < p className = "text-lg font-bold mt-1" > { formatCurrency ( stats . avgFine ) } </ p >
165+ </ div >
166+ < div className = "detail-yellow-box p-4" >
167+ < p className = "text-[10px] font-mono font-bold uppercase tracking-wider text-muted-foreground" > % Monetary</ p >
168+ < p className = "text-lg font-bold mt-1" > { stats . pctMonetary } %</ p >
215169 </ div >
170+ </ div >
216171
217- { /* Most Common Outcomes */ }
172+ { /* Bar charts grid */ }
173+ < div className = "grid grid-cols-1 md:grid-cols-2 gap-8 mb-8" >
174+ < BarSection title = "Top Sectors Affected" data = { stats . topSectors } total = { stats . totalCases } />
175+ < BarSection title = "Most Common Violations" data = { stats . topViolations } total = { stats . totalCases } />
218176 < div className = "md:col-span-2" >
219- < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mb-3" > Most Common Outcomes</ p >
220- < div className = "space-y-3" >
221- { stats . topOutcomes . map ( ( [ outcome , count ] ) => {
222- const pct = stats . totalCases > 0 ? ( count / stats . totalCases ) * 100 : 0 ;
223- return (
224- < div key = { outcome } >
225- < div className = "flex items-baseline justify-between mb-1" >
226- < span className = "text-sm font-bold truncate" > { outcome } </ span >
227- < span className = "text-xs font-mono font-bold ml-2 shrink-0" > { count } </ span >
228- </ div >
229- < div className = "h-2.5 bg-border overflow-hidden" >
230- < div className = "h-full bg-black transition-all duration-500" style = { { width : `${ pct } %` } } />
231- </ div >
232- </ div >
233- ) ;
234- } ) }
235- </ div >
177+ < BarSection title = "Most Common Outcomes" data = { stats . topOutcomes } total = { stats . totalCases } />
236178 </ div >
237179 </ div >
238- </ section >
239180
240- { /* Top Companies */ }
241- < section >
242- < h2 className = "text-2xl font-bold tracking-tight mb-4" > \ TOP COMPANIES</ h2 >
243- < div className = "h-[3px] bg-border mb-4" />
181+ { /* Top Companies table */ }
182+ < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mb-3" > Top Companies</ p >
244183 < div className = "border-2 border-black" >
245184 < table className = "w-full text-sm" >
246185 < thead >
@@ -266,3 +205,30 @@ export default function JurisdictionDetail({ jurisdiction }: JurisdictionDetailP
266205 </ div >
267206 ) ;
268207}
208+
209+ /** Bar chart section with a label header and proportional bars */
210+ function BarSection ( { title, data, total } : { title : string ; data : [ string , number ] [ ] ; total : number } ) {
211+ const maxCount = data . length > 0 ? data [ 0 ] [ 1 ] : 1 ;
212+ return (
213+ < div >
214+ < p className = "text-[10px] font-mono font-bold uppercase tracking-widest text-muted-foreground mb-3" > { title } </ p >
215+ < div className = "space-y-3" >
216+ { data . map ( ( [ label , count ] ) => {
217+ // Bar width relative to the largest item so bars are visually distinct
218+ const barPct = maxCount > 0 ? ( count / maxCount ) * 100 : 0 ;
219+ return (
220+ < div key = { label } >
221+ < div className = "flex items-baseline justify-between mb-1" >
222+ < span className = "text-sm font-bold truncate" > { label } </ span >
223+ < span className = "text-xs font-mono font-bold ml-2 shrink-0" > { count } </ span >
224+ </ div >
225+ < div className = "h-2.5 overflow-hidden" style = { { backgroundColor : "#e5e5e5" } } >
226+ < div className = "h-full bg-black transition-all duration-500" style = { { width : `${ barPct } %` } } />
227+ </ div >
228+ </ div >
229+ ) ;
230+ } ) }
231+ </ div >
232+ </ div >
233+ ) ;
234+ }
0 commit comments