implemented identity logout

This commit is contained in:
Roland Osborne 2022-08-06 00:24:13 -07:00
parent e20c6cf6fb
commit 7fd7efa029
9 changed files with 185 additions and 6 deletions

View File

@ -2,8 +2,12 @@ const Colors = {
background: '#8fbea7',
primary: '#8fbea7',
formBackground: '#f4f4f4',
formHover: '#e8e8e8',
grey: '#888888',
white: '#f8f8f8',
divider: '#dddddd',
encircle: '#cccccc',
alert: '#ff8888',
};
export default Colors;

View File

@ -3,9 +3,9 @@ import { useEffect, useState } from 'react';
export function useViewportContext() {
const [state, setState] = useState({ });
const SMALL_MEDIUM = 640;
const MEDIUM_LARGE = 1024;
const LARGE_XLARGE = 1600;
const SMALL_MEDIUM = 600;
const MEDIUM_LARGE = 1000;
const LARGE_XLARGE = 1400;
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

After

Width:  |  Height:  |  Size: 70 KiB

14
net/web/src/logo/Logo.jsx Normal file
View File

@ -0,0 +1,14 @@
import avatar from 'images/avatar.png';
export function Logo({ url, width, height, radius }) {
return (
<div style={{ borderRadius: radius, overflow: 'hidden' }}>
{ url && (
<img src={url} alt="logo" width={width} height={height} />
)}
{ !url && (
<img src={avatar} alt="default logo" width={width} height={height} />
)}
</div>
);
}

View File

@ -11,11 +11,31 @@ export const SessionWrapper = styled.div`
}
.desktop-layout {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
.left {
min-width: 256px;
max-width: 384px;
width: 20%;
height: 100%;
background-color: yellow;
display: flex;
flex-direction: column;
}
.center {
flex-grow: 1;
}
.right {
min-width: 256px;
max-width: 384px;
width: 20%;
height: 100%;
background-color: yellow;
display: flex;
flex-direction: column;
}
}

View File

@ -1,11 +1,54 @@
import { useContext } from 'react';
import { AppContext } from 'context/AppContext';
import { Button } from 'antd';
import { Dropdown, Menu, Tooltip } from 'antd';
import { Logo } from 'logo/Logo';
import { IdentityWrapper } from './Identity.styled';
import { useIdentity } from './useIdentity.hook';
import { ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons';
export function Identity() {
const app = useContext(AppContext);
const { state, actions } = useIdentity();
return <Button type="primary" onClick={() => app.actions.logout()}>Logout</Button>
const menu = (
<Menu>
<Menu.Item key="0">
<div>Edit Profile</div>
</Menu.Item>
<Menu.Item key="1">
<div>Change Login</div>
</Menu.Item>
<Menu.Item key="2">
<div onClick={actions.logout}>Logout</div>
</Menu.Item>
</Menu>
);
return (
<Dropdown overlay={menu} overlayStyle={{ minWidth: 0 }} trigger={['click']} placement="bottomRight">
<IdentityWrapper>
{ state.init && (
<Logo url={state.url} width={48} height={48} radius={4} />
)}
<div class="label">
<div class="name">{state.name}</div>
<div class="handle">
<div class="alert">
{ state.disconnected && (
<Tooltip placement="right" title="disconnected from server">
<ExclamationCircleOutlined />
</Tooltip>
)}
</div>
<div>{state.handle}</div>
<div class="alert"></div>
</div>
</div>
<div class="drop">
<DownOutlined />
</div>
</IdentityWrapper>
</Dropdown>
);
}

View File

@ -0,0 +1,56 @@
import styled from 'styled-components';
import Colors from 'constants/Colors';
export const IdentityWrapper = styled.div`
width: 100%;
height: 64px;
display: flex;
flex-direction: row;
align-items: center;
padding-left: 16px;
padding-right: 16px;
border-bottom: 1px solid ${Colors.divider};
background-color: ${Colors.formBackground};
&:hover {
cursor: pointer;
.drop {
border: 1px solid ${Colors.encircle};
background-color: ${Colors.formHover};
}
}
.drop {
padding-left: 4px;
padding-right: 4px;
border-radius: 8px;
border: 1px solid ${Colors.formBackground};
}
.label {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.name {
font-size: 1.2em;
}
.handle {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-weight: bold;
.alert {
width: 24px;
color: ${Colors.alert};
}
}
}
`;

View File

@ -0,0 +1,42 @@
import { useState, useEffect, useContext } from 'react';
import { ProfileContext } from 'context/ProfileContext';
import { AppContext } from 'context/AppContext';
export function useIdentity() {
const [state, setState] = useState({
url: null,
name: null,
handle: null,
disconnected: false,
init: false,
});
const app = useContext(AppContext);
const profile = useContext(ProfileContext);
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
useEffect(() => {
if (profile.state.init) {
const { name, handle, image } = profile.state.profile;
let url = !image ? null : profile.actions.profileImageUrl();
updateState({ init: true, name, handle, url });
}
}, [profile]);
useEffect(() => {
if (app.state) {
updateState({ disconnected: app.state.disconnected });
}
}, [app]);
const actions = {
logout: app.actions.logout,
};
return { state, actions };
}