refactor: move WorkspaceCard (#1803)

This commit is contained in:
Himself65
2023-04-03 18:13:43 -05:00
committed by GitHub
parent dbcadbaf60
commit 9a20f50b05
16 changed files with 143 additions and 25 deletions
@@ -0,0 +1,133 @@
import { useTranslation } from '@affine/i18n';
import { PermissionType } from '@affine/workspace/affine/api';
import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { SettingsIcon } from '@blocksuite/icons';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-blocksuite-workspace-name';
import type React from 'react';
import { useCallback } from 'react';
import { WorkspaceAvatar } from '../workspace-avatar';
import {
StyledCard,
StyledSettingLink,
StyleWorkspaceInfo,
StyleWorkspaceTitle,
} from './styles';
export type WorkspaceTypeProps = {
workspace: AffineWorkspace | LocalWorkspace;
};
import {
CloudWorkspaceIcon as DefaultCloudWorkspaceIcon,
JoinedWorkspaceIcon as DefaultJoinedWorkspaceIcon,
LocalDataIcon as DefaultLocalDataIcon,
LocalWorkspaceIcon as DefaultLocalWorkspaceIcon,
PublishIcon as DefaultPublishIcon,
} from '@blocksuite/icons';
const JoinedWorkspaceIcon = () => {
return <DefaultJoinedWorkspaceIcon style={{ color: '#FF646B' }} />;
};
const LocalWorkspaceIcon = () => {
return <DefaultLocalWorkspaceIcon style={{ color: '#FDBD32' }} />;
};
const CloudWorkspaceIcon = () => {
return <DefaultCloudWorkspaceIcon style={{ color: '#60A5FA' }} />;
};
const LocalDataIcon = () => {
return <DefaultLocalDataIcon style={{ color: '#62CD80' }} />;
};
const PublishIcon = () => {
return <DefaultPublishIcon style={{ color: '#8699FF' }} />;
};
const WorkspaceType: React.FC<WorkspaceTypeProps> = ({ workspace }) => {
const { t } = useTranslation();
let isOwner = true;
if (workspace.flavour === WorkspaceFlavour.AFFINE) {
isOwner = workspace.permission === PermissionType.Owner;
} else if (workspace.flavour === WorkspaceFlavour.LOCAL) {
isOwner = true;
}
if (workspace.flavour === WorkspaceFlavour.LOCAL) {
return (
<p title={t('Local Workspace')}>
<LocalWorkspaceIcon />
<span>{t('Local Workspace')}</span>
</p>
);
}
return isOwner ? (
<p title={t('Cloud Workspace')}>
<CloudWorkspaceIcon />
<span>{t('Cloud Workspace')}</span>
</p>
) : (
<p title={t('Joined Workspace')}>
<JoinedWorkspaceIcon />
<span>{t('Joined Workspace')}</span>
</p>
);
};
export type WorkspaceCardProps = {
currentWorkspaceId: string | null;
workspace: AffineWorkspace | LocalWorkspace;
onClick: (workspace: AffineWorkspace | LocalWorkspace) => void;
onSettingClick: (workspace: AffineWorkspace | LocalWorkspace) => void;
};
export const WorkspaceCard: React.FC<WorkspaceCardProps> = ({
workspace,
onClick,
onSettingClick,
currentWorkspaceId,
}) => {
const { t } = useTranslation();
const [name] = useBlockSuiteWorkspaceName(workspace.blockSuiteWorkspace);
return (
<StyledCard
data-testid="workspace-card"
onClick={useCallback(() => {
onClick(workspace);
}, [onClick, workspace])}
active={workspace.id === currentWorkspaceId}
>
<WorkspaceAvatar size={58} workspace={workspace} />
<StyleWorkspaceInfo>
<StyleWorkspaceTitle>{name}</StyleWorkspaceTitle>
<WorkspaceType workspace={workspace} />
{workspace.flavour === WorkspaceFlavour.LOCAL && (
<p title={t('Available Offline')}>
<LocalDataIcon />
<span>{t('Available Offline')}</span>
</p>
)}
{workspace.flavour === WorkspaceFlavour.AFFINE && workspace.public && (
<p title={t('Published to Web')}>
<PublishIcon />
<span>{t('Published to Web')}</span>
</p>
)}
</StyleWorkspaceInfo>
<StyledSettingLink
className="setting-entry"
hoverBackground="#fff"
onClick={e => {
e.stopPropagation();
onSettingClick(workspace);
}}
>
<SettingsIcon />
</StyledSettingLink>
</StyledCard>
);
};
@@ -0,0 +1,92 @@
import { displayFlex, styled, textEllipsis } from '../..';
import { IconButton } from '../..';
export const StyleWorkspaceInfo = styled('div')(({ theme }) => {
return {
marginLeft: '15px',
width: '202px',
p: {
height: '20px',
fontSize: theme.font.sm,
...displayFlex('flex-start', 'center'),
},
svg: {
marginRight: '10px',
fontSize: '16px',
flexShrink: 0,
},
span: {
flexGrow: 1,
...textEllipsis(1),
},
};
});
export const StyleWorkspaceTitle = styled('div')(({ theme }) => {
return {
fontSize: theme.font.base,
fontWeight: 600,
lineHeight: '24px',
marginBottom: '10px',
maxWidth: '200px',
...textEllipsis(1),
};
});
export const StyledCard = styled('div')<{
active?: boolean;
}>(({ theme, active }) => {
const borderColor = active ? theme.colors.primaryColor : 'transparent';
return {
width: '310px',
height: '124px',
cursor: 'pointer',
padding: '16px',
boxShadow: '0px 0px 8px rgba(0, 0, 0, 0.1)',
borderRadius: '12px',
border: `1px solid ${borderColor}`,
...displayFlex('flex-start', 'flex-start'),
marginBottom: '24px',
transition: 'background .2s',
background: theme.palette.mode === 'light' ? '#FFF' : '#2C2C2C',
position: 'relative',
':hover': {
background: theme.colors.cardHoverBackground,
'.add-icon': {
borderColor: theme.colors.primaryColor,
color: theme.colors.primaryColor,
},
'.setting-entry': {
opacity: 1,
pointerEvents: 'auto',
},
},
};
});
export const StyledModalHeader = styled('div')(() => {
return {
width: '100%',
height: '72px',
position: 'absolute',
left: 0,
top: 0,
borderRadius: '24px 24px 0 0',
padding: '0 40px',
...displayFlex('space-between', 'center'),
};
});
export const StyledSettingLink = styled(IconButton)(({ theme }) => {
return {
position: 'absolute',
right: '6px',
bottom: '6px',
opacity: 0,
pointerEvents: 'none',
transition: 'all .15s',
':hover': {
background: theme.colors.pageBackground,
},
};
});