Commit
·
7663767
1
Parent(s):
d90c730
- src/App.tsx +27 -20
src/App.tsx
CHANGED
|
@@ -9,6 +9,11 @@ import { Button } from '@/components/ui/button'
|
|
| 9 |
import { ChevronDown, ChevronRight } from 'lucide-react'
|
| 10 |
import { mockData } from './lib/data'
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
export interface Model {
|
| 13 |
name: string
|
| 14 |
inputPrice: number
|
|
@@ -44,6 +49,16 @@ const App: React.FC = () => {
|
|
| 44 |
return (((modelPrice - comparisonPrice) / comparisonPrice) * 100).toFixed(2)
|
| 45 |
}
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
const filteredData = data
|
| 48 |
.filter((provider) => selectedProviders.length === 0 || selectedProviders.includes(provider.provider))
|
| 49 |
.map((provider) => ({
|
|
@@ -52,24 +67,19 @@ const App: React.FC = () => {
|
|
| 52 |
}))
|
| 53 |
.filter((provider) => provider.models.length > 0)
|
| 54 |
|
| 55 |
-
const
|
| 56 |
-
|
| 57 |
-
provider.models.map(model => ({
|
| 58 |
-
provider: provider.provider,
|
| 59 |
-
uri: provider.uri,
|
| 60 |
-
...model
|
| 61 |
-
}))
|
| 62 |
-
);
|
| 63 |
}
|
| 64 |
|
| 65 |
const sortedFlattenedData = React.useMemo(() => {
|
| 66 |
-
let sortableData = flattenData(filteredData);
|
| 67 |
if (sortConfig !== null) {
|
| 68 |
sortableData.sort((a, b) => {
|
| 69 |
-
|
|
|
|
| 70 |
return sortConfig.direction === 'ascending' ? -1 : 1;
|
| 71 |
}
|
| 72 |
-
if (a[
|
| 73 |
return sortConfig.direction === 'ascending' ? 1 : -1;
|
| 74 |
}
|
| 75 |
return 0;
|
|
@@ -78,9 +88,10 @@ const App: React.FC = () => {
|
|
| 78 |
return sortableData;
|
| 79 |
}, [filteredData, sortConfig]);
|
| 80 |
|
| 81 |
-
|
|
|
|
| 82 |
const reassembledData = sortedFlattenedData.reduce((acc, item) => {
|
| 83 |
-
const providerIndex = acc.findIndex(provider => provider.provider === item.provider);
|
| 84 |
if (providerIndex === -1) {
|
| 85 |
acc.push({
|
| 86 |
provider: item.provider,
|
|
@@ -91,9 +102,9 @@ const App: React.FC = () => {
|
|
| 91 |
acc[providerIndex].models.push({ name: item.name, inputPrice: item.inputPrice, outputPrice: item.outputPrice });
|
| 92 |
}
|
| 93 |
return acc;
|
| 94 |
-
}, []);
|
| 95 |
return reassembledData;
|
| 96 |
-
}
|
| 97 |
|
| 98 |
const sortedData = reassembleData(sortedFlattenedData);
|
| 99 |
|
|
@@ -107,10 +118,6 @@ const App: React.FC = () => {
|
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
-
const toggleProviderExpansion = (provider: string) => {
|
| 111 |
-
setExpandedProviders((prev) => (prev.includes(provider) ? prev.filter((p) => p !== provider) : [...prev, provider]))
|
| 112 |
-
}
|
| 113 |
-
|
| 114 |
return (
|
| 115 |
<Card className="w-full max-w-6xl mx-auto">
|
| 116 |
<CardHeader>
|
|
@@ -262,7 +269,7 @@ const App: React.FC = () => {
|
|
| 262 |
</TableRow>
|
| 263 |
</TableHeader>
|
| 264 |
<TableBody>
|
| 265 |
-
{sortedData.flatMap((provider) =>
|
| 266 |
provider.models.map((model) => (
|
| 267 |
<TableRow key={`${provider.provider}-${model.name}`}>
|
| 268 |
<TableCell>
|
|
|
|
| 9 |
import { ChevronDown, ChevronRight } from 'lucide-react'
|
| 10 |
import { mockData } from './lib/data'
|
| 11 |
|
| 12 |
+
interface FlattenedModel extends Model {
|
| 13 |
+
provider: string;
|
| 14 |
+
uri: string;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
export interface Model {
|
| 18 |
name: string
|
| 19 |
inputPrice: number
|
|
|
|
| 49 |
return (((modelPrice - comparisonPrice) / comparisonPrice) * 100).toFixed(2)
|
| 50 |
}
|
| 51 |
|
| 52 |
+
const flattenData = (data: Provider[]) => {
|
| 53 |
+
return data.flatMap(provider =>
|
| 54 |
+
provider.models.map(model => ({
|
| 55 |
+
provider: provider.provider,
|
| 56 |
+
uri: provider.uri,
|
| 57 |
+
...model
|
| 58 |
+
}))
|
| 59 |
+
);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
const filteredData = data
|
| 63 |
.filter((provider) => selectedProviders.length === 0 || selectedProviders.includes(provider.provider))
|
| 64 |
.map((provider) => ({
|
|
|
|
| 67 |
}))
|
| 68 |
.filter((provider) => provider.models.length > 0)
|
| 69 |
|
| 70 |
+
const toggleProviderExpansion = (provider: string) => {
|
| 71 |
+
setExpandedProviders((prev) => (prev.includes(provider) ? prev.filter((p) => p !== provider) : [...prev, provider]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
}
|
| 73 |
|
| 74 |
const sortedFlattenedData = React.useMemo(() => {
|
| 75 |
+
let sortableData: FlattenedModel[] = flattenData(filteredData);
|
| 76 |
if (sortConfig !== null) {
|
| 77 |
sortableData.sort((a, b) => {
|
| 78 |
+
const key = sortConfig.key as keyof FlattenedModel;
|
| 79 |
+
if (a[key] < b[key]) {
|
| 80 |
return sortConfig.direction === 'ascending' ? -1 : 1;
|
| 81 |
}
|
| 82 |
+
if (a[key] > b[key]) {
|
| 83 |
return sortConfig.direction === 'ascending' ? 1 : -1;
|
| 84 |
}
|
| 85 |
return 0;
|
|
|
|
| 88 |
return sortableData;
|
| 89 |
}, [filteredData, sortConfig]);
|
| 90 |
|
| 91 |
+
|
| 92 |
+
const reassembleData = (sortedFlattenedData: any[]) => {
|
| 93 |
const reassembledData = sortedFlattenedData.reduce((acc, item) => {
|
| 94 |
+
const providerIndex = acc.findIndex((provider: { provider: any }) => provider.provider === item.provider);
|
| 95 |
if (providerIndex === -1) {
|
| 96 |
acc.push({
|
| 97 |
provider: item.provider,
|
|
|
|
| 102 |
acc[providerIndex].models.push({ name: item.name, inputPrice: item.inputPrice, outputPrice: item.outputPrice });
|
| 103 |
}
|
| 104 |
return acc;
|
| 105 |
+
}, [] as Provider[]);
|
| 106 |
return reassembledData;
|
| 107 |
+
};
|
| 108 |
|
| 109 |
const sortedData = reassembleData(sortedFlattenedData);
|
| 110 |
|
|
|
|
| 118 |
|
| 119 |
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
return (
|
| 122 |
<Card className="w-full max-w-6xl mx-auto">
|
| 123 |
<CardHeader>
|
|
|
|
| 269 |
</TableRow>
|
| 270 |
</TableHeader>
|
| 271 |
<TableBody>
|
| 272 |
+
{sortedData.flatMap((provider: { models: any[]; provider: string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | null | undefined; uri: string | undefined }) =>
|
| 273 |
provider.models.map((model) => (
|
| 274 |
<TableRow key={`${provider.provider}-${model.name}`}>
|
| 275 |
<TableCell>
|