feat(react): add MemberSidebar component

This commit is contained in:
Pavel Prichodko 2022-03-16 12:42:30 +01:00
parent c1fba5e633
commit f9a99c3946
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
4 changed files with 224 additions and 0 deletions

View File

@ -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',
},
})

View File

@ -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>
)
}

View File

@ -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>
)
}

View File

@ -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',
})