feat(react): add MemberSidebar component
This commit is contained in:
parent
c1fba5e633
commit
f9a99c3946
|
@ -0,0 +1,60 @@
|
|||
import React from 'react'
|
||||
|
||||
import { styled } from '~/src/styles/config'
|
||||
import { Grid } from '~/src/system'
|
||||
import { Heading } from '~/src/system/heading'
|
||||
|
||||
import { MemberGroup } from './member-group'
|
||||
import { MemberItem } from './member-item'
|
||||
import { UserItem } from './user-item'
|
||||
|
||||
export function MemberSidebar() {
|
||||
return (
|
||||
<Wrapper>
|
||||
<Heading size="15" css={{ marginBottom: '$3' }}>
|
||||
Members
|
||||
</Heading>
|
||||
<Grid gap="2">
|
||||
<MemberGroup label="You">
|
||||
<UserItem />
|
||||
</MemberGroup>
|
||||
<MemberGroup label="Online">
|
||||
<MemberItem verified={true} untrustworthy={false} indicator="online">
|
||||
pvl.eth
|
||||
</MemberItem>
|
||||
<MemberItem verified={false} untrustworthy={false} indicator="online">
|
||||
carmen
|
||||
</MemberItem>
|
||||
<MemberItem verified={false} untrustworthy={false} indicator="online">
|
||||
carmen
|
||||
</MemberItem>
|
||||
</MemberGroup>
|
||||
<MemberGroup label="Offline">
|
||||
<MemberItem verified={false} untrustworthy indicator="offline">
|
||||
mark
|
||||
</MemberItem>
|
||||
<MemberItem
|
||||
verified={false}
|
||||
untrustworthy={false}
|
||||
indicator="offline"
|
||||
>
|
||||
mark
|
||||
</MemberItem>
|
||||
</MemberGroup>
|
||||
</Grid>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
|
||||
const Wrapper = styled('div', {
|
||||
width: 256,
|
||||
flexShrink: 0,
|
||||
padding: '18px 16px',
|
||||
display: 'none',
|
||||
backgroundColor: '#F6F8FA',
|
||||
overflowY: 'scroll',
|
||||
|
||||
'@medium': {
|
||||
display: 'block',
|
||||
},
|
||||
})
|
|
@ -0,0 +1,21 @@
|
|||
import React from 'react'
|
||||
|
||||
import { Text } from '~/src/system'
|
||||
|
||||
interface Props {
|
||||
label: string
|
||||
children: React.ReactElement[] | React.ReactElement
|
||||
}
|
||||
|
||||
export const MemberGroup = (props: Props) => {
|
||||
const { label, children } = props
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Text size={12} color="gray">
|
||||
{label}
|
||||
</Text>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
import React from 'react'
|
||||
|
||||
import { Avatar, EthAddress, Flex, Text } from '~/src/system'
|
||||
|
||||
import type { AvatarProps } from '~/src/system/avatar'
|
||||
|
||||
interface Props {
|
||||
children: string
|
||||
verified: boolean
|
||||
untrustworthy: boolean
|
||||
indicator?: AvatarProps['indicator']
|
||||
}
|
||||
|
||||
export const MemberItem = (props: Props) => {
|
||||
const { children, indicator, verified, untrustworthy } = props
|
||||
|
||||
return (
|
||||
<Flex gap="2" align="center" css={{ height: 56 }}>
|
||||
<Avatar
|
||||
size={32}
|
||||
indicator={indicator}
|
||||
src="https://images.unsplash.com/photo-1499155286265-79a9dc9c6380?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1284&q=80"
|
||||
/>
|
||||
<div>
|
||||
<Flex align="center" gap={1}>
|
||||
<Text size="15" color="black-70">
|
||||
{children}
|
||||
</Text>
|
||||
{verified && (
|
||||
<svg
|
||||
width="10"
|
||||
height="10"
|
||||
viewBox="0 0 10 10"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="5" cy="5" r="5" fill="#4360DF" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M4.21097 5.79222L6.73854 3.25573C6.91216 3.08149 7.19307 3.0809 7.36869 3.25713C7.54308 3.43214 7.54399 3.71498 7.37008 3.8895L4.52534 6.74428C4.43901 6.83091 4.32615 6.87462 4.2129 6.875C4.09629 6.87412 3.98311 6.8311 3.89811 6.7458L2.6292 5.47241C2.45641 5.29901 2.4565 5.01779 2.63211 4.84156C2.8065 4.66655 3.09029 4.66758 3.26074 4.83864L4.21097 5.79222Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
{untrustworthy && (
|
||||
<svg
|
||||
width="10"
|
||||
height="10"
|
||||
viewBox="0 0 10 10"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="5" cy="5" r="5" fill="#FF2D55" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.78125 7.65625C5.78125 8.08772 5.43147 8.4375 5 8.4375C4.56853 8.4375 4.21875 8.08772 4.21875 7.65625C4.21875 7.22478 4.56853 6.875 5 6.875C5.43147 6.875 5.78125 7.22478 5.78125 7.65625ZM5 1.875C4.65482 1.875 4.375 2.15482 4.375 2.5V5.3125C4.375 5.65768 4.65482 5.9375 5 5.9375C5.34518 5.9375 5.625 5.65768 5.625 5.3125V2.5C5.625 2.15482 5.34518 1.875 5 1.875Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</Flex>
|
||||
<EthAddress size={10} color="gray">
|
||||
71C7656EC7ab88b098defB751B7401B5f6d8976F
|
||||
</EthAddress>
|
||||
</div>
|
||||
</Flex>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import React from 'react'
|
||||
|
||||
import { styled } from '~/src/styles/config'
|
||||
import {
|
||||
Avatar,
|
||||
Dialog,
|
||||
DialogTrigger,
|
||||
EthAddress,
|
||||
Flex,
|
||||
Text,
|
||||
} from '~/src/system'
|
||||
|
||||
export const UserItem = () => {
|
||||
return (
|
||||
<Flex align="center" justify="between">
|
||||
<Flex gap="2" align="center" css={{ height: 56 }}>
|
||||
<Avatar
|
||||
size={32}
|
||||
src="https://images.unsplash.com/photo-1546776310-eef45dd6d63c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1620&q=80"
|
||||
/>
|
||||
<div>
|
||||
<Flex align="center" gap={1}>
|
||||
<Text size="15" color="black-70">
|
||||
Pavel
|
||||
</Text>
|
||||
</Flex>
|
||||
<EthAddress size={10} color="gray">
|
||||
71C7656EC7ab88b098defB751B7401B5f6d8976F
|
||||
</EthAddress>
|
||||
</div>
|
||||
</Flex>
|
||||
|
||||
<DialogTrigger>
|
||||
<LogoutButton>
|
||||
<svg
|
||||
width="20"
|
||||
height="18"
|
||||
viewBox="0 0 20 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.985 8.36269C16.363 8.36269 16.5523 7.90572 16.285 7.63846L14.7017 6.05509C14.4531 5.80658 14.4531 5.40365 14.7017 5.15514C14.9502 4.90662 15.3531 4.90662 15.6016 5.15514L18.9956 8.54908C19.2441 8.79759 19.2441 9.20051 18.9956 9.44903L15.6016 12.843C15.3531 13.0915 14.9502 13.0915 14.7017 12.843C14.4531 12.5945 14.4531 12.1915 14.7017 11.943L16.285 10.3596C16.5523 10.0924 16.363 9.63542 15.985 9.63542L7.51527 9.63542C7.16382 9.63542 6.87891 9.35051 6.87891 8.99905C6.87891 8.6476 7.16382 8.36269 7.51527 8.36269L15.985 8.36269Z"
|
||||
fill="#4360DF"
|
||||
/>
|
||||
<path
|
||||
d="M11.1218 3.90956C11.1218 2.73805 10.1721 1.78835 9.00059 1.78835H3.90968C2.73817 1.78835 1.78847 2.73805 1.78847 3.90956V14.0914C1.78847 15.2629 2.73817 16.2126 3.90968 16.2126H9.00059C10.1721 16.2126 11.1218 15.2629 11.1218 14.0914V11.3338C11.1218 10.9824 11.4067 10.6974 11.7582 10.6974C12.1096 10.6974 12.3945 10.9824 12.3945 11.3338V14.0914C12.3945 15.9658 10.875 17.4853 9.00059 17.4853H3.90968C2.03526 17.4853 0.515744 15.9658 0.515744 14.0914V3.90956C0.515744 2.03514 2.03526 0.515625 3.90968 0.515625H9.00059C10.875 0.515625 12.3945 2.03514 12.3945 3.90956V6.66714C12.3945 7.01859 12.1096 7.3035 11.7582 7.3035C11.4067 7.3035 11.1218 7.01859 11.1218 6.66714V3.90956Z"
|
||||
fill="#4360DF"
|
||||
/>
|
||||
</svg>
|
||||
</LogoutButton>
|
||||
<Dialog
|
||||
title="Disconnect"
|
||||
cancelLabel="Disconnect"
|
||||
actionLabel="Stay Connected"
|
||||
>
|
||||
<Text>Do you want to disconnect your profile from this browser?</Text>
|
||||
<Avatar size="120" />
|
||||
</Dialog>
|
||||
</DialogTrigger>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
const LogoutButton = styled('button', {
|
||||
background: 'rgba(67, 96, 223, 0.1)',
|
||||
borderRadius: '50%',
|
||||
height: 32,
|
||||
width: 32,
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
})
|
Loading…
Reference in New Issue