styling remaining profile modals

This commit is contained in:
Roland Osborne 2024-02-23 23:21:58 -08:00
parent 606b8c4122
commit 82c8221f2e
4 changed files with 126 additions and 68 deletions

View File

@ -1,6 +1,6 @@
import { useRef, useCallback } from 'react'; import { useRef, useCallback } from 'react';
import { Modal, Input, Button, Switch } from 'antd'; import { Modal, Input, Button, Switch } from 'antd';
import { LogoutContent, ProfileWrapper, ProfileDetailsWrapper, ProfileImageWrapper, EditFooter } from './Profile.styled'; import { LogoutContent, ProfileWrapper, ProfileDetailsWrapper, ProfileImageWrapper } from './Profile.styled';
import { useProfile } from './useProfile.hook'; import { useProfile } from './useProfile.hook';
import { Logo } from 'logo/Logo'; import { Logo } from 'logo/Logo';
import { AccountAccess } from './accountAccess/AccountAccess'; import { AccountAccess } from './accountAccess/AccountAccess';
@ -70,17 +70,6 @@ export function Profile({ closeProfile }) {
}); });
} }
const editImageFooter = (
<EditFooter>
<input type='file' id='file' accept="image/*" ref={imageFile} onChange={e => selected(e)} style={{display: 'none'}}/>
<div className="select">
<Button key="select" className="pic" 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>
</EditFooter>
);
const onCropComplete = useCallback((area, crop) => { const onCropComplete = useCallback((area, crop) => {
actions.setEditImageCrop(crop.width, crop.height, crop.x, crop.y) actions.setEditImageCrop(crop.width, crop.height, crop.x, crop.y)
// eslint-disable-next-line // eslint-disable-next-line
@ -156,12 +145,23 @@ export function Profile({ closeProfile }) {
<div className="contentFill" /> <div className="contentFill" />
</div> </div>
)} )}
<Modal title="Profile Image" centered visible={state.editProfileImage} footer={editImageFooter} <Modal centered closable={false} visible={state.editProfileImage} footer={null}
bodyStyle={{ padding: 16 }} onCancel={actions.clearEditProfileImage}> bodyStyle={{ borderRadius: 8, padding: 16, ...state.menuStyle }} onCancel={actions.clearEditProfileImage}>
<ProfileImageWrapper> <ProfileImageWrapper>
<Cropper image={state.editImage} crop={state.crop} zoom={state.zoom} aspect={1} <div className="title">Profile Image</div>
onCropChange={actions.setCrop} onCropComplete={onCropComplete} onZoomChange={actions.setZoom} /> <div className="cropper">
<Cropper image={state.editImage} crop={state.crop} zoom={state.zoom} aspect={1}
onCropChange={actions.setCrop} onCropComplete={onCropComplete} onZoomChange={actions.setZoom} />
</div>
<div className="controls">
<input type='file' id='file' accept="image/*" ref={imageFile} onChange={e => selected(e)} style={{display: 'none'}}/>
<div className="select">
<Button key="select" className="pic" 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>
</div>
</ProfileImageWrapper> </ProfileImageWrapper>
</Modal> </Modal>

View File

@ -229,15 +229,6 @@ export const LogoutContent = styled.div`
} }
` `
export const EditFooter = styled.div`
width: 100%;
display: flex;
.select {
display: flex;
flex-grow: 1;
}
`
export const ProfileDetailsWrapper = styled.div` export const ProfileDetailsWrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -287,11 +278,34 @@ export const ProfileDetailsWrapper = styled.div`
`; `;
export const ProfileImageWrapper = styled.div` export const ProfileImageWrapper = styled.div`
position: relative;
height: 256px;
width: 100%;
display: flex; display: flex;
align-items: center; flex-direction: column;
justify-content: center; justify-content: center;
gap: 16px;
.cropper {
position: relative;
height: 256px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.title {
font-size: 1.2rem;
display: flex;
justify-content: center;
}
.controls {
display: flex;
justify-content: flex-end;
gap: 16px;
.select {
flex-grow: 1;
}
}
`; `;

View File

@ -52,22 +52,6 @@ export function AccountAccess() {
} }
} }
const editSealFooter = (
<div>
<div className="select"></div>
<Button key="back" onClick={actions.clearEditSeal}>Cancel</Button>
{ state.sealMode === 'enabled' && (
<Button key="save" type="primary" onClick={saveSeal} loading={state.busy}>Forget</Button>
)}
{ state.sealMode === 'unlocking' && (
<Button key="save" type="primary" onClick={saveSeal} disabled={!actions.canSaveSeal()} loading={state.busy}>Unlock</Button>
)}
{ state.sealMode !== 'unlocking' && state.sealMode !== 'enabled' && (
<Button key="save" type="primary" onClick={saveSeal} disabled={!actions.canSaveSeal()} loading={state.busy}>Save</Button>
)}
</div>
);
return ( return (
<AccountAccessWrapper> <AccountAccessWrapper>
{ modalContext } { modalContext }
@ -127,42 +111,55 @@ export function AccountAccess() {
</div> </div>
</div> </div>
</div> </div>
<Modal title="Topic Sealing Key" centered visible={state.editSeal} footer={editSealFooter} onCancel={actions.clearEditSeal} bodyStyle={{ padding: 16 }}> <Modal centered closable={false} visible={state.editSeal} footer={null} onCancel={actions.clearEditSeal} bodyStyle={{ borderRadius: 8, padding: 16, ...state.menuStyle }}>
<SealModal> <SealModal>
<div className="title">Topic Sealing Key</div>
<div className="switch"> <div className="switch">
<Switch size="small" checked={state.sealEnabled} onChange={enable => actions.enableSeal(enable)} /> <Switch size="small" checked={state.sealEnabled} onChange={enable => actions.enableSeal(enable)} />
<div className="switchLabel">Enable Sealed Topics</div> <div className="switchLabel">Enable Sealed Topics</div>
</div> </div>
{ (state.sealMode === 'updating' || state.sealMode === 'enabling') && ( { (state.sealMode === 'updating' || state.sealMode === 'enabling') && (
<div className="sealPassword"> <div className="sealChange">
<Input.Password placeholder="New Password" spellCheck="false" onChange={(e) => actions.setSealPassword(e.target.value)} <Input.Password placeholder="New Password" spellCheck="false" onChange={(e) => actions.setSealPassword(e.target.value)}
autocomplete="new-password" prefix={<LockOutlined />} /> autocomplete="new-password" prefix={<LockOutlined />} />
</div> </div>
)} )}
{ (state.sealMode === 'updating' || state.sealMode === 'enabling') && ( { (state.sealMode === 'updating' || state.sealMode === 'enabling') && (
<div className="sealPassword"> <div className="sealChange">
<Input.Password placeholder="Confirm Password" spellCheck="false" onChange={(e) => actions.setSealConfirm(e.target.value)} <Input.Password placeholder="Confirm Password" spellCheck="false" onChange={(e) => actions.setSealConfirm(e.target.value)}
autocomplete="new-password" prefix={<LockOutlined />} /> autocomplete="new-password" prefix={<LockOutlined />} />
</div> </div>
)} )}
{ state.sealMode === 'disabling' && ( { state.sealMode === 'disabling' && (
<div className="sealPassword"> <div className="sealChange">
<Input placeholder="Type 'delete' to remove key" spellCheck="false" onChange={(e) => actions.setSealDelete(e.target.value)} <Input placeholder="Type 'delete' to remove key" spellCheck="false" onChange={(e) => actions.setSealDelete(e.target.value)}
prefix={<ExclamationCircleOutlined />} /> prefix={<ExclamationCircleOutlined />} />
</div> </div>
)} )}
{ state.sealMode === 'enabled' && ( { state.sealMode === 'enabled' && (
<div className="sealPassword" onClick={() => actions.updateSeal()}> <div className="sealChange" onClick={() => actions.updateSeal()}>
<Input.Password defaultValue="xxxxxxxxxx" disabled={true} prefix={<LockOutlined />} /> <Input.Password defaultValue="xxxxxxxxxx" disabled={true} prefix={<LockOutlined />} />
<div className="editPassword" /> <div className="editPassword" />
</div> </div>
)} )}
{ state.sealMode === 'unlocking' && ( { state.sealMode === 'unlocking' && (
<div className="sealPassword"> <div className="sealChange">
<Input.Password placeholder="Password" spellCheck="false" onChange={(e) => actions.setSealUnlock(e.target.value)} <Input.Password placeholder="Password" spellCheck="false" onChange={(e) => actions.setSealUnlock(e.target.value)}
prefix={<LockOutlined />} /> prefix={<LockOutlined />} />
</div> </div>
)} )}
<div className="controls">
<Button key="back" onClick={actions.clearEditSeal}>Cancel</Button>
{ state.sealMode === 'enabled' && (
<Button key="save" type="primary" onClick={saveSeal} loading={state.busy}>Forget</Button>
)}
{ state.sealMode === 'unlocking' && (
<Button key="save" type="primary" onClick={saveSeal} className={actions.canSaveSeal() ? 'saveEnabled' : 'saveDisabled'} disabled={!actions.canSaveSeal()} loading={state.busy}>Unlock</Button>
)}
{ state.sealMode !== 'unlocking' && state.sealMode !== 'enabled' && (
<Button key="save" type="primary" onClick={saveSeal} className={actions.canSaveSeal() ? 'saveEnabled' : 'saveDisabled'} disabled={!actions.canSaveSeal()} loading={state.busy}>Save</Button>
)}
</div>
</SealModal> </SealModal>
</Modal> </Modal>
<Modal centered closable={false} footer={null} visible={state.editLogin} bodyStyle={{ borderRadius: 8, padding: 16, ...state.menuStyle }} onCancel={actions.clearEditLogin}> <Modal centered closable={false} footer={null} visible={state.editLogin} bodyStyle={{ borderRadius: 8, padding: 16, ...state.menuStyle }} onCancel={actions.clearEditLogin}>

View File

@ -91,16 +91,17 @@ export const AccountAccessWrapper = styled.div`
export const SealModal = styled.div` export const SealModal = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding-bottom: 8px; gap: 16px;
.title {
font-size: 1.2rem;
display: flex;
justify-content: center;
}
.switch { .switch {
display: flex; display: flex;
flex-direction: row;
align-items: center; align-items: center;
padding-bottom: 8px;
align-items: center;
justify-content: center;
padding-top: 8px;
.switchLabel { .switchLabel {
color: ${props => props.theme.mainText}; color: ${props => props.theme.mainText};
@ -109,19 +110,65 @@ export const SealModal = styled.div`
} }
} }
.sealPassword { .controls {
padding-top: 4px; width: 100%;
padding-bottom: 4px; display: flex;
position: relative; justify-content: flex-end;
gap: 16px;
.editPassword { .saveDisabled {
position: absolute; background-color: ${props => props.theme.disabledArea};
top: 0;
left: 0; button {
width: 100%; color: ${props => props.theme.idleText};
height: 100%; }
cursor: pointer;
} }
.saveEnabled {
background-color: ${props => props.theme.enabledArea};
button {
color: ${props => props.theme.activeText};
}
}
}
.sealChange {
width: 100%;
background-color: ${props => props.theme.inputArea};
color: ${props => props.theme.mainText};
border-radius: 8px;
.ant-input-affix-wrapper {
background-color: ${props => props.theme.inputArea};
}
.anticon {
color: ${props => props.theme.placeholderText};
&:hover {
color: ${props => props.theme.linkText};
}
}
input {
padding-left: 8px;
background-color: ${props => props.theme.inputArea};
color: ${props => props.theme.mainText};
}
input::placeholder {
color: ${props => props.theme.placeholderText};
}
}
.editPassword {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
} }
` `