refactor profile & account components for webapp

This commit is contained in:
Roland Osborne 2023-01-22 21:51:14 -08:00
parent ef73615d20
commit 5078538a4b
15 changed files with 285 additions and 365 deletions

View File

@ -37,6 +37,10 @@ export function useAppContext(websocket) {
const channelContext = useContext(ChannelContext);
const cardContext = useContext(CardContext);
useEffect(() => {
console.log(state.status);
}, [state.status]);
const setSession = (token) => {
try {
accountContext.actions.setToken(token);

View File

@ -7,7 +7,7 @@ import { Identity } from './identity/Identity';
import { Channels } from './channels/Channels';
import { Cards } from './cards/Cards';
import { Contact } from './contact/Contact';
import { Profile } from './profile/Profile';
import { Profile } from './account/profile/Profile';
import { Listing } from './listing/Listing';
import { Account } from './account/Account';
import { Welcome } from './welcome/Welcome';

View File

@ -1,24 +1,24 @@
import { AccountWrapper } from './Account.styled';
import { DoubleRightOutlined } from '@ant-design/icons';
import { SettingOutlined } from '@ant-design/icons';
import { AccountAccess } from '../accountAccess/AccountAccess';
import { AccountAccess } from './profile/accountAccess/AccountAccess';
export function Account({ closeAccount, openProfile }) {
return (
<AccountWrapper>
<div class="header">
<div class="label">Account</div>
<div class="dismiss" onClick={closeAccount}>
<div className="header">
<div className="label">Account</div>
<div className="dismiss" onClick={closeAccount}>
<DoubleRightOutlined />
</div>
</div>
<div class="content">
<div className="content">
<AccountAccess />
<div class="bottom">
<div class="link" onClick={openProfile}>
<div className="bottom">
<div className="link" onClick={openProfile}>
<SettingOutlined />
<div class="label">Update Profile</div>
<div className="label">Update Profile</div>
</div>
</div>
</div>

View File

@ -1,15 +1,16 @@
import { useRef } from 'react';
import { Modal, Button } from 'antd';
import { Space, Modal, Button } from 'antd';
import { ProfileWrapper, EditFooter } from './Profile.styled';
import { useProfile } from './useProfile.hook';
import { ProfileImage } from './profileImage/ProfileImage';
import { ProfileDetails } from './profileDetails/ProfileDetails';
import { Logo } from 'logo/Logo';
import { AccountAccess } from '../accountAccess/AccountAccess';
import { AccountAccess } from './accountAccess/AccountAccess';
import { LogoutOutlined, RightOutlined, EditOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons';
export function Profile({ closeProfile }) {
const [ modal, modalContext ] = Modal.useModal();
const { state, actions } = useProfile();
const imageFile = useRef(null);
@ -28,7 +29,7 @@ export function Profile({ closeProfile }) {
}
catch(err) {
console.log(err);
Modal.error({
modal.error({
title: 'Failed to Save',
content: 'Please try again.',
});
@ -42,7 +43,7 @@ export function Profile({ closeProfile }) {
}
catch(err) {
console.log(err);
Modal.error({
modal.error({
title: 'Failed to Save',
content: 'Please try again.',
});
@ -50,7 +51,7 @@ export function Profile({ closeProfile }) {
}
const logout = () => {
Modal.confirm({
modal.confirm({
title: 'Are you sure you want to logout?',
icon: <LogoutOutlined />,
onOk() {
@ -60,54 +61,11 @@ export function Profile({ closeProfile }) {
});
}
const Image = (
<div class="logo" onClick={actions.setEditProfileImage}>
<Logo url={state.url} width={'100%'} radius={4} />
<div class="edit">
<EditOutlined />
</div>
</div>
);
const Details = (
<div class="details">
<div class="name" onClick={actions.setEditProfileDetails}>
{ state.name && (
<div class="data">{ state.name }</div>
)}
{ !state.name && (
<div class="data notset">name</div>
)}
<div class="icon">
<EditOutlined />
</div>
</div>
<div class="location">
<EnvironmentOutlined />
{ state.location && (
<div class="data">{ state.location }</div>
)}
{ !state.location && (
<div class="data notset">location</div>
)}
</div>
<div class="description">
<BookOutlined />
{ state.description && (
<div class="data">{ state.description }</div>
)}
{ !state.description && (
<div class="data notset">description</div>
)}
</div>
</div>
);
const editImageFooter = (
<EditFooter>
<input type='file' id='file' accept="image/*" ref={imageFile} onChange={e => selected(e)} style={{display: 'none'}}/>
<div class="select">
<Button key="select" class="select" onClick={() => imageFile.current.click()}>Select Image</Button>
<div className="select">
<Button key="select" className="select" onClick={() => imageFile.current.click()}>Select Image</Button>
</div>
<Button key="back" onClick={actions.clearEditProfileImage}>Cancel</Button>
<Button key="save" type="primary" onClick={saveImage} loading={state.busy}>Save</Button>
@ -116,7 +74,7 @@ export function Profile({ closeProfile }) {
const editDetailsFooter = (
<EditFooter>
<div class="select"></div>
<div className="select"></div>
<Button key="back" onClick={actions.clearEditProfileDetails}>Cancel</Button>
<Button key="save" type="primary" onClick={saveDetails} loading={state.busy}>Save</Button>
</EditFooter>
@ -124,36 +82,69 @@ export function Profile({ closeProfile }) {
return (
<ProfileWrapper>
{ state.init && state.display === 'xlarge' && (
<>
<div class="header">
<div class="handle">{ state.handle }</div>
<div class="close" onClick={closeProfile}>
{ modalContext }
{ state.display === 'xlarge' && (
<div className="middleHeader">
<div className="handle">{ state.handle }</div>
<div className="close" onClick={closeProfile}>
<RightOutlined />
</div>
</div>
<div class="content">
{ Image }
{ Details }
</div>
</>
)}
{ state.init && state.display !== 'xlarge' && (
<div class="view">
<div class="title">{ state.handle }</div>
<div class="section">Profile Settings</div>
<div class="controls">
{ Image }
{ Details }
{ state.display !== 'xlarge' && (
<div className="rightHeader">
<div className="title">{ state.handle }</div>
<div className="section">Profile Settings</div>
</div>
<div class="section">Account Settings</div>
<div class="controls">
)}
<div className={ state.display === 'xlarge' ? 'midContent' : 'rightContent' }>
<div className="logo" onClick={actions.setEditProfileImage}>
<Logo url={state.url} width={'100%'} radius={4} />
<div className="edit">
<EditOutlined />
</div>
</div>
<div className="details">
<div className="name" onClick={actions.setEditProfileDetails}>
{ state.name && (
<div className="data">{ state.name }</div>
)}
{ !state.name && (
<div className="data notset">name</div>
)}
<div className="icon">
<EditOutlined />
</div>
</div>
<div className="location">
<EnvironmentOutlined />
{ state.location && (
<div className="data">{ state.location }</div>
)}
{ !state.location && (
<div className="data notset">location</div>
)}
</div>
<div className="description">
<BookOutlined />
{ state.description && (
<div className="data">{ state.description }</div>
)}
{ !state.description && (
<div className="data notset">description</div>
)}
</div>
</div>
</div>
{ state.init && state.display !== 'xlarge' && (
<div className="account">
<div className="section">Account Settings</div>
<div className="controls">
<AccountAccess />
{ state.display === 'small' && (
<div class="logout" onClick={logout}>
<div className="logout" onClick={logout}>
<LogoutOutlined />
<div class="label">Logout</div>
<div className="label">Logout</div>
</div>
)}
</div>

View File

@ -0,0 +1,207 @@
import styled from 'styled-components';
import Colors from 'constants/Colors';
export const ProfileWrapper = styled.div`
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
background-color: ${Colors.profileForm};
.middleHeader {
margin-left: 16px;
margin-right: 16px;
height: 48px;
border-bottom: 1px solid ${Colors.profileDivider};
display: flex;
flex-direction: row;
align-items: center;
flex-shrink: 0;
.handle {
font-size: 20px;
font-weight: bold;
flex-grow: 1;
padding-left: 16px;
}
.close {
font-size: 16px;
color: ${Colors.primary};
cursor: pointer;
padding-right: 16px;
}
}
.rightHeader {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
.title {
font-size: 18px;
font-weight: bold;
}
}
.section {
width: 100%;
color: ${Colors.grey};
padding-top: 24px;
font-size: 12px;
display: flex;
widtH: 75%;
justify-content: center;
border-bottom: 1px solid ${Colors.divider};
}
.logo {
position: relative;
width: 20vw;
cursor: pointer;
margin-left: 32px;
margin-right: 32px;
&:hover .edit {
opacity: 1;
}
.edit {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
border-top-left-radius: 4px;
border-bottom-right-radius: 4px;
width: 24px;
height: 24px;
bottom: 0;
right: 0;
color: ${Colors.link};
background-color: ${Colors.white};
opacity: 0.7;
}
}
.midContent {
min-height: 0;
width: 100%;
overflow: auto;
display: flex;
flex-direction: row;
justify-content: center;
padding-top: 32px;
}
.rightContent {
min-height: 0;
width: 100%;
overflow: auto;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 4px;
padding: 8px;
}
.details {
display: flex;
flex-direction: column;
.notset {
font-style: italic;
color: ${Colors.grey};
}
.name {
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
&:hover .icon {
border: 1px solid ${Colors.grey};
background-color: ${Colors.white};
}
.icon {
padding-left: 4px;
padding-right: 4px;
border: 1px solid ${Colors.profileForm};
border-raidus: 4px;
}
.data {
padding-right: 4px;
font-size: 24px;
font-weight: bold;
}
}
.location {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 8px;
.data {
padding-left: 8px;
}
}
.description {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 8px;
.data {
padding-left: 8px;
}
}
}
.account {
display: flex;
flex-direction: column;
align-items: center;
}
.controls {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-top: 1px solid ${Colors.divider};
border-radius: 4px;
padding: 8px;
width: 75%;
}
.logout {
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
color: ${Colors.white};
background-color: ${Colors.primary};
margin-top: 8px;
padding: 8px;
border-radius: 4px;
.label {
padding-left: 8px;
}
}
`
export const EditFooter = styled.div`
width: 100%;
display: flex;
.select {
display: flex;
flex-grow: 1;
}
`

View File

@ -1,282 +0,0 @@
import styled from 'styled-components';
import Colors from 'constants/Colors';
export const ProfileWrapper = styled.div`
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
background-color: ${Colors.profileForm};
.header {
margin-left: 16px;
margin-right: 16px;
height: 48px;
border-bottom: 1px solid ${Colors.profileDivider};
display: flex;
flex-direction: row;
align-items: center;
flex-shrink: 0;
.handle {
font-size: 20px;
font-weight: bold;
flex-grow: 1;
padding-left: 16px;
}
.close {
font-size: 16px;
color: ${Colors.primary};
cursor: pointer;
padding-right: 16px;
}
}
.content {
min-height: 0;
width: 100%;
overflow: auto;
display: flex;
flex-direction: row;
justify-content: center;
padding-top: 32px;
.logo {
position: relative;
width: 20vw;
margin-right: 32px;
cursor: pointer;
&:hover .edit {
opacity: 1;
}
.edit {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
border-top-left-radius: 4px;
border-bottom-right-radius: 4px;
width: 24px;
height: 24px;
bottom: 0;
right: 0;
color: ${Colors.link};
background-color: ${Colors.white};
opacity: 0.7;
}
}
.details {
display: flex;
flex-direction: column;
.notset {
font-style: italic;
color: ${Colors.grey};
}
.name {
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
&:hover .icon {
border: 1px solid ${Colors.grey};
background-color: ${Colors.white};
}
.icon {
padding-left: 4px;
padding-right: 4px;
border: 1px solid ${Colors.profileForm};
border-raidus: 4px;
}
.data {
padding-right: 4px;
font-size: 24px;
font-weight: bold;
}
}
.location {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 8px;
.data {
padding-left: 8px;
}
}
.description {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 8px;
.data {
padding-left: 8px;
}
}
}
}
.view {
width: 100%;
height: 100%;
overflow: auto;
display: flex;
flex-direction: column;
align-items: center;
.title {
font-size: 18px;
font-weight: bold;
}
.logo {
position: relative;
width: 60%;
margin-bottom: 16px;
cursor: pointer;
&:hover .edit {
opacity: 1;
}
.edit {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
border-top-left-radius: 4px;
border-bottom-right-radius: 4px;
width: 24px;
height: 24px;
bottom: 0;
right: 0;
color: ${Colors.link};
background-color: ${Colors.white};
opacity: 0.7;
}
}
.details {
display: flex;
flex-direction: column;
align-items: center;
.name {
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
&:hover .icon {
border: 1px solid ${Colors.grey};
background-color: ${Colors.white};
}
.icon {
padding-left: 4px;
padding-right: 4px;
border: 1px solid ${Colors.profileForm};
border-radius: 4px;
}
.data {
padding-right: 4px;
font-size: 24px;
font-weight: bold;
}
}
.location {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 8px;
.data {
padding-left: 8px;
}
}
.description {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 8px;
.data {
padding-left: 8px;
}
}
}
.section {
width: 100%;
color: ${Colors.grey};
padding-top: 24px;
font-size: 12px;
display: flex;
justify-content: center;
}
.controls {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-top: 1px solid ${Colors.divider};
border-radius: 4px;
padding: 8px;
width: 75%;
}
.link {
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
color: ${Colors.primary};
padding-top: 8px;
.label {
padding-left: 8px;
}
}
.logout {
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
color: ${Colors.white};
background-color: ${Colors.primary};
margin-top: 8px;
padding: 8px;
border-radius: 4px;
.label {
padding-left: 8px;
}
}
}
`
export const EditFooter = styled.div`
width: 100%;
display: flex;
.select {
display: flex;
flex-grow: 1;
}
`