Skip to content

Commit cba749e

Browse files
committed
feat: display expired quotes
1 parent e43c155 commit cba749e

File tree

4 files changed

+163
-1
lines changed

4 files changed

+163
-1
lines changed

src/components/AppSidebar.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ const data = {
5151
{
5252
title: "Expired",
5353
url: "/quotes/expired",
54-
disabled: true,
5554
},
5655
],
5756
},

src/main.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import EarningsPage from "./pages/balances/EarningsPage"
1818
import CashFlowPage from "./pages/balances/CashFlowPage"
1919
import OfferedQuotesPage from "./pages/quotes/OfferedQuotesPage"
2020
import DeniedQuotesPage from "./pages/quotes/DeniedQuotesPage"
21+
import ExpiredQuotesPage from "./pages/quotes/ExpiredQuotesPage"
2122

2223
const queryClient = new QueryClient()
2324

@@ -44,6 +45,7 @@ void prepare().then(() => {
4445
<Route path="quotes/accepted" element={<AcceptedQuotesPage />} />
4546
<Route path="quotes/offered" element={<OfferedQuotesPage />} />
4647
<Route path="quotes/denied" element={<DeniedQuotesPage />} />
48+
<Route path="quotes/expired" element={<ExpiredQuotesPage />} />
4749
<Route path="quotes/:id" element={<QuotePage />} />
4850
<Route path="settings" element={<SettingsPage />} />
4951
<Route path="info" element={<InfoPage />} />
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { Breadcrumbs } from "@/components/Breadcrumbs"
2+
import { PageTitle } from "@/components/PageTitle"
3+
import { Button } from "@/components/ui/button"
4+
import { Skeleton } from "@/components/ui/skeleton"
5+
import { ListQuotesData } from "@/generated/client"
6+
import { listQuotesOptions } from "@/generated/client/@tanstack/react-query.gen"
7+
import useLocalStorage from "@/hooks/use-local-storage"
8+
import { cn } from "@/lib/utils"
9+
import { useSuspenseQuery } from "@tanstack/react-query"
10+
import { LoaderIcon } from "lucide-react"
11+
import { Suspense } from "react"
12+
import { Link, useNavigate } from "react-router"
13+
14+
function Loader() {
15+
return (
16+
<div className="flex flex-col gap-1.5 py-2">
17+
<Skeleton className="h-4 rounded-lg" />
18+
<Skeleton className="h-16 rounded-lg" />
19+
<Skeleton className="h-16 rounded-lg" />
20+
<Skeleton className="h-16 rounded-lg" />
21+
<Skeleton className="h-16 rounded-lg" />
22+
<Skeleton className="h-16 rounded-lg" />
23+
</div>
24+
)
25+
}
26+
27+
function QuoteListExpired() {
28+
const navigate = useNavigate()
29+
30+
const { data, isFetching } = useSuspenseQuery({
31+
...listQuotesOptions({
32+
query: {
33+
status: "expired",
34+
} as unknown as ListQuotesData["query"],
35+
}),
36+
})
37+
38+
return (
39+
<>
40+
<div className="flex items-center gap-1">
41+
<LoaderIcon
42+
className={cn("stroke-1 animate-spin", {
43+
"animate-spin": isFetching,
44+
invisible: !isFetching,
45+
})}
46+
/>
47+
</div>
48+
49+
<div className="flex flex-col gap-1 my-2">
50+
{data.quotes.length === 0 && <div className="py-2 font-bold">No expired quotes.</div>}
51+
{data.quotes.map((it, index) => {
52+
return (
53+
<div key={index} className="flex gap-1 items-center text-sm">
54+
<span className="font-mono">
55+
{isFetching ? (
56+
<>{it.id}</>
57+
) : (
58+
<>
59+
<Link to={"/quotes/:id".replace(":id", it.id)}>{it.id}</Link>
60+
</>
61+
)}
62+
</span>
63+
64+
<Button
65+
size="sm"
66+
disabled={isFetching}
67+
onClick={() => {
68+
void navigate("/quotes/:id".replace(":id", it.id))
69+
}}
70+
>
71+
View
72+
</Button>
73+
</div>
74+
)
75+
})}
76+
</div>
77+
</>
78+
)
79+
}
80+
81+
function DevSection() {
82+
const [devMode] = useLocalStorage("devMode", false)
83+
84+
const { data: quotesExpired } = useSuspenseQuery({
85+
...listQuotesOptions({
86+
query: {
87+
status: "expired",
88+
} as unknown as ListQuotesData["query"],
89+
}),
90+
})
91+
92+
return (
93+
<>
94+
{devMode && (
95+
<>
96+
<pre className="text-sm bg-accent text-accent-foreground rounded-lg p-2 my-2">
97+
{JSON.stringify(quotesExpired, null, 2)}
98+
</pre>
99+
</>
100+
)}
101+
</>
102+
)
103+
}
104+
105+
function PageBody() {
106+
return (
107+
<div className="flex flex-col gap-2">
108+
<div>
109+
<QuoteListExpired />
110+
</div>
111+
</div>
112+
)
113+
}
114+
115+
export default function ExpiredQuotesPage() {
116+
return (
117+
<>
118+
<Breadcrumbs
119+
parents={[
120+
<>
121+
<Link to="/quotes">Quotes</Link>
122+
</>,
123+
]}
124+
>
125+
Expired
126+
</Breadcrumbs>
127+
<PageTitle>Expired Quotes</PageTitle>
128+
<Suspense fallback={<Loader />}>
129+
<PageBody />
130+
</Suspense>
131+
<Suspense>
132+
<DevSection />
133+
</Suspense>
134+
</>
135+
)
136+
}

src/pages/quotes/QuotesPage.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ function Loader() {
1616
<Skeleton className="h-32 rounded-lg" />
1717
<Skeleton className="h-32 rounded-lg" />
1818
<Skeleton className="h-32 rounded-lg" />
19+
<Skeleton className="h-32 rounded-lg" />
20+
<Skeleton className="h-32 rounded-lg" />
1921
</div>
2022
)
2123
}
@@ -49,6 +51,14 @@ function PageBody() {
4951
}),
5052
})
5153

54+
const { data: quotesExpired } = useSuspenseQuery({
55+
...listQuotesOptions({
56+
query: {
57+
status: "expired",
58+
} as unknown as ListQuotesData["query"],
59+
}),
60+
})
61+
5262
return (
5363
<div className="flex flex-col gap-1.5 my-2">
5464
<Link to={"/quotes/pending"}>
@@ -122,6 +132,21 @@ function PageBody() {
122132
</div>
123133
</Card>
124134
</Link>
135+
<Link to={"/quotes/expired"}>
136+
<Card className="flex-1 self-stretch">
137+
<div className="flex items-center">
138+
<div className="flex-1 flex flex-col justify-center">
139+
<CardHeader>
140+
<CardTitle>Expired quotes</CardTitle>
141+
</CardHeader>
142+
<CardContent className="text-2xl">{quotesExpired.quotes.length} expired</CardContent>
143+
</div>
144+
<div className="flex p-8">
145+
<ChevronRight size={48} className="text-neutral-400" />
146+
</div>
147+
</div>
148+
</Card>
149+
</Link>
125150
</div>
126151
)
127152
}

0 commit comments

Comments
 (0)