File tree Expand file tree Collapse file tree 5 files changed +172
-0
lines changed
apps/dashboard/src/app/(app)/(dashboard)/(bridge) Expand file tree Collapse file tree 5 files changed +172
-0
lines changed Original file line number Diff line number Diff line change 1+ "use client" ;
2+
3+ import { Button } from "@/components/ui/button" ;
4+ import { useDashboardRouter } from "@/lib/DashboardRouter" ;
5+ import { usePathname , useSearchParams } from "next/navigation" ;
6+ import { useCallback } from "react" ;
7+
8+ export type OnrampProvider = "stripe" | "coinbase" | "transak" ;
9+
10+ export const ProviderSelector : React . FC < { activeProvider : OnrampProvider } > = ( {
11+ activeProvider,
12+ } ) => {
13+ const pathname = usePathname ( ) ;
14+ const searchParams = useSearchParams ( ) ;
15+ const router = useDashboardRouter ( ) ;
16+
17+ const createPageURL = useCallback (
18+ ( provider : OnrampProvider ) => {
19+ const params = new URLSearchParams ( searchParams || undefined ) ;
20+ params . set ( "provider" , provider ) ;
21+ return `${ pathname } ?${ params . toString ( ) } ` ;
22+ } ,
23+ [ pathname , searchParams ] ,
24+ ) ;
25+
26+ const providers : OnrampProvider [ ] = [ "coinbase" , "stripe" , "transak" ] ;
27+
28+ return (
29+ < div className = "flex flex-row gap-2" >
30+ { providers . map ( ( p ) => (
31+ < Button
32+ key = { p }
33+ size = "sm"
34+ variant = { activeProvider === p ? "default" : "outline" }
35+ onClick = { ( ) => router . replace ( createPageURL ( p ) ) }
36+ className = "capitalize"
37+ >
38+ { p }
39+ </ Button >
40+ ) ) }
41+ </ div >
42+ ) ;
43+ } ;
Original file line number Diff line number Diff line change 1+ import {
2+ Table ,
3+ TableBody ,
4+ TableCell ,
5+ TableContainer ,
6+ TableHead ,
7+ TableHeader ,
8+ TableRow ,
9+ } from "@/components/ui/table" ;
10+ import { getOnrampCountrySupport } from "../../../../utils" ;
11+ import type { OnrampProvider } from "../client/provider" ;
12+
13+ export async function CountriesTable ( props : { provider : OnrampProvider } ) {
14+ const data = await getOnrampCountrySupport ( props . provider ) ;
15+ const countries = data . supportedCountries ;
16+
17+ return (
18+ < TableContainer className = "overflow-hidden rounded-xl border border-border/50 bg-card/50 shadow-sm transition-all" >
19+ < Table >
20+ < TableHeader className = "z-0" >
21+ < TableRow className = "border-border/50 border-b bg-muted/50" >
22+ < TableHead className = "py-4 font-medium text-muted-foreground/80 text-xs uppercase tracking-wider" >
23+ Country
24+ </ TableHead >
25+ < TableHead className = "py-4 font-medium text-muted-foreground/80 text-xs uppercase tracking-wider" >
26+ Currencies
27+ </ TableHead >
28+ </ TableRow >
29+ </ TableHeader >
30+ < TableBody >
31+ { countries . map ( ( country ) => (
32+ < TableRow key = { country . code } className = "hover:bg-accent/50" >
33+ < TableCell className = "font-medium" > { country . name } </ TableCell >
34+ < TableCell className = "text-muted-foreground" >
35+ { country . currencies . join ( ", " ) }
36+ </ TableCell >
37+ </ TableRow >
38+ ) ) }
39+ </ TableBody >
40+ </ Table >
41+ </ TableContainer >
42+ ) ;
43+ }
Original file line number Diff line number Diff line change 1+ import type { Metadata } from "next" ;
2+ import {
3+ type OnrampProvider ,
4+ ProviderSelector ,
5+ } from "./components/client/provider" ;
6+ import { CountriesTable } from "./components/server/countries-table" ;
7+
8+ const title = "Onramp Country Support" ;
9+ const description = "Countries and currencies supported by onramp providers." ;
10+
11+ export const metadata : Metadata = {
12+ title,
13+ description,
14+ openGraph : {
15+ title,
16+ description,
17+ } ,
18+ } ;
19+
20+ export default async function OnrampCountriesPage ( props : {
21+ searchParams : Promise < { provider ?: OnrampProvider } > ;
22+ } ) {
23+ const searchParams = await props . searchParams ;
24+ const activeProvider : OnrampProvider =
25+ ( searchParams . provider as OnrampProvider ) || "coinbase" ;
26+
27+ return (
28+ < section className = "container mx-auto flex h-full flex-col px-4 py-10" >
29+ < header className = "flex flex-col gap-6" >
30+ < div className = "flex flex-col gap-6 lg:flex-row lg:items-center lg:justify-between" >
31+ < div className = "flex flex-col gap-2" >
32+ < h1 className = "font-semibold text-4xl tracking-tighter lg:text-5xl" >
33+ Onramp Countries
34+ </ h1 >
35+ </ div >
36+ < div className = "flex flex-row items-end gap-4 lg:flex-col" >
37+ < div className = "flex w-full flex-row items-center gap-4" >
38+ < ProviderSelector activeProvider = { activeProvider } />
39+ </ div >
40+ </ div >
41+ </ div >
42+ </ header >
43+ < div className = "h-10" />
44+ < CountriesTable provider = { activeProvider } />
45+ </ section >
46+ ) ;
47+ }
Original file line number Diff line number Diff line change 1+ export type OnrampCountryToken = {
2+ chainId : number ;
3+ address : string ;
4+ symbol : string ;
5+ } ;
6+
7+ export type OnrampCountryDetails = {
8+ code : string ;
9+ name : string ;
10+ currencies : string [ ] ;
11+ tokens : OnrampCountryToken [ ] ;
12+ } ;
13+
14+ export type OnrampCountrySupport = {
15+ provider : "stripe" | "coinbase" | "transak" ;
16+ supportedCountries : OnrampCountryDetails [ ] ;
17+ } ;
Original file line number Diff line number Diff line change @@ -68,3 +68,25 @@ export async function getRoutes({
6868
6969 return routes ;
7070}
71+
72+ export async function getOnrampCountrySupport (
73+ provider : "stripe" | "coinbase" | "transak" ,
74+ ) {
75+ const url = new URL (
76+ `${ NEXT_PUBLIC_THIRDWEB_BRIDGE_HOST } /v1/onramp/countries` ,
77+ ) ;
78+ url . searchParams . set ( "provider" , provider ) ;
79+ const res = await fetch ( url . toString ( ) , {
80+ headers : {
81+ "x-secret-key" : DASHBOARD_THIRDWEB_SECRET_KEY ,
82+ } ,
83+ next : { revalidate : 60 * 60 } ,
84+ } ) ;
85+
86+ if ( ! res . ok ) {
87+ throw new Error ( "Failed to fetch onramp countries" ) ;
88+ }
89+
90+ const json = await res . json ( ) ;
91+ return json . data as import ( "./types/onramp-country" ) . OnrampCountrySupport ;
92+ }
You can’t perform that action at this time.
0 commit comments