Skip to content

Commit

Permalink
feat: network switching
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickDinh authored May 23, 2024
1 parent d06fd8a commit 23daaec
Show file tree
Hide file tree
Showing 15 changed files with 202 additions and 20 deletions.
5 changes: 5 additions & 0 deletions src/App.routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { InnerTransactionPage } from './features/transactions/pages/inner-transa
import { AccountPage, accountPageTitle } from './features/accounts/pages/account-page'
import { AssetPage, assetPageTitle } from './features/assets/pages/asset-page'
import { ApplicationPage, applicationPageTitle } from './features/applications/pages/application-page'
import { SettingsPage } from './features/settings/pages/settings-page'

export const routes = evalTemplates([
{
Expand Down Expand Up @@ -88,6 +89,10 @@ export const routes = evalTemplates([
template: Urls.AppStudio,
element: <div>App Studio</div>,
},
{
template: Urls.Settings,
element: <SettingsPage />,
},
],
},
])
9 changes: 6 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import { RouterProvider, createBrowserRouter } from 'react-router-dom'
import { ThemeProvider } from './features/theme/context/theme-provider'
import { LayoutProvider } from './features/layout/context/layout-provider'
import { TooltipProvider } from './features/common/components/tooltip'
import { SettingsProvider } from './features/settings/components/settings-provider'

const router = createBrowserRouter(routes)

function App() {
return (
<ThemeProvider defaultTheme="system" storageKey="vite-ui-theme">
<TooltipProvider>
<LayoutProvider>
<RouterProvider router={router} />
</LayoutProvider>
<SettingsProvider>
<LayoutProvider>
<RouterProvider router={router} />
</LayoutProvider>
</SettingsProvider>
</TooltipProvider>
</ThemeProvider>
)
Expand Down
11 changes: 11 additions & 0 deletions src/assets/icons/cog.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions src/features/common/components/icons/cog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { SVGProps } from 'react'
const SvgCog = (props: SVGProps<SVGSVGElement>) => (
<svg
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
xmlnsXlink="http://www.w3.org/1999/xlink"
enableBackground="new 0 0 512 512"
{...props}
>
<g>
<line fill="currentColor" y1={501} x1={303.1} y2={501} x2={302.1} />
<g>
<path
fill="currentColor"
d="m501,300.8v-91.7h-45.3c-5.3-22.4-14.3-43.3-26.4-62.1l32.9-32.7-64.9-64.6-33.4,33.3c-18.8-11.5-39.6-19.9-61.8-24.8v-47.2h-92.1v48.3c-22,5.4-42.6,14.4-61.1,26.4l-34.2-34-64.9,64.6 35.3,35.2c-2.8,4.6-5.3,9.2-7.7,14-7.5,14.3-13.2,30-17.1,45.7h-49.3v91.7h50.3c1.5,6 3.3,11.9 5.3,17.8 0.1,0.4 0.3,0.8 0.4,1.2 0,0.1 0.1,0.2 0.1,0.4 4.9,14.2 11.3,27.7 19.1,40.2l-35.5,35.3 64.9,64.6 35.1-34.9c18.3,11.5 38.6,20.2 60.2,25.4v48.1h91.1v-47.1c22.7-5 44-13.7 63.1-25.6l32.2,32 64.9-64.6-32.1-31.9c12-19.1 20.9-40.3 26-62.9h44.9zm-94.8,64l29.9,29.8-36.6,36.5-29.5-29.4c-24.7,18.9-54.4,31.7-86.7,36v42.4h-51.3v-42.7c-31.5-4.6-60.4-17.2-84.6-35.7l-31.6,31.5-36.6-36.5 32.4-31.3c-17.9-24-30-52.4-34.4-83.4h-45.3v-51.1h44l1.5-3.6c4.7-29.7 16.5-57.1 33.6-80.3l-32-31.9 36.6-36.5 31,31.9c24-18.5 52.8-31.2 84.1-36v-42.7h51.3v42.3c32,4.1 61.3,16.4 86,34.8l30.3-30.1 35.6,36.5-29.6,29.5c18.2,23.8 30.7,52.2 35.5,83.1h45.4v51.1h-44.7c-3.9,31.8-16.1,61.1-34.3,85.8z"
/>
<path
fill="currentColor"
d="m257,143.4c-61.8,0-113.1,50-113.1,112.6s51.4,112.6 113.1,112.6 113.1-51.1 113.1-112.6-51.3-112.6-113.1-112.6zm0,204.3c-51.3,0-92.1-40.7-92.1-91.7 0-51.1 41.9-91.7 92.1-91.7s92.1,40.7 92.1,91.7c0.1,51.1-41.8,91.7-92.1,91.7z"
/>
</g>
</g>
</svg>
)
export default SvgCog
16 changes: 8 additions & 8 deletions src/features/common/data/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Config, getAlgoClient, getAlgoIndexerClient } from '@algorandfoundation/algokit-utils'
import { NetworkConfig, localnetConfig } from '../../settings/data/network'
export * from './atom-with-debounce'

Config.configure({
logger: Config.getLogger(true),
})

export const indexer = getAlgoIndexerClient({
server: 'https://mainnet-idx.algonode.cloud/',
port: 443,
})
export let indexer = getAlgoIndexerClient(localnetConfig.indexer)

export const algod = getAlgoClient({
server: 'https://mainnet-api.algonode.cloud/',
port: 443,
})
export let algod = getAlgoClient(localnetConfig.algod)

export const setNetwork = (networkConfig: NetworkConfig) => {
indexer = getAlgoIndexerClient(networkConfig.indexer)
algod = getAlgoClient(networkConfig.algod)
}
8 changes: 5 additions & 3 deletions src/features/layout/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { cn } from '@/features/common/utils'
import { ThemeToggle } from '@/features/theme/components/theme-toggle'
import { NetworkSelect } from './network-select'
import { ConnectWallet } from './connect-wallet'
import { Search } from '@/features/search/components/search'
import { useNetworkConfig } from '@/features/settings/data'

type Props = {
className?: string
}

export function Header({ className }: Props) {
const networkConfig = useNetworkConfig()

return (
<div className={cn('bg-card flex h-20 flex-row justify-between px-5 pt-4 gap-5', className)}>
<div className={cn('flex flex-row items-baseline justify-start mt-1')}>
<Search />
</div>
<div className={cn('flex flex-row items-start justify-end gap-2')}>
<NetworkSelect />
<div className={cn('flex flex-row items-center justify-end gap-2')}>
<label>Network: {networkConfig.name}</label>
<ConnectWallet />
<ThemeToggle />
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/features/layout/components/left-side-bar-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SvgChevronLeft from '@/features/common/components/icons/chevron-left'
import { useCallback } from 'react'
import { useLayout } from '../hooks/use-layout'
import SvgChevronRight from '@/features/common/components/icons/chevron-right'
import SvgCog from '@/features/common/components/icons/cog'

type Props = {
className?: string
Expand All @@ -20,6 +21,7 @@ export function LeftSideBarMenu({ className }: Props) {
{ urlTemplate: Urls.Index, icon: <SvgHome />, text: 'Home' },
{ urlTemplate: Urls.Explore, icon: <SvgWallet />, text: 'Explore' },
{ urlTemplate: Urls.AppStudio, icon: <SvgCodeBlock />, text: 'App Studio' },
{ urlTemplate: Urls.Settings, icon: <SvgCog />, text: 'Settings' },
]
const { isLeftSideBarExpanded, setIsLeftSideBarExpanded } = useLayout()

Expand Down
19 changes: 13 additions & 6 deletions src/features/layout/components/network-select.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import { selectedNetworkAtom, networksConfigs } from '@/features/settings/data'
import { Label } from '@/features/common/components/label'
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/features/common/components/select'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/features/common/components/select'
import { cn } from '@/features/common/utils'
import { useAtom } from 'jotai'
import { settingsStore } from '@/features/settings/data'

export function NetworkSelect() {
const [selectedNetwork, setSelectedNetwork] = useAtom(selectedNetworkAtom, { store: settingsStore })

return (
<div className={cn('flex w-48 flex-col')}>
<Label htmlFor="network" className={cn('text-xs ml-0.5')}>
Network
</Label>
<Select>
<Select onValueChange={(value) => setSelectedNetwork(value)} value={selectedNetwork}>
<SelectTrigger id="network" className={cn('h-7')}>
Network
<SelectValue placeholder="Select network" />
</SelectTrigger>
<SelectContent className={cn('bg-card text-card-foreground')}>
<SelectItem value="localnet">Localnet</SelectItem>
<SelectItem value="testnet">Testnet</SelectItem>
<SelectItem value="main">Mainnet</SelectItem>
{networksConfigs.map((item) => (
<SelectItem key={item.id} value={item.id}>
{item.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
Expand Down
25 changes: 25 additions & 0 deletions src/features/settings/components/settings-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Provider, createStore } from 'jotai'
import { useNetworkConfig } from '../data/network'
import { useEffect } from 'react'
import { setNetwork } from '../../common/data'

type Props = {
children: React.ReactNode
}

export let dataStore = createStore()

export function SettingsProvider({ children }: Props) {
const networkConfig = useNetworkConfig()

useEffect(() => {
setNetwork(networkConfig)
dataStore = createStore()
}, [networkConfig])

return (
<Provider key={networkConfig.id} store={dataStore}>
{children}
</Provider>
)
}
5 changes: 5 additions & 0 deletions src/features/settings/components/settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { NetworkSelect } from '@/features/layout/components/network-select'

export function Settings() {
return <NetworkSelect />
}
2 changes: 2 additions & 0 deletions src/features/settings/data/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './settings'
export * from './network'
78 changes: 78 additions & 0 deletions src/features/settings/data/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { atom, useAtomValue } from 'jotai'
import { atomWithStorage } from 'jotai/utils'
import { settingsStore } from './settings'

export type NetworkConfig = {
id: string
name: string
indexer: {
server: string
port: number
token?: string
}
algod: {
server: string
port: number
token?: string
}
}

export const mainnetConfig: NetworkConfig = {
id: 'mainnet',
name: 'MainNet',
indexer: {
server: 'https://mainnet-idx.algonode.cloud/',
port: 443,
},
algod: {
server: 'https://mainnet-api.algonode.cloud/',
port: 443,
},
}
const testnetConfig: NetworkConfig = {
id: 'testnet',
name: 'TestNet',
indexer: {
server: 'https://testnet-idx.algonode.cloud/',
port: 443,
},
algod: {
server: 'https://testnet-api.algonode.cloud/',
port: 443,
},
}
export const localnetConfig: NetworkConfig = {
id: 'localnet',
name: 'LocalNet',
indexer: {
server: 'http://localhost/',
port: 8980,
token: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
},
algod: {
server: 'http://localhost/',
port: 4001,
token: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
},
}

export const networksConfigs = [mainnetConfig, testnetConfig, localnetConfig]

export const selectedNetworkAtom = atomWithStorage('network', localnetConfig.id, undefined, { getOnInit: true })

const networkConfigAtom = atom((get) => {
const id = get(selectedNetworkAtom)
const config = networksConfigs.find((n) => n.id === id)

if (!config) {
// eslint-disable-next-line no-console
console.warn(`Unknown network: ${id}, fallback to ${localnetConfig.name}`)
return localnetConfig
}

return config
})

export const useNetworkConfig = () => {
return useAtomValue(networkConfigAtom, { store: settingsStore })
}
3 changes: 3 additions & 0 deletions src/features/settings/data/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createStore } from 'jotai'

export const settingsStore = createStore()
11 changes: 11 additions & 0 deletions src/features/settings/pages/settings-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { cn } from '@/features/common/utils'
import { Settings } from '../components/settings'

export function SettingsPage() {
return (
<div>
<h1 className={cn('text-2xl text-primary font-bold')}>Settings</h1>
<Settings />
</div>
)
}
1 change: 1 addition & 0 deletions src/routes/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ export const Urls = {
}),
}),
AppStudio: UrlTemplate`/app-studio`,
Settings: UrlTemplate`/settings`,
}

0 comments on commit 23daaec

Please sign in to comment.