Skip to content

Commit

Permalink
chore: update ui
Browse files Browse the repository at this point in the history
  • Loading branch information
bluecco committed Nov 12, 2024
1 parent ca2b6f0 commit eaee435
Show file tree
Hide file tree
Showing 36 changed files with 1,288 additions and 673 deletions.
Binary file added public/starknet_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
429 changes: 386 additions & 43 deletions src/app/globals.css

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { Metadata } from "next"
import { Inter } from "next/font/google"
import "./globals.css"

const inter = Inter({ subsets: ["latin"] })

export const metadata: Metadata = {
title: "Demo dapp starknet",
description:
Expand All @@ -14,7 +17,13 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body>{children}</body>
<body className={inter.className}>
<main
style={{ height: "100dvh", display: "flex", flexDirection: "column" }}
>
{children}
</main>
</body>
</html>
)
}
13 changes: 3 additions & 10 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
"use client"

import { StarknetDapp } from "@/components/StarknetDapp"
import { Flex } from "@/components/ui/Flex"
import { connectors } from "@/connectors"
import { CHAIN_ID } from "@/constants"
import { mainnet, sepolia } from "@starknet-react/chains"
import { publicProvider, StarknetConfig } from "@starknet-react/core"
import { constants } from "starknet"

/* TODO: update ui */

export default function Home() {
const chains = [
CHAIN_ID === constants.NetworkName.SN_MAIN ? mainnet : sepolia,
]
const chains = [mainnet, sepolia]
const providers = publicProvider()

return (
<Flex flexDirection="column" className="demo-dapp-container">
<div className="flex demo-dapp-container">
{/* eslint-disable @typescript-eslint/no-explicit-any */}
<StarknetConfig
chains={chains}
Expand All @@ -28,6 +21,6 @@ export default function Home() {
<StarknetDapp />
</StarknetConfig>
{/* eslint-enable @typescript-eslint/no-explicit-any */}
</Flex>
</div>
)
}
54 changes: 54 additions & 0 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { isMainnet, toHexChainid } from "@/helpers/chainId"
import { formatTruncatedAddress } from "@/helpers/formatAddress"
import { useAccount, useBalance } from "@starknet-react/core"
import { AvatarIcon } from "./icons/AvatarIcon"
import { LogoIcon } from "./icons/LogoIcon"
import { WalletIcon } from "./icons/WalletIcon"

const Header = () => {
const { address, isConnected, chainId } = useAccount()

const { data: balance } = useBalance({
address: address,
})

const hexChainId = toHexChainid(chainId)

return (
<div className="flex header-container">
<div className="flex header-logo-container">
<LogoIcon />
<h1 className="header-title">Demo dapp</h1>
<div className="flex full-flex" />

{isConnected && (
<div className="flex header-profile-container">
<div className="flex header-balance">
<WalletIcon />
{balance && balance?.formatted.length > 7
? `${balance.formatted.slice(0, 7)} ETH`
: `${balance?.formatted} ETH`}
</div>
<div className="header-account-separator" />
<div
className="flex header-address"
onClick={() =>
window.open(
isMainnet(hexChainId)
? `https://voyager.online/contract/${address}`
: `https://sepolia.voyager.online/contract/${address}`,
"_blank",
)
}
>
<AvatarIcon />
{formatTruncatedAddress(address || "")}
</div>
</div>
)}
</div>
</div>
)
}

export { Header }
88 changes: 71 additions & 17 deletions src/components/StarknetDapp.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,81 @@
"use client"
import { SignMessage } from "@/components/sections/SignMessage"
import { Transactions } from "@/components/sections/Transactions/Transactions"
import { useAccount } from "@starknet-react/core"
import { useState } from "react"
import { Connect } from "./connect/Connect"
import { Flex } from "./ui/Flex"
import { Header } from "./Header"
import { AccountStatus } from "./sections/AccountStatus"
import { AddToken } from "./sections/ERC20/AddToken"
import { Network } from "./sections/Network/Network"
import { SectionButton } from "./sections/SectionButton"
import { Section } from "./sections/types"

const StarknetDapp = () => (
<Flex
flexDirection="column"
maxWidth="500px"
width="100%"
margin="0 auto"
gap="24px"
>
<AccountStatus />
<Connect />
<Transactions />
<SignMessage />
<Network />
<AddToken />
</Flex>
)
const StarknetDapp = () => {
const [section, setSection] = useState<Section | undefined>(undefined)
const { isConnected } = useAccount()

return (
<div className="flex full column">
<Header />

<div className="flex get-started-container">
<div className="flex column">
<h1 className="get-started-title">your</h1>
<span className="get-started-subtitle">
Starknet utilizes the power of STARK technology to ensure
computational integrity.
</span>
</div>

<div className="status-grid-container">
<AccountStatus />
</div>
</div>

<div className="flex sections-container">
<div className="flex full column sections-list">
<SectionButton
section="Connection"
setSection={setSection}
selected={section === "Connection"}
/>
<SectionButton
section="Transactions"
setSection={setSection}
selected={section === "Transactions"}
disabled={!isConnected}
/>
<SectionButton
section="Signing"
setSection={setSection}
selected={section === "Signing"}
disabled={!isConnected}
/>
<SectionButton
section="Network"
setSection={setSection}
selected={section === "Network"}
disabled={!isConnected}
/>
<SectionButton
section="ERC20"
setSection={setSection}
selected={section === "ERC20"}
disabled={!isConnected}
/>
</div>

<div className="flex full-flex">
{section === "Connection" && <Connect />}
{section === "Transactions" && <Transactions />}
{section === "Signing" && <SignMessage />}
{section === "Network" && <Network />}
{section === "ERC20" && <AddToken />}
</div>
</div>
</div>
)
}

export { StarknetDapp }
113 changes: 58 additions & 55 deletions src/components/connect/Connect.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { useAccount, useConnect } from "@starknet-react/core"
import { useAccount, useConnect, useDisconnect } from "@starknet-react/core"
import Image from "next/image"
import { useEffect, useState } from "react"
import { disconnect } from "starknetkit"
import { Accordion } from "../ui/Accordion"
import { SectionLayout } from "../sections/SectionLayout"
import { Button } from "../ui/Button"
import { Flex } from "../ui/Flex"
import { ConnectorButton } from "./ConnectorButton"
import { ConnectStarknetkitModal } from "./ConnectStarknetkitModal"
import { DisconnectIcon } from "../icons/DisconnectIcon"

const Connect = () => {
const { isConnected } = useAccount()
const { connectors } = useConnect()
const { disconnect } = useDisconnect({})
const [isClient, setIsClient] = useState(false)

useEffect(() => {
Expand All @@ -21,57 +22,59 @@ const Connect = () => {
}

return (
<Flex flexDirection="column" gap="12px">
<Accordion
isDefaultOpen
items={[
{
title: "Connection",
content: (
<Flex gap="12px">
<Flex flex={1} flexDirection="column" gap="12px">
<ConnectStarknetkitModal />

<Accordion
withBorder
items={[
{
title: "starknet-react connectors",
content: (
<Flex
flex={1}
flexDirection="column"
gap="12px"
padding="8px"
>
{connectors.map((connector) => (
<ConnectorButton
key={connector.id}
connector={connector}
/>
))}
</Flex>
),
},
]}
/>
</Flex>

<Flex flex={1} height="fit-content">
<Button
className="full"
onClick={() => disconnect()}
disabled={!isConnected}
>
Disconnect
</Button>
</Flex>
</Flex>
),
},
]}
/>
</Flex>
<SectionLayout sectionTitle="Connection">
<div className="flex column gap-3">
<div className="flex gap-3">
<ConnectStarknetkitModal />
<Button
className={`full ${!isConnected ? "disabled" : ""}`}
onClick={() => disconnect()}
disabled={!isConnected}
hideChevron
leftIcon={<DisconnectIcon />}
>
Disconnect
</Button>
</div>
<div className="flex column available-connector">
<span className="starknet-react-connectors-title">
Starknet-react connectors
</span>
<div className="connectors-grid">
{connectors.map((connector) => {
const icon =
typeof connector.icon === "string"
? connector.icon
: connector.icon.dark
const isSvg = icon?.startsWith("<svg")
return (
<ConnectorButton
key={connector.id}
connector={connector}
icon={
<>
{isSvg ? (
<div
dangerouslySetInnerHTML={{ __html: icon }}
className="connector-icon"
/>
) : (
<Image
alt={connector.name}
src={icon}
height={17}
width={17}
/>
)}
</>
}
/>
)
})}
</div>
</div>
</div>
</SectionLayout>
)
}

Expand Down
1 change: 1 addition & 0 deletions src/components/connect/ConnectStarknetkitModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const ConnectStarknetkitModal = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await connectAsync({ connector: connector as any })
}}
hideChevron
>
Starknetkit Modal
</Button>
Expand Down
15 changes: 11 additions & 4 deletions src/components/connect/ConnectorButton.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
import { Connector, useConnect } from "@starknet-react/core"
import { FC } from "react"
import { FC, ReactNode } from "react"
import { Button } from "../ui/Button"

const ConnectorButton: FC<{ connector: Connector }> = ({ connector }) => {
const ConnectorButton: FC<{ connector: Connector; icon: ReactNode }> = ({
connector,
icon,
}) => {
const { connectAsync } = useConnect()
if (!connector.available()) {
return null
}

return (
<Button
className="full"
key={connector.id}
onClick={async () => {
await connectAsync({ connector })
}}
className="connector"
hideChevron
>
{connector.name}
<div className="flex align-items-center gap-2">
{icon}
{connector.name}
</div>
</Button>
)
}
Expand Down
Loading

0 comments on commit eaee435

Please sign in to comment.