fix: finish the dashboard style

This commit is contained in:
Juan Di Toro 2023-09-30 12:18:49 +02:00
parent 38ef322635
commit c565eaca36
3 changed files with 59 additions and 27 deletions

BIN
src/assets/lume-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,28 +1,64 @@
import * as Dialog from "@radix-ui/react-dialog" import * as Dialog from "@radix-ui/react-dialog"
import { Chain, useLume } from "@/components/lume/LumeProvider" import { Chain, useLume } from "@/components/lume/LumeProvider"
import Logo from "@/assets/lume-logo.png"
const SYNCSTATE_TO_TEXT: Record<Chain['syncState'], string> = {
done: 'Synced',
error: 'Issue',
syncing: 'Syncing'
}
const SYNC_STATE_TO_TW_COLOR: Record<Chain['syncState'], string> = {
'done': 'text-primary',
'error': 'text-red-500',
'syncing': 'text-orange-500',
}
const LumeDashboard = () => { const LumeDashboard = () => {
const { chains } = useLume() const { chains } = useLume()
const contentChains = chains.filter(c => c.type === 'content');
const blockchainChains = chains.filter(c => c.type === 'blockchain');
return ( return (
<Dialog.Root> <Dialog.Root>
<Dialog.Trigger>Open</Dialog.Trigger> <Dialog.Trigger>Open</Dialog.Trigger>
<Dialog.Portal> <Dialog.Portal>
<Dialog.Overlay className="fixed z-40 inset-0 bg-black bg-opacity-50 backdrop-blur-sm" /> <Dialog.Overlay className="fixed z-40 inset-0 bg-black bg-opacity-50 backdrop-blur-sm" />
<Dialog.Content className="fixed p-5 z-50 right-0 bottom-0 top-0 w-[300px] bg-neutral-800 text-white border-black border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500"> <Dialog.Content className="fixed p-5 z-50 right-0 bottom-0 top-0 w-[300px] bg-neutral-950 text-white border-black border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500">
<Dialog.Title>Syncing State: Connected</Dialog.Title> <div className="w-[calc(100%+38px)] border-b pb-3 -mx-5 px-5 border-neutral-900">
<Dialog.Description>Network Log:</Dialog.Description> <img src={Logo.src} className="w-24" />
{chains.map((chain) => ( </div>
<div key={chain.chainId}> <div className="mt-4 mb-8">
<CircularProgress chain={chain} /> <h2 className="text-xl mb-4"> Content </h2>
<div className="grid grid-cols-2">
{contentChains.map((chain, index) => <ChainIndicator key={`Content_ChainIndicator_${index}`} chain={chain} />)}
</div> </div>
))} </div>
<div className="mt-4 mb-8">
<h2 className="text-xl mb-4"> Blockchain </h2>
<div className="grid grid-cols-2">
{blockchainChains.map((chain, index) => <ChainIndicator key={`Blockchain_ChainIndicator_${index}`} chain={chain} />)}
</div>
</div>
</Dialog.Content> </Dialog.Content>
</Dialog.Portal> </Dialog.Portal>
</Dialog.Root> </Dialog.Root>
) )
} }
const ChainIndicator = ({ chain }: { chain: Chain }) => {
return <div key={chain.chainId} className="flex flex-row gap-x-2 items-center ">
<CircularProgress chain={chain} />
<div className="flex flex-col">
<span>{chain.name}</span>
<span className={`text-[12px] -mt-1 ${SYNC_STATE_TO_TW_COLOR[chain.syncState]}`}> {SYNCSTATE_TO_TEXT[chain.syncState]} </span>
</div>
</div>
}
const CircularProgress = ({ const CircularProgress = ({
chain, chain,
className className
@ -35,16 +71,10 @@ const CircularProgress = ({
return ( return (
<svg <svg
className={`${className} ${ className={`${className} ${SYNC_STATE_TO_TW_COLOR[chain.syncState]}`}
chain.syncState === "done" width="36"
? "text-primary" height="36"
: chain.syncState === "error" viewBox="0 0 100 100"
? "text-red-600"
: "text-orange-500"
}`}
width="100"
height="100"
viewBox="-25 -25 250 250"
version="1.1" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
style={{ transform: "rotate(-90deg)" }} style={{ transform: "rotate(-90deg)" }}
@ -55,7 +85,7 @@ const CircularProgress = ({
cy="50" cy="50"
fill="transparent" fill="transparent"
stroke="#e0e0e0" stroke="#e0e0e0"
stroke-width="8px" stroke-width="4px"
stroke-dasharray="282.74px" stroke-dasharray="282.74px"
stroke-dashoffset="0" stroke-dashoffset="0"
></circle> ></circle>
@ -64,7 +94,7 @@ const CircularProgress = ({
cx="50" cx="50"
cy="50" cy="50"
stroke="currentColor" stroke="currentColor"
stroke-width="8px" stroke-width="4px"
stroke-linecap="round" stroke-linecap="round"
stroke-dashoffset={`${progressOffset}px`} stroke-dashoffset={`${progressOffset}px`}
fill="transparent" fill="transparent"
@ -75,7 +105,7 @@ const CircularProgress = ({
y="57.5px" y="57.5px"
fill="currentColor" fill="currentColor"
font-size="26px" font-size="26px"
font-weight="bold" font-weight="normal"
style={{ transform: "rotate(90deg) translate(0px, -98px)" }} style={{ transform: "rotate(90deg) translate(0px, -98px)" }}
> >
{chain.progress} {chain.progress}

View File

@ -4,12 +4,13 @@ type LumeSyncState = 'syncing' | 'done' | 'error'
export type Chain = { export type Chain = {
syncState: LumeSyncState, syncState: LumeSyncState,
name: string,
chainId: string, chainId: string,
active: boolean, active: boolean,
progress: number, // in porcentage progress: number, // in porcentage
logs: string[], logs: string[],
type: 'blockchain' | 'content', type: 'blockchain' | 'content',
peerCount?: number peerCount?: number
} }
type LumeObject = { type LumeObject = {
@ -27,15 +28,16 @@ const LumeProvider = ({ children }: { children: React.ReactNode }) => {
const [lume, setLume] = React.useState<LumeObject>({ const [lume, setLume] = React.useState<LumeObject>({
chains: [ chains: [
{ {
name: 'Ethereum',
syncState: 'done', syncState: 'done',
chainId: '1', chainId: '1',
active: true, active: true,
progress: 100, progress: 100,
logs: [], logs: [],
type: 'blockchain', type: 'blockchain'
peerCount: 5
}, },
{ {
name: "IPFS",
syncState: 'syncing', syncState: 'syncing',
chainId: '2', chainId: '2',
active: false, active: false,
@ -59,13 +61,13 @@ const LumeProvider = ({ children }: { children: React.ReactNode }) => {
export default LumeProvider; export default LumeProvider;
export function useLume() { export function useLume() {
const ctx = useContext(LumeContext); const ctx = useContext(LumeContext);
if(!ctx) { if (!ctx) {
throw new Error('useLume must be used within a LumeProvider'); throw new Error('useLume must be used within a LumeProvider');
} }
const { lume } = ctx; const { lume } = ctx;
return lume return lume
} }