mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
implemented identity logout
This commit is contained in:
parent
e20c6cf6fb
commit
7fd7efa029
@ -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;
|
||||
|
@ -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 }));
|
||||
|
BIN
net/web/src/images/avatar.png
Normal file
BIN
net/web/src/images/avatar.png
Normal file
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
14
net/web/src/logo/Logo.jsx
Normal 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>
|
||||
);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
|
56
net/web/src/session/identity/Identity.styled.js
Normal file
56
net/web/src/session/identity/Identity.styled.js
Normal 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};
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
42
net/web/src/session/identity/useIdentity.hook.js
Normal file
42
net/web/src/session/identity/useIdentity.hook.js
Normal 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 };
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user