CrispStrobe commited on
Commit
d699da8
·
1 Parent(s): c3fc087

feat: implement 5 granular jurisdiction filters and shorten table labels

Browse files
Files changed (2) hide show
  1. src/App.css +5 -5
  2. src/App.tsx +20 -10
src/App.css CHANGED
@@ -188,11 +188,11 @@ tr.group-divider {
188
  }
189
 
190
  /* Jurisdiction Colors */
191
- .eu--sovereign- { background-color: #dcfce7; color: #166534; }
192
- .non-eu--eea-swiss- { background-color: #fef9c3; color: #854d0e; }
193
- .us--eu-endpoint---cloud-act- { background-color: #ffedd5; color: #9a3412; }
194
- .us--global---cloud-act- { background-color: #fee2e2; color: #991b1b; }
195
- .other-non-eu { background-color: #f1f5f9; color: #475569; }
196
 
197
  footer {
198
  margin-top: 2rem;
 
188
  }
189
 
190
  /* Jurisdiction Colors */
191
+ .eu { background-color: #dcfce7; color: #166534; }
192
+ .eea { background-color: #fef9c3; color: #854d0e; }
193
+ .us-eu { background-color: #ffedd5; color: #9a3412; }
194
+ .us { background-color: #fee2e2; color: #991b1b; }
195
+ .other { background-color: #f1f5f9; color: #475569; }
196
 
197
  footer {
198
  margin-top: 2rem;
src/App.tsx CHANGED
@@ -90,6 +90,7 @@ const CAP_ICON: Record<string, string> = {
90
  tools: '🔧',
91
  reasoning: '💡',
92
  embedding: '🧩',
 
93
  }
94
 
95
  function App() {
@@ -208,25 +209,28 @@ function App() {
208
  setDataVersion((v) => v + 1);
209
  }, []);
210
 
211
- const getComplianceStatus = (provider: Provider) => {
212
  const hq = provider.headquarters.toLowerCase();
213
  const isEU = provider.region === 'EU' || hq === 'germany' || hq === 'france' || hq === 'netherlands';
214
- const isUS = hq === 'usa';
215
  const isEEA = provider.region === 'EEA Equivalent' || hq === 'switzerland';
216
 
217
- if (isEU) return 'EU (Sovereign)';
218
- if (isEEA) return 'Non-EU (EEA/Swiss)';
219
- if (isUS && provider.eu_endpoints) return 'US (EU Endpoint / Cloud Act)';
220
- if (isUS) return 'US (Global / Cloud Act)';
221
- return 'Other Non-EU';
 
 
 
222
  };
223
 
224
  const allModels = useMemo(() => {
225
  const rawModels: (Model & { provider: Provider; complianceStatus: string })[] = []
226
 
227
  liveProviders.forEach((provider: Provider) => {
228
- const status = getComplianceStatus(provider);
229
  provider.models.forEach((model) => {
 
230
  let cleanName = model.name;
231
  // Strip provider/ prefix for all models
232
  if (cleanName.includes('/')) {
@@ -259,7 +263,11 @@ function App() {
259
  const matchesSearch = model.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
260
  model.provider.name.toLowerCase().includes(searchTerm.toLowerCase())
261
  const matchesType = selectedType === 'all' || model.type === selectedType
262
- const matchesRegion = selectedRegion === 'all' || model.complianceStatus.includes(selectedRegion)
 
 
 
 
263
  return matchesSearch && matchesType && matchesRegion
264
  })
265
  }, [searchTerm, selectedType, selectedRegion, allModels])
@@ -429,8 +437,10 @@ function App() {
429
  <select value={selectedRegion} onChange={(e) => setSelectedRegion(e.target.value)} className="type-select">
430
  <option value="all">All Jurisdictions</option>
431
  <option value="EU">EU (Sovereign)</option>
432
- <option value="Non-EU">Non-EU (Swiss/EEA)</option>
 
433
  <option value="US">US (Cloud Act)</option>
 
434
  </select>
435
  <label className="checkbox-label">
436
  <input
 
90
  tools: '🔧',
91
  reasoning: '💡',
92
  embedding: '🧩',
93
+ 'eu-endpoint': '🇪🇺',
94
  }
95
 
96
  function App() {
 
209
  setDataVersion((v) => v + 1);
210
  }, []);
211
 
212
+ const getComplianceStatus = (provider: Provider, model?: Model) => {
213
  const hq = provider.headquarters.toLowerCase();
214
  const isEU = provider.region === 'EU' || hq === 'germany' || hq === 'france' || hq === 'netherlands';
215
+ const isUS = hq === 'usa' || provider.region === 'US';
216
  const isEEA = provider.region === 'EEA Equivalent' || hq === 'switzerland';
217
 
218
+ // Model-level override for OpenRouter or similar aggregators
219
+ const hasEuEndpoint = model?.capabilities?.includes('eu-endpoint') || provider.eu_endpoints;
220
+
221
+ if (isEU) return 'EU';
222
+ if (isEEA) return 'EEA';
223
+ if (isUS && hasEuEndpoint) return 'US/EU';
224
+ if (isUS) return 'US';
225
+ return 'Other';
226
  };
227
 
228
  const allModels = useMemo(() => {
229
  const rawModels: (Model & { provider: Provider; complianceStatus: string })[] = []
230
 
231
  liveProviders.forEach((provider: Provider) => {
 
232
  provider.models.forEach((model) => {
233
+ const status = getComplianceStatus(provider, model);
234
  let cleanName = model.name;
235
  // Strip provider/ prefix for all models
236
  if (cleanName.includes('/')) {
 
263
  const matchesSearch = model.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
264
  model.provider.name.toLowerCase().includes(searchTerm.toLowerCase())
265
  const matchesType = selectedType === 'all' || model.type === selectedType
266
+
267
+ let matchesRegion = selectedRegion === 'all' || model.complianceStatus === selectedRegion;
268
+ // US filter includes US/EU
269
+ if (selectedRegion === 'US' && model.complianceStatus === 'US/EU') matchesRegion = true;
270
+
271
  return matchesSearch && matchesType && matchesRegion
272
  })
273
  }, [searchTerm, selectedType, selectedRegion, allModels])
 
437
  <select value={selectedRegion} onChange={(e) => setSelectedRegion(e.target.value)} className="type-select">
438
  <option value="all">All Jurisdictions</option>
439
  <option value="EU">EU (Sovereign)</option>
440
+ <option value="EEA">EEA (Swiss/EEA)</option>
441
+ <option value="US/EU">US/EU (EU Endpoint)</option>
442
  <option value="US">US (Cloud Act)</option>
443
+ <option value="Other">Other</option>
444
  </select>
445
  <label className="checkbox-label">
446
  <input