Skip to content

Commit

Permalink
restore routes:
Browse files Browse the repository at this point in the history
  /asset/<assetId>
  /error/not-found/<searchStr>
  /search/<searchStr>
improved error messages
contracts fix
  • Loading branch information
chatch committed Sep 19, 2023
1 parent 95b7af7 commit 447bc4f
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 101 deletions.
3 changes: 1 addition & 2 deletions app/lib/stellar/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ const getContractInfo = async (
console.error(error)
}

if (ledgerEntries == null || ledgerEntries.entries == null) {
if (ledgerEntries == null || ledgerEntries.entries == null || ledgerEntries.entries.length == 0) {
return null
}

const ledgerEntry = ledgerEntries.entries[0]
const codeData = xdr.LedgerEntryData.fromXDR(ledgerEntry.xdr, 'base64')
.contractData()
Expand Down
2 changes: 1 addition & 1 deletion app/routes/account.$accountId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export const loader = async ({ params, request }: LoaderArgs) => {
if (error instanceof NotFoundError) {
throw new Response(null, {
status: 404,
statusText: `Account [${params.accountId}] not found on this network.`,
statusText: `Account ${params.accountId} not found on this network.`,
})
} else if (error instanceof AccountTypeUnrecognizedException) {
throw new Response(null, {
Expand Down
31 changes: 31 additions & 0 deletions app/routes/asset.$assetId.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useEffect } from "react"
import { json } from "@remix-run/node"
import { useLoaderData } from "@remix-run/react"

import { setTitle } from "../lib/utils"
import { Assets } from "./lib/assets-base"

import directory from "../data/directory"

const { assets } = directory

export const loader = (
{ params }: { params: { assetId: string } }
) => {
const matchingAssetKeys = Object.keys(assets).filter(k => k.startsWith(params.assetId))
return json({ matchingAssetKeys })
}

export default function AssetsById() {
useEffect(() => {
setTitle("Assets")
}, [])

const {
matchingAssetKeys,
}: {
matchingAssetKeys: Array<string>
} = useLoaderData<typeof loader>()

return (<Assets assetKeys={matchingAssetKeys} />)
}
101 changes: 5 additions & 96 deletions app/routes/assets.tsx
Original file line number Diff line number Diff line change
@@ -1,107 +1,16 @@
import Container from "react-bootstrap/Container"
import Card from "react-bootstrap/Card"
import CardHeader from "react-bootstrap/CardHeader"
import Row from "react-bootstrap/Row"
import Table from "react-bootstrap/Table"
import { FormattedMessage, useIntl } from "react-intl"
import { Link } from "react-router-dom"
import { useEffect } from "react"

import { Assets } from "./lib/assets-base"
import { setTitle } from "../lib/utils"
import AccountLink from "../components/shared/AccountLink"
import BackendResourceBadgeButton from "../components/shared/BackendResourceBadgeButton"
import ClipboardCopy from "../components/shared/ClipboardCopy"
import Logo from "../components/shared/Logo"
import NewWindowIcon from "../components/shared/NewWindowIcon"

import directory from "../data/directory"
import { TitleWithJSONButton } from "~/components/shared/TitleWithJSONButton"
import { useEffect } from "react"
const { anchors, assets } = directory

const METADATA_URI =
"https://raw.githubusercontent.com/irisli/stellarterm/master/directory/directory.json"

interface AssetProps {
code: string
issuer: string
domain: string
}

function Asset({ code, domain, issuer }: AssetProps) {
const anchor = anchors[domain]
return (
<tr className="directoryRow">
<td>
<a href={anchor.website} target="_blank" rel="noreferrer">
<Logo name={domain} type="anchor" />
</a>
</td>
<td style={{ color: "white" }}>{code}</td>
<td>
<AccountLink account={issuer} hideKnown />
<ClipboardCopy text={issuer} />
</td>
<td>
<div>
<Link to={`/anchor/${domain}`}>{anchor.name}</Link>
</div>
<div>
<a href={anchor.website} target="_blank" rel="noreferrer">
{anchor.website}
<NewWindowIcon />
</a>
</div>
<div className="stellarToml">
<BackendResourceBadgeButton
label="server.toml"
url={`https://${domain}/.well-known/stellar.toml`}
/>
</div>
</td>
</tr>
)
};
const { assets } = directory

export default function Assets() {
const { formatMessage } = useIntl()
export default function AssetsAll() {
useEffect(() => {
setTitle("Assets")
}, [])

return (
<Container>
<Row>
<Card>
<CardHeader>
<TitleWithJSONButton title={formatMessage({ id: "assets" })}
url={METADATA_URI} />
</CardHeader>
<Card.Body>
<Table id="assets-table">
<thead>
<tr>
<th />
<th>
<FormattedMessage id="code" />
</th>
<th>
<FormattedMessage id="issuer" />
</th>
<th>
<FormattedMessage id="anchor" />
</th>
</tr>
</thead>
<tbody>
{Object.keys(assets).sort().map((key) => {
const asset = assets[key]
return <Asset key={key} {...asset} />
})}
</tbody>
</Table>
</Card.Body>
</Card>
</Row>
</Container>
)
return (<Assets assetKeys={Object.keys(assets)} />)
}
9 changes: 7 additions & 2 deletions app/routes/contract.$contractId.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Link } from 'react-router-dom'
import { FormattedMessage, useIntl } from 'react-intl'
import { LoaderArgs, json } from '@remix-run/node'
import { NavLink, Outlet, useLoaderData, useLocation } from '@remix-run/react'
import { NavLink, Outlet, useLoaderData, useLocation, useParams } from '@remix-run/react'

import Container from 'react-bootstrap/Container'
import Card from 'react-bootstrap/Card'
Expand Down Expand Up @@ -63,13 +63,18 @@ export default function () {
const [activeTab, setActiveTab] = useState('storage')
const { pathname } = useLocation()
const { contractDetails } = useLoaderData<typeof loader>()
const { contractId } = useParams()

useEffect(() => {
setActiveTab(pathToTabName(pathname))
}, [pathname])

if (!contractDetails) {
return (<span>Not Found</span>)
return (
<Container>
<span>Contract {contractId} not found</span>
</Container>
)
}

const {
Expand Down
12 changes: 12 additions & 0 deletions app/routes/error.not-found.$searchStr.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Container from "react-bootstrap/Container"
import { useParams } from "@remix-run/react"
import { FormattedMessage } from "react-intl"

export default function SearchNotFound() {
const { searchStr } = useParams()
return (
<Container>
<FormattedMessage id="error.cant.find" values={{ searchStr }} />
</Container>
)
}
108 changes: 108 additions & 0 deletions app/routes/lib/assets-base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { useEffect } from "react"
import Container from "react-bootstrap/Container"
import Card from "react-bootstrap/Card"
import CardHeader from "react-bootstrap/CardHeader"
import Row from "react-bootstrap/Row"
import Table from "react-bootstrap/Table"
import { FormattedMessage, useIntl } from "react-intl"
import { Link } from "react-router-dom"

import { setTitle } from "../../lib/utils"
import AccountLink from "../../components/shared/AccountLink"
import BackendResourceBadgeButton from "../../components/shared/BackendResourceBadgeButton"
import ClipboardCopy from "../../components/shared/ClipboardCopy"
import Logo from "../../components/shared/Logo"
import NewWindowIcon from "../../components/shared/NewWindowIcon"
import { TitleWithJSONButton } from "~/components/shared/TitleWithJSONButton"

import directory from "../../data/directory"

const { anchors, assets } = directory

export const METADATA_URI =
"https://raw.githubusercontent.com/irisli/stellarterm/master/directory/directory.json"

export interface AssetProps {
code: string
issuer: string
domain: string
}

export function Asset({ code, domain, issuer }: AssetProps) {
const anchor = anchors[domain]
return (
<tr className="directoryRow">
<td>
<a href={anchor.website} target="_blank" rel="noreferrer">
<Logo name={domain} type="anchor" />
</a>
</td>
<td style={{ color: "white" }}>{code}</td>
<td>
<AccountLink account={issuer} hideKnown />
<ClipboardCopy text={issuer} />
</td>
<td>
<div>
<Link to={`/anchor/${domain}`}>{anchor.name}</Link>
</div>
<div>
<a href={anchor.website} target="_blank" rel="noreferrer">
{anchor.website}
<NewWindowIcon />
</a>
</div>
<div className="stellarToml">
<BackendResourceBadgeButton
label="server.toml"
url={`https://${domain}/.well-known/stellar.toml`}
/>
</div>
</td>
</tr>
)
};

export function Assets({ assetKeys }: { assetKeys: Array<string> }) {
const { formatMessage } = useIntl()
useEffect(() => {
setTitle("Assets")
}, [])

return (
<Container>
<Row>
<Card>
<CardHeader>
<TitleWithJSONButton title={formatMessage({ id: "assets" })}
url={METADATA_URI} />
</CardHeader>
<Card.Body>
<Table id="assets-table">
<thead>
<tr>
<th />
<th>
<FormattedMessage id="code" />
</th>
<th>
<FormattedMessage id="issuer" />
</th>
<th>
<FormattedMessage id="anchor" />
</th>
</tr>
</thead>
<tbody>
{assetKeys.sort().map((key) => {
const asset = assets[key]
return <Asset key={key} {...asset} />
})}
</tbody>
</Table>
</Card.Body>
</Card>
</Row>
</Container>
)
}
10 changes: 10 additions & 0 deletions app/routes/search.$searchStr.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { redirect } from "@remix-run/node"
import { searchStrToPath } from "~/lib/search"


export const loader = async (
{ params }: { params: { searchStr: string } }
) => {
const matchPath = searchStrToPath(params.searchStr)
return redirect(matchPath as string)
}

0 comments on commit 447bc4f

Please sign in to comment.