Merge pull request #743 from toeverything/feat/datacenter-settings-style

feat:add datacenter settings style
This commit is contained in:
JimmFly
2023-01-19 15:39:45 +08:00
committed by GitHub
18 changed files with 286 additions and 148 deletions
@@ -44,7 +44,7 @@ const HeaderRightItems: Record<HeaderRightItemNames, ReactNode> = {
}; };
export const Header = ({ export const Header = ({
rightItems = ['syncUser'], rightItems = ['syncUser', 'themeModeSwitch'],
children, children,
}: PropsWithChildren<{ rightItems?: HeaderRightItemNames[] }>) => { }: PropsWithChildren<{ rightItems?: HeaderRightItemNames[] }>) => {
const [showWarning, setShowWarning] = useState(shouldShowWarning()); const [showWarning, setShowWarning] = useState(shouldShowWarning());
@@ -4,6 +4,7 @@ import {
StyledPublishCopyContainer, StyledPublishCopyContainer,
StyledPublishExplanation, StyledPublishExplanation,
StyledSettingH2, StyledSettingH2,
StyledStopPublishContainer,
} from './style'; } from './style';
import { useState } from 'react'; import { useState } from 'react';
import { Button } from '@/ui/button'; import { Button } from '@/ui/button';
@@ -42,7 +43,9 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
<StyledPublishExplanation> <StyledPublishExplanation>
{t('Publishing')} {t('Publishing')}
</StyledPublishExplanation> </StyledPublishExplanation>
<StyledSettingH2>{t('Share with link')}</StyledSettingH2> <StyledSettingH2 marginTop={48}>
{t('Share with link')}
</StyledSettingH2>
<StyledPublishCopyContainer> <StyledPublishCopyContainer>
<Input width={500} value={shareUrl} disabled={true}></Input> <Input width={500} value={shareUrl} disabled={true}></Input>
<StyledCopyButtonContainer> <StyledCopyButtonContainer>
@@ -54,24 +57,27 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
</> </>
) : ( ) : (
<StyledPublishExplanation> <StyledPublishExplanation>
{'Publishing Description'} {t('Publishing Description')}
</StyledPublishExplanation> </StyledPublishExplanation>
)} )}
</StyledPublishContent> </StyledPublishContent>
<StyledPublishCopyContainer>
{workspace.published ? ( {workspace.published ? (
<StyledStopPublishContainer>
<Button <Button
onClick={async () => { onClick={async () => {
setLoaded(false); setLoaded(false);
await togglePublic(false); await togglePublic(false);
setLoaded(true); setLoaded(true);
}} }}
type="primary" type="danger"
shape="circle" shape="circle"
> >
{t('Stop publishing')} {t('Stop publishing')}
</Button> </Button>
) : ( </StyledStopPublishContainer>
) : (
<StyledPublishCopyContainer>
<Button <Button
onClick={async () => { onClick={async () => {
setLoaded(false); setLoaded(false);
@@ -83,8 +89,8 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
> >
{t('Publish to web')} {t('Publish to web')}
</Button> </Button>
)} </StyledPublishCopyContainer>
</StyledPublishCopyContainer> )}
</div> </div>
) : ( ) : (
<StyledPublishContent> <StyledPublishContent>
@@ -2,6 +2,8 @@ import {
StyledPublishContent, StyledPublishContent,
StyledPublishCopyContainer, StyledPublishCopyContainer,
StyledPublishExplanation, StyledPublishExplanation,
StyledWorkspaceName,
StyledWorkspaceType,
} from './style'; } from './style';
import { DownloadIcon } from '@blocksuite/icons'; import { DownloadIcon } from '@blocksuite/icons';
import { Button } from '@/ui/button'; import { Button } from '@/ui/button';
@@ -9,6 +11,7 @@ import { Menu, MenuItem } from '@/ui/menu';
import { WorkspaceUnit } from '@affine/datacenter'; import { WorkspaceUnit } from '@affine/datacenter';
import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; import { useWorkspaceHelper } from '@/hooks/use-workspace-helper';
import { Trans, useTranslation } from '@affine/i18n'; import { Trans, useTranslation } from '@affine/i18n';
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => { export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
const { enableWorkspace } = useWorkspaceHelper(); const { enableWorkspace } = useWorkspaceHelper();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -18,11 +21,20 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
{workspace.provider === 'local' ? ( {workspace.provider === 'local' ? (
<> <>
<StyledPublishExplanation> <StyledPublishExplanation>
{t('Sync Description', { <WorkspaceUnitAvatar
workspaceName: workspace.name ?? 'Affine', size={32}
})} name={workspace.name}
workspaceUnit={workspace}
/>
<StyledWorkspaceName>
&nbsp;{workspace.name}&nbsp;
</StyledWorkspaceName>
<StyledWorkspaceType>is a Local Workspace.</StyledWorkspaceType>
</StyledPublishExplanation> </StyledPublishExplanation>
<StyledWorkspaceType>
All data is stored on the current device. You can enable AFFiNE
Cloud for this workspace to keep data in sync with the cloud.
</StyledWorkspaceType>
<StyledPublishCopyContainer> <StyledPublishCopyContainer>
<Button <Button
onClick={async () => { onClick={async () => {
@@ -30,6 +42,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
}} }}
type="primary" type="primary"
shape="circle" shape="circle"
style={{ fontWeight: '500' }}
> >
{t('Enable AFFiNE Cloud')} {t('Enable AFFiNE Cloud')}
</Button> </Button>
@@ -3,15 +3,17 @@ import {
// StyledSettingAvatar, // StyledSettingAvatar,
StyledSettingAvatarContent, StyledSettingAvatarContent,
StyledSettingInputContainer, StyledSettingInputContainer,
StyledDoneButtonContainer,
StyledInput,
} from './style'; } from './style';
import { StyledSettingH2 } from '../style'; import { StyledSettingH2 } from '../style';
import { useState } from 'react'; import { useState } from 'react';
import { Button, TextButton } from '@/ui/button'; import { Button } from '@/ui/button';
import Input from '@/ui/input';
import { useAppState } from '@/providers/app-state-provider'; import { useAppState } from '@/providers/app-state-provider';
import { WorkspaceDelete } from './delete'; import { WorkspaceDelete } from './delete';
import { WorkspaceLeave } from './leave'; import { WorkspaceLeave } from './leave';
import { DoneIcon, CloudUnsyncedIcon } from '@blocksuite/icons';
// import { Upload } from '@/components/file-upload'; // import { Upload } from '@/components/file-upload';
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar'; import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
import { WorkspaceUnit } from '@affine/datacenter'; import { WorkspaceUnit } from '@affine/datacenter';
@@ -44,7 +46,7 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
return workspace ? ( return workspace ? (
<div> <div>
<StyledSettingH2 marginTop={56}>{t('Workspace Icon')}</StyledSettingH2> <StyledSettingH2 marginTop={56}>Workspace Avatar</StyledSettingH2>
<StyledSettingAvatarContent> <StyledSettingAvatarContent>
<div <div
style={{ style={{
@@ -69,29 +71,30 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
</StyledSettingAvatarContent> </StyledSettingAvatarContent>
<StyledSettingH2 marginTop={20}>{t('Workspace Name')}</StyledSettingH2> <StyledSettingH2 marginTop={20}>{t('Workspace Name')}</StyledSettingH2>
<StyledSettingInputContainer> <StyledSettingInputContainer>
<Input <StyledInput
width={327} width={284}
height={32}
value={workspaceName} value={workspaceName}
placeholder={t('Workspace Name')} placeholder={t('Workspace Name')}
maxLength={14} maxLength={14}
minLength={1} minLength={1}
disabled={!isOwner} disabled={!isOwner}
onChange={handleChangeWorkSpaceName} onChange={handleChangeWorkSpaceName}
></Input> ></StyledInput>
{isOwner ? ( {isOwner ? (
<TextButton <StyledDoneButtonContainer
onClick={() => { onClick={() => {
handleUpdateWorkspaceName(); handleUpdateWorkspaceName();
}} }}
style={{ marginLeft: '0px' }}
> >
<DoneIcon />
</TextButton> </StyledDoneButtonContainer>
) : null} ) : null}
</StyledSettingInputContainer> </StyledSettingInputContainer>
<StyledSettingH2 marginTop={20}>{t('Workspace Type')}</StyledSettingH2> <StyledSettingH2 marginTop={20}>{t('Workspace Type')}</StyledSettingH2>
<StyledSettingInputContainer> <StyledSettingInputContainer>
<code>{workspace.provider} </code> <CloudUnsyncedIcon style={{ marginRight: '15px' }} />
Local workspace
</StyledSettingInputContainer> </StyledSettingInputContainer>
<StyledDeleteButtonContainer> <StyledDeleteButtonContainer>
{isOwner ? ( {isOwner ? (
@@ -99,6 +102,7 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
<Button <Button
type="danger" type="danger"
shape="circle" shape="circle"
style={{ borderRadius: '40px' }}
onClick={() => { onClick={() => {
setShowDelete(true); setShowDelete(true);
}} }}
@@ -46,7 +46,7 @@ export const WorkspaceDelete = ({
<Modal open={open} onClose={onClose}> <Modal open={open} onClose={onClose}>
<StyledModalWrapper> <StyledModalWrapper>
<ModalCloseButton onClick={onClose} /> <ModalCloseButton onClick={onClose} />
<StyledModalHeader>{t('Delete Workspace')}</StyledModalHeader> <StyledModalHeader>{t('Delete Workspace')}?</StyledModalHeader>
{workspace.provider === 'local' ? ( {workspace.provider === 'local' ? (
<StyledTextContent> <StyledTextContent>
<Trans i18nKey="Delete Workspace Description"> <Trans i18nKey="Delete Workspace Description">
@@ -75,6 +75,8 @@ export const WorkspaceDelete = ({
onChange={handlerInputChange} onChange={handlerInputChange}
placeholder={t('Delete Workspace placeholder')} placeholder={t('Delete Workspace placeholder')}
value={deleteStr} value={deleteStr}
width={284}
height={42}
></Input> ></Input>
</StyledInputContent> </StyledInputContent>
<StyledButtonContent> <StyledButtonContent>
@@ -4,20 +4,20 @@ export const StyledModalWrapper = styled('div')(({ theme }) => {
return { return {
position: 'relative', position: 'relative',
padding: '0px', padding: '0px',
width: '460px', width: '560px',
background: theme.colors.popoverBackground, background: theme.colors.popoverBackground,
borderRadius: '12px', borderRadius: '12px',
height: '312px',
}; };
}); });
export const StyledModalHeader = styled('div')(({ theme }) => { export const StyledModalHeader = styled('div')(({ theme }) => {
return { return {
margin: '44px 0px 12px 0px', margin: '44px 0px 12px 0px',
width: '460px', width: '560px',
fontWeight: '600', fontWeight: '600',
fontSize: '20px;', fontSize: '20px;',
textAlign: 'left', textAlign: 'center',
paddingLeft: '20px',
color: theme.colors.popoverColor, color: theme.colors.popoverColor,
}; };
}); });
@@ -37,21 +37,25 @@ export const StyledTextContent = styled('div')(() => {
}; };
}); });
export const StyledInputContent = styled('div')(() => { export const StyledInputContent = styled('div')(({ theme }) => {
return { return {
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'center', justifyContent: 'center',
margin: '20px 0 24px 0', margin: '32px 0',
fontSize: theme.font.base,
}; };
}); });
export const StyledButtonContent = styled('div')(() => { export const StyledButtonContent = styled('div')(() => {
return { return {
position: 'absolute',
left: '50%',
transform: 'translateX(-50%)',
bottom: '32px',
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'center', justifyContent: 'center',
margin: '0px 0 32px 0',
}; };
}); });
@@ -1,15 +1,42 @@
import { styled } from '@/styles'; import { displayFlex, styled } from '@/styles';
import MuiAvatar from '@mui/material/Avatar'; import MuiAvatar from '@mui/material/Avatar';
import IconButton from '@/ui/button/IconButton';
import Input from '@/ui/input';
export const StyledSettingInputContainer = styled('div')(() => { export const StyledSettingInputContainer = styled('div')(() => {
return { return {
marginTop: '12px', marginTop: '12px',
width: '100%',
...displayFlex('flex-start', 'center'),
}; };
}); });
export const StyledDeleteButtonContainer = styled('div')(() => { export const StyledDeleteButtonContainer = styled('div')(() => {
return { return {
marginTop: '30px', position: 'absolute',
bottom: '0',
left: '50%',
marginBottom: '20px',
transform: 'translateX(-50%)',
};
});
export const StyledDoneButtonContainer = styled(IconButton)(({ theme }) => {
return {
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: '10px',
height: '32px',
overflow: 'hidden',
marginLeft: '20px',
':hover': {
borderColor: theme.colors.primaryColor,
},
};
});
export const StyledInput = styled(Input)(({ theme }) => {
return {
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: '10px',
fontSize: theme.font.sm,
}; };
}); });
@@ -122,6 +122,7 @@ export const InviteMemberModal = ({
<Button <Button
shape="circle" shape="circle"
type="primary" type="primary"
style={{ width: '364px', height: '38px', borderRadius: '40px' }}
onClick={async () => { onClick={async () => {
await inviteMember(email); await inviteMember(email);
onInviteSuccess(); onInviteSuccess();
@@ -143,10 +144,8 @@ const Header = styled('div')({
const Content = styled('div')({ const Content = styled('div')({
display: 'flex', display: 'flex',
padding: '0 48px',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
gap: '16px',
}); });
const ContentTitle = styled('h1')({ const ContentTitle = styled('h1')({
@@ -158,9 +157,8 @@ const ContentTitle = styled('h1')({
}); });
const Footer = styled('div')({ const Footer = styled('div')({
height: '70px', height: '102px',
paddingLeft: '24px', margin: '32px 0',
marginTop: '32px',
textAlign: 'center', textAlign: 'center',
}); });
@@ -159,7 +159,7 @@ export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
return ( return (
<StyledMemberWarp> <StyledMemberWarp>
<>{t('Collaboration Description')}</> {t('Collaboration Description')}
<StyledPublishExplanation> <StyledPublishExplanation>
<Button <Button
type="primary" type="primary"
@@ -19,6 +19,7 @@ export const StyledMemberNameContainer = styled('div')(() => {
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
width: '402px', width: '402px',
flex: 2,
}; };
}); });
@@ -27,6 +28,7 @@ export const StyledMemberRoleContainer = styled('div')(() => {
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
width: '222px', width: '222px',
flex: 1,
}; };
}); });
@@ -34,6 +36,8 @@ export const StyledMemberListContainer = styled('ul')(() => {
return { return {
marginTop: '15px', marginTop: '15px',
overflowY: 'scroll', overflowY: 'scroll',
width: '100%',
maxHeight: 'calc(100vh - 300px)',
}; };
}); });
@@ -42,6 +46,7 @@ export const StyledMemberListItem = styled('li')(() => {
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
height: '72px', height: '72px',
width: '100%',
}; };
}); });
@@ -71,7 +76,9 @@ export const StyledMemberEmail = styled('div')(({ theme }) => {
export const StyledMemberButtonContainer = styled('div')(() => { export const StyledMemberButtonContainer = styled('div')(() => {
return { return {
marginTop: '14px', position: 'absolute',
bottom: '0',
marginBottom: '20px',
}; };
}); });
@@ -83,6 +90,7 @@ export const StyledMoreVerticalButton = styled('button')(() => {
width: '24px', width: '24px',
height: '24px', height: '24px',
cursor: 'pointer', cursor: 'pointer',
paddingRight: '48px',
}; };
}); });
@@ -101,6 +109,8 @@ export const StyledMemberWarp = styled('div')(() => {
return { return {
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
padding: '40px 0', padding: '48px 0',
fontWeight: '500',
fontSize: '18px',
}; };
}); });
@@ -1,11 +1,11 @@
import { styled } from '@/styles'; import { displayFlex, styled } from '@/styles';
export const StyledSettingContainer = styled('div')(() => { export const StyledSettingContainer = styled('div')(() => {
return { return {
display: 'flex', display: 'flex',
padding: '50px',
flexDirection: 'column', flexDirection: 'column',
height: '100vh', marginTop: '24px',
marginLeft: '48px',
overflow: 'auto', overflow: 'auto',
}; };
}); });
@@ -20,9 +20,7 @@ export const StyledSettingSidebar = styled('div')(() => {
}); });
export const StyledSettingContent = styled('div')(() => { export const StyledSettingContent = styled('div')(() => {
return { return {};
paddingLeft: '48px',
};
}); });
export const StyledSetting = styled('div')(({ theme }) => { export const StyledSetting = styled('div')(({ theme }) => {
@@ -60,14 +58,26 @@ export const WorkspaceSettingTagItem = styled('li')<{ isActive?: boolean }>(
{ {
return { return {
display: 'flex', display: 'flex',
marginBottom: '12px', position: 'relative',
padding: '0 24px', margin: '0 48px 8px 0',
height: '32px', height: '34px',
color: isActive ? theme.colors.primaryColor : theme.colors.textColor, color: isActive ? theme.colors.primaryColor : theme.colors.textColor,
fontWeight: '400', fontWeight: '500',
fontSize: '16px', fontSize: theme.font.base,
lineHeight: '32px', lineHeight: theme.font.lineHeightBase,
cursor: 'pointer', cursor: 'pointer',
transition: 'all 0.15s ease',
'::after': {
content: '""',
width: '100%',
height: '2px',
background: isActive ? theme.colors.primaryColor : 'transparent',
transition: 'all 0.15s ease',
position: 'absolute',
left: '0',
bottom: '0',
},
':hover': { color: theme.colors.primaryColor },
}; };
} }
} }
@@ -84,11 +94,11 @@ export const StyledSettingTagIconContainer = styled('div')(() => {
}); });
export const StyledSettingH2 = styled('h2')<{ marginTop?: number }>( export const StyledSettingH2 = styled('h2')<{ marginTop?: number }>(
({ marginTop }) => { ({ marginTop, theme }) => {
return { return {
fontWeight: '500', fontWeight: '500',
fontSize: '18px', fontSize: theme.font.base,
lineHeight: '26px', lineHeight: theme.font.lineHeightBase,
marginTop: marginTop ? `${marginTop}px` : '0px', marginTop: marginTop ? `${marginTop}px` : '0px',
}; };
} }
@@ -96,12 +106,28 @@ export const StyledSettingH2 = styled('h2')<{ marginTop?: number }>(
export const StyledPublishExplanation = styled('div')(() => { export const StyledPublishExplanation = styled('div')(() => {
return { return {
...displayFlex('row', 'center', 'center'),
paddingRight: '48px', paddingRight: '48px',
fontWeight: '500', fontWeight: '500',
fontSize: '18px', fontSize: '18px',
lineHeight: '26px', lineHeight: '26px',
flex: 1, flex: 1,
marginTop: '60px', marginTop: '60px',
marginBottom: '22px',
};
});
export const StyledWorkspaceName = styled('div')(() => {
return {
fontWeight: '400',
fontSize: '18px',
lineHeight: '26px',
};
});
export const StyledWorkspaceType = styled('div')(() => {
return {
fontWeight: '500',
fontSize: '18px',
lineHeight: '26px',
}; };
}); });
@@ -109,16 +135,26 @@ export const StyledPublishCopyContainer = styled('div')(() => {
return { return {
marginTop: '12px', marginTop: '12px',
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'column',
alignItems: 'center', alignItems: 'start',
justifyContent: 'center',
marginBottom: '20px', marginBottom: '20px',
paddingTop: '20px', paddingTop: '20px',
}; };
}); });
export const StyledStopPublishContainer = styled('div')(() => {
return {
position: 'absolute',
bottom: '0',
left: '50%',
transform: 'translateX(-50%)',
marginBottom: '20px',
};
});
export const StyledCopyButtonContainer = styled('div')(() => { export const StyledCopyButtonContainer = styled('div')(() => {
return { return {
marginLeft: '12px', marginTop: '64px',
}; };
}); });
@@ -42,6 +42,8 @@ export const useWorkspaceHelper = () => {
content: `If enabled, the data in this workspace will be backed up and synchronized via AFFiNE Cloud.`, content: `If enabled, the data in this workspace will be backed up and synchronized via AFFiNE Cloud.`,
confirmText: user ? 'Enable' : 'Sign in and Enable', confirmText: user ? 'Enable' : 'Sign in and Enable',
cancelText: 'Skip', cancelText: 'Skip',
confirmType: 'primary',
buttonDirection: 'column',
}).then(async confirm => { }).then(async confirm => {
if (confirm && currentWorkspace) { if (confirm && currentWorkspace) {
if (!user) { if (!user) {
@@ -2,17 +2,9 @@ import {
StyledSettingContainer, StyledSettingContainer,
StyledSettingContent, StyledSettingContent,
StyledSettingSidebar, StyledSettingSidebar,
StyledSettingSidebarHeader,
StyledSettingTabContainer, StyledSettingTabContainer,
StyledSettingTagIconContainer,
WorkspaceSettingTagItem, WorkspaceSettingTagItem,
} from '@/components/workspace-setting/style'; } from '@/components/workspace-setting/style';
import {
EditIcon,
UsersIcon,
PublishIcon,
CloudInsyncIcon,
} from '@blocksuite/icons';
import { ReactElement, ReactNode, useState } from 'react'; import { ReactElement, ReactNode, useState } from 'react';
import { import {
GeneralPage, GeneralPage,
@@ -21,41 +13,38 @@ import {
ExportPage, ExportPage,
SyncPage, SyncPage,
} from '@/components/workspace-setting'; } from '@/components/workspace-setting';
import { SettingsIcon } from '@blocksuite/icons';
import { useAppState } from '@/providers/app-state-provider'; import { useAppState } from '@/providers/app-state-provider';
import WorkspaceLayout from '@/components/workspace-layout'; import WorkspaceLayout from '@/components/workspace-layout';
import { WorkspaceUnit } from '@affine/datacenter'; import { WorkspaceUnit } from '@affine/datacenter';
import { useTranslation } from '@affine/i18n'; import { useTranslation } from '@affine/i18n';
import { PageListHeader } from '@/components/header';
type TabNames = 'general' | 'members' | 'publish' | 'sync' | 'export'; type TabNames = 'General' | 'Sync' | 'Collaboration' | 'Publish' | 'Export';
const tabMap: { const tabMap: {
name: TabNames; name: TabNames;
icon: ReactNode;
panelRender: (workspace: WorkspaceUnit) => ReactNode; panelRender: (workspace: WorkspaceUnit) => ReactNode;
}[] = [ }[] = [
{ {
name: 'general', name: 'General',
icon: <EditIcon />,
panelRender: workspace => <GeneralPage workspace={workspace} />, panelRender: workspace => <GeneralPage workspace={workspace} />,
}, },
{ {
name: 'members', name: 'Sync',
icon: <CloudInsyncIcon />,
panelRender: workspace => <MembersPage workspace={workspace} />,
},
{
name: 'publish',
icon: <UsersIcon />,
panelRender: workspace => <PublishPage workspace={workspace} />,
},
{
name: 'sync',
icon: <PublishIcon />,
panelRender: workspace => <SyncPage workspace={workspace} />, panelRender: workspace => <SyncPage workspace={workspace} />,
}, },
{ {
name: 'export', name: 'Collaboration',
icon: <PublishIcon />, panelRender: workspace => <MembersPage workspace={workspace} />,
},
{
name: 'Publish',
panelRender: workspace => <PublishPage workspace={workspace} />,
},
{
name: 'Export',
panelRender: workspace => <ExportPage workspace={workspace} />, panelRender: workspace => <ExportPage workspace={workspace} />,
}, },
]; ];
@@ -74,48 +63,43 @@ const WorkspaceSetting = () => {
)?.panelRender; )?.panelRender;
let tableArr: { let tableArr: {
name: TabNames; name: TabNames;
icon: ReactNode;
panelRender: (workspace: WorkspaceUnit) => ReactNode; panelRender: (workspace: WorkspaceUnit) => ReactNode;
}[] = tabMap; }[] = tabMap;
if (!isOwner) { if (!isOwner) {
tableArr = [ tableArr = [
{ {
name: 'general', name: 'General',
icon: <EditIcon />,
panelRender: workspace => <GeneralPage workspace={workspace} />, panelRender: workspace => <GeneralPage workspace={workspace} />,
}, },
]; ];
} }
return ( return (
<StyledSettingContainer> <>
<StyledSettingSidebar> <StyledSettingContainer>
<StyledSettingSidebarHeader> <PageListHeader icon={<SettingsIcon />}>{t('Settings')}</PageListHeader>
{t('Workspace Settings')} <StyledSettingSidebar>
</StyledSettingSidebarHeader> <StyledSettingTabContainer>
<StyledSettingTabContainer> {tableArr.map(({ name }) => {
{tableArr.map(({ icon, name }) => { return (
return ( <WorkspaceSettingTagItem
<WorkspaceSettingTagItem key={name}
key={name} isActive={activeTab === name}
isActive={activeTab === name} onClick={() => {
onClick={() => { handleTabChange(name);
handleTabChange(name); }}
}} >
> {name}
<StyledSettingTagIconContainer> </WorkspaceSettingTagItem>
{icon} );
</StyledSettingTagIconContainer> })}
{name} </StyledSettingTabContainer>
</WorkspaceSettingTagItem> </StyledSettingSidebar>
);
})}
</StyledSettingTabContainer>
</StyledSettingSidebar>
<StyledSettingContent> <StyledSettingContent>
{currentWorkspace && activeTabPanelRender?.(currentWorkspace)} {currentWorkspace && activeTabPanelRender?.(currentWorkspace)}
</StyledSettingContent> </StyledSettingContent>
</StyledSettingContainer> </StyledSettingContainer>
</>
); );
}; };
WorkspaceSetting.getLayout = function getLayout(page: ReactElement) { WorkspaceSetting.getLayout = function getLayout(page: ReactElement) {
+1 -1
View File
@@ -182,7 +182,7 @@ export const StyledButton = styled('button', {
paddingLeft: padding, paddingLeft: padding,
paddingRight: padding, paddingRight: padding,
border: '1px solid', border: '1px solid',
...displayInlineFlex('flex-start', 'center'), ...displayInlineFlex('center', 'center'),
position: 'relative', position: 'relative',
// TODO: disabled color is not decided // TODO: disabled color is not decided
...(disabled ...(disabled
+61 -26
View File
@@ -1,7 +1,8 @@
import { useState } from 'react'; import { useState } from 'react';
import { Modal, ModalCloseButton, ModalProps } from '../modal'; import { Modal, ModalCloseButton, ModalProps } from '../modal';
import { import {
StyledButtonWrapper, StyledRowButtonWrapper,
StyledColumnButtonWrapper,
StyledConfirmContent, StyledConfirmContent,
StyledConfirmTitle, StyledConfirmTitle,
StyledModalWrapper, StyledModalWrapper,
@@ -15,6 +16,7 @@ export type ConfirmProps = {
cancelText?: string; cancelText?: string;
// TODO: Confirm button's color should depend on confirm type // TODO: Confirm button's color should depend on confirm type
confirmType?: 'primary' | 'warning' | 'danger'; confirmType?: 'primary' | 'warning' | 'danger';
buttonDirection?: 'row' | 'column';
onConfirm?: () => void; onConfirm?: () => void;
onCancel?: () => void; onCancel?: () => void;
} & Omit<ModalProps, 'open' | 'children'>; } & Omit<ModalProps, 'open' | 'children'>;
@@ -26,6 +28,7 @@ export const Confirm = ({
confirmType, confirmType,
onConfirm, onConfirm,
onCancel, onCancel,
buttonDirection = 'row',
cancelText = 'Cancel', cancelText = 'Cancel',
}: ConfirmProps) => { }: ConfirmProps) => {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
@@ -41,31 +44,63 @@ export const Confirm = ({
/> />
<StyledConfirmTitle>{title}</StyledConfirmTitle> <StyledConfirmTitle>{title}</StyledConfirmTitle>
<StyledConfirmContent>{content}</StyledConfirmContent> <StyledConfirmContent>{content}</StyledConfirmContent>
{buttonDirection === 'row' ? (
<StyledButtonWrapper> <StyledRowButtonWrapper>
<Button <Button
shape="round" shape="round"
bold={true} bold={true}
onClick={() => { onClick={() => {
setOpen(false); setOpen(false);
onCancel?.(); onCancel?.();
}} }}
style={{ marginRight: '24px' }} style={{ marginRight: '24px' }}
> >
{cancelText === 'Cancel' ? t('Cancel') : cancelText} {cancelText === 'Cancel' ? t('Cancel') : cancelText}
</Button> </Button>
<Button <Button
type={confirmType} type={confirmType}
shape="round" shape="round"
bold={true} bold={true}
onClick={() => { onClick={() => {
setOpen(false); setOpen(false);
onConfirm?.(); onConfirm?.();
}} }}
> >
{confirmText} {confirmText}
</Button> </Button>
</StyledButtonWrapper> </StyledRowButtonWrapper>
) : (
<StyledColumnButtonWrapper>
<Button
type={confirmType}
shape="round"
bold={true}
onClick={() => {
setOpen(false);
onConfirm?.();
}}
style={{ width: '284px', height: '38px', textAlign: 'center' }}
>
{confirmText}
</Button>
<Button
shape="round"
bold={true}
onClick={() => {
setOpen(false);
onCancel?.();
}}
style={{
marginTop: '16px',
width: '284px',
height: '38px',
textAlign: 'center',
}}
>
{cancelText === 'Cancel' ? t('Cancel') : cancelText}
</Button>
</StyledColumnButtonWrapper>
)}
</StyledModalWrapper> </StyledModalWrapper>
</Modal> </Modal>
); );
+15 -3
View File
@@ -3,8 +3,10 @@ import { ModalWrapper } from '@/ui/modal';
export const StyledModalWrapper = styled(ModalWrapper)(() => { export const StyledModalWrapper = styled(ModalWrapper)(() => {
return { return {
width: '460px', minWidth: '460px',
padding: '46px 60px 32px', maxWidth: '560px',
maxHeight: '292px',
padding: '44px 84px 32px 84px',
}; };
}); });
@@ -14,6 +16,7 @@ export const StyledConfirmTitle = styled.div(({ theme }) => {
fontWeight: 600, fontWeight: 600,
textAlign: 'center', textAlign: 'center',
color: theme.colors.popoverColor, color: theme.colors.popoverColor,
lineHeight: '28px',
}; };
}); });
@@ -23,12 +26,21 @@ export const StyledConfirmContent = styled.div(({ theme }) => {
textAlign: 'center', textAlign: 'center',
marginTop: '12px', marginTop: '12px',
color: theme.colors.textColor, color: theme.colors.textColor,
lineHeight: '26px',
}; };
}); });
export const StyledButtonWrapper = styled.div(() => { export const StyledColumnButtonWrapper = styled.div(() => {
return { return {
...displayFlex('center', 'center'), ...displayFlex('center', 'center'),
flexDirection: 'column',
marginTop: '32px',
};
});
export const StyledRowButtonWrapper = styled.div(() => {
return {
...displayFlex('center', 'center'),
flexDirection: 'row',
marginTop: '32px', marginTop: '32px',
}; };
}); });
+3
View File
@@ -12,6 +12,7 @@ type inputProps = {
placeholder?: string; placeholder?: string;
disabled?: boolean; disabled?: boolean;
width?: number; width?: number;
height?: number;
maxLength?: number; maxLength?: number;
minLength?: number; minLength?: number;
onChange?: (value: string) => void; onChange?: (value: string) => void;
@@ -26,6 +27,7 @@ export const Input = (props: inputProps) => {
placeholder, placeholder,
maxLength, maxLength,
minLength, minLength,
height,
width = 260, width = 260,
onChange, onChange,
onBlur, onBlur,
@@ -62,6 +64,7 @@ export const Input = (props: inputProps) => {
onChange={handleChange} onChange={handleChange}
onBlur={handleBlur} onBlur={handleBlur}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
height={height}
></StyledInput> ></StyledInput>
); );
}; };
+3 -1
View File
@@ -4,7 +4,8 @@ export const StyledInput = styled('input')<{
disabled?: boolean; disabled?: boolean;
value?: string; value?: string;
width: number; width: number;
}>(({ theme, width, disabled }) => { height?: number;
}>(({ theme, width, disabled, height }) => {
const fontWeight = 400; const fontWeight = 400;
const fontSize = '16px'; const fontSize = '16px';
return { return {
@@ -13,6 +14,7 @@ export const StyledInput = styled('input')<{
padding: '8px 12px', padding: '8px 12px',
fontWeight, fontWeight,
fontSize, fontSize,
height: height ? `${height}px` : 'auto',
color: disabled ? theme.colors.disableColor : theme.colors.inputColor, color: disabled ? theme.colors.disableColor : theme.colors.inputColor,
border: `1px solid`, border: `1px solid`,
borderColor: theme.colors.borderColor, // TODO: check out disableColor, borderColor: theme.colors.borderColor, // TODO: check out disableColor,