feat: modify invite page & 404 page (#1097)

This commit is contained in:
Qi
2023-02-17 17:44:48 +08:00
committed by GitHub
parent 5e6366ba44
commit 67fe1871da
26 changed files with 926 additions and 501 deletions
+17 -15
View File
@@ -1,26 +1,28 @@
import { Button } from '@affine/component';
import { useTranslation } from '@affine/i18n';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { NotFoundTitle, PageContainer } from './styles';
import ErrorImg from '../../../public/imgs/invite-error.svg';
import { StyledContainer } from './styles';
export const NotfoundPage = () => {
const { t } = useTranslation();
const router = useRouter();
return (
<PageContainer>
<NotFoundTitle data-testid="notFound">
{t('404 - Page Not Found')}
<p>
<Button
onClick={() => {
router.push('/workspace');
}}
>
{t('Back Home')}
</Button>
</p>
</NotFoundTitle>
</PageContainer>
<StyledContainer data-testid="notFound">
<Image alt="404" src={ErrorImg}></Image>
<p>{t('404 - Page Not Found')}</p>
<Button
shape="round"
onClick={() => {
router.push('/workspace');
}}
>
{t('Back Home')}
</Button>
</StyledContainer>
);
};
+15 -17
View File
@@ -1,21 +1,19 @@
import { styled } from '@affine/component';
import { displayFlex, styled } from '@affine/component';
export const PageContainer = styled('div')(({ theme }) => {
export const StyledContainer = styled.div(() => {
return {
width: '100%',
height: 'calc(100vh)',
backgroundColor: theme.colors.pageBackground,
};
});
export const NotFoundTitle = styled('h1')(({ theme }) => {
return {
position: 'relative',
top: 'calc(50% - 100px)',
height: '100px',
fontSize: '60px',
lineHeight: '100px',
color: theme.colors.textColor,
textAlign: 'center',
...displayFlex('center', 'center'),
flexDirection: 'column',
height: '100vh',
img: {
width: '360px',
height: '270px',
},
p: {
fontSize: '22px',
fontWeight: 600,
margin: '24px 0',
},
};
});
+15 -9
View File
@@ -4,16 +4,22 @@ import React from 'react';
export const PageListEmpty = (props: { listType?: string }) => {
const { listType } = props;
const { t } = useTranslation();
const getEmptyDescription = () => {
if (listType === 'all') {
return t('emptyAllPages');
}
if (listType === 'favorite') {
return t('emptyFavorite');
}
if (listType === 'trash') {
return t('emptyTrash');
}
};
return (
<div style={{ textAlign: 'center' }}>
<Empty
width={800}
height={300}
sx={{ marginTop: '100px', marginBottom: '30px' }}
/>
{listType === 'all' && <p>{t('emptyAllPages')}</p>}
{listType === 'favorite' && <p>{t('emptyFavorite')}</p>}
{listType === 'trash' && <p>{t('emptyTrash')}</p>}
<div style={{ height: 'calc(100% - 60px)' }}>
<Empty description={getEmptyDescription()} />
</div>
);
};
File diff suppressed because one or more lines are too long
@@ -49,7 +49,7 @@ export const StyledNotFound = styled('div')(({ theme }) => {
'>svg': {
marginTop: '10px',
fontSize: '150px',
height: '200px',
},
};
});
@@ -7,7 +7,7 @@ export const ExportPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
console.log(workspace);
return (
<>
<Wrapper marginBottom="32px"> {t('Export Description')}</Wrapper>
<Wrapper marginBottom="42px"> {t('Export Description')}</Wrapper>
<Button type="light" shape="circle" disabled>
{t('Export AFFiNE backup file')}
</Button>
@@ -32,7 +32,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
if (workspace.published) {
return (
<>
<Wrapper marginBottom="32px">{t('Published Description')}</Wrapper>
<Wrapper marginBottom="42px">{t('Published Description')}</Wrapper>
<Wrapper marginBottom="12px">
<Content weight="500">{t('Share with link')}</Content>
@@ -66,7 +66,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
return (
<>
<Wrapper marginBottom="32px">{t('Publishing Description')}</Wrapper>
<Wrapper marginBottom="42px">{t('Publishing Description')}</Wrapper>
<Button
onClick={async () => {
setLoaded(true);
@@ -84,7 +84,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
return (
<>
<Wrapper marginBottom="32px">{t('Publishing')}</Wrapper>
<Wrapper marginBottom="42px">{t('Publishing')}</Wrapper>
<Button
type="light"
shape="circle"
@@ -53,7 +53,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
<Content weight={500}>{t('is a Local Workspace')}</Content>
</FlexWrapper>
<p>{t('Local Workspace Description')}</p>
<Wrapper marginTop="32px">
<Wrapper marginTop="42px">
<Button
type="light"
shape="circle"
@@ -42,7 +42,7 @@ export const StyledInputContent = styled('div')(({ theme }) => {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
margin: '32px 0',
margin: '42px 0',
fontSize: theme.font.base,
};
});
@@ -52,7 +52,7 @@ export const StyledButtonContent = styled('div')(() => {
position: 'absolute',
left: '50%',
transform: 'translateX(-50%)',
bottom: '32px',
bottom: '42px',
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
@@ -1,7 +1,6 @@
import { Wrapper } from '@affine/component';
import { Button, IconButton } from '@affine/component';
import { Menu, MenuItem } from '@affine/component';
import { Empty } from '@affine/component';
import { toast } from '@affine/component';
import { FlexWrapper } from '@affine/component';
import { WorkspaceUnit } from '@affine/datacenter';
@@ -37,121 +36,126 @@ export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
if (workspace.provider === 'affine') {
return (
<StyledMemberContainer>
<StyledMemberListContainer>
{!loaded && (
<FlexWrapper justifyContent="center">
<Loading size={25} />
</FlexWrapper>
)}
{loaded && members.length === 0 && (
<Empty width={648} sx={{ marginTop: '60px' }} height={300} />
)}
{loaded && members.length > 0 && (
<>
<StyledMemberTitleContainer>
<StyledMemberNameContainer>
{t('Users')} ({members.length})
</StyledMemberNameContainer>
<StyledMemberRoleContainer>
{t('Access level')}
</StyledMemberRoleContainer>
<div style={{ width: '24px', paddingRight: '48px' }}></div>
</StyledMemberTitleContainer>
{members.map((member, index) => {
const user = Object.assign(
{
avatar_url: '',
email: '',
id: '',
name: '',
},
member.user
);
return (
<StyledMemberListItem key={index}>
<StyledMemberNameContainer>
<StyledMemberAvatar
alt="member avatar"
src={user.avatar_url}
>
<EmailIcon />
</StyledMemberAvatar>
<>
<StyledMemberContainer>
<ul>
<StyledMemberTitleContainer>
<StyledMemberNameContainer>
{t('Users')} ({members.length})
</StyledMemberNameContainer>
<StyledMemberRoleContainer>
{t('Access level')}
</StyledMemberRoleContainer>
<div style={{ width: '24px', paddingRight: '48px' }}></div>
</StyledMemberTitleContainer>
</ul>
<StyledMemberInfo>
<StyledMemberName>{user.name}</StyledMemberName>
<StyledMemberEmail>
{member.user.email}
</StyledMemberEmail>
</StyledMemberInfo>
</StyledMemberNameContainer>
<StyledMemberRoleContainer>
{member.accepted
? member.type !== 99
? t('Member')
: t('Owner')
: t('Pending')}
</StyledMemberRoleContainer>
<StyledMoreVerticalButton>
{member.type === 99 ? (
<></>
) : (
<Menu
content={
<>
<MenuItem
onClick={async () => {
await removeMember(member.id);
toast(
t('Member has been removed', {
name: user.name,
})
);
}}
icon={<TrashIcon />}
>
{t('Remove from workspace')}
</MenuItem>
</>
}
placement="bottom-end"
disablePortal={true}
<StyledMemberListContainer>
{!loaded && (
<FlexWrapper justifyContent="center">
<Loading size={25} />
</FlexWrapper>
)}
{loaded && members.length > 0 && (
<>
{members.map((member, index) => {
const user = Object.assign(
{
avatar_url: '',
email: '',
id: '',
name: '',
},
member.user
);
return (
<StyledMemberListItem key={index}>
<StyledMemberNameContainer>
<StyledMemberAvatar
alt="member avatar"
src={user.avatar_url}
>
<IconButton>
<MoreVerticalIcon />
</IconButton>
</Menu>
)}
</StyledMoreVerticalButton>
</StyledMemberListItem>
);
})}
</>
)}
</StyledMemberListContainer>
<StyledMemberButtonContainer>
<Button
onClick={() => {
setIsInviteModalShow(true);
}}
type="primary"
shape="circle"
>
{t('Invite Members')}
</Button>
<InviteMemberModal
onClose={() => {
setIsInviteModalShow(false);
}}
onInviteSuccess={() => {
setIsInviteModalShow(false);
// refreshMembers();
}}
workspaceId={workspace.id}
open={isInviteModalShow}
></InviteMemberModal>
</StyledMemberButtonContainer>
</StyledMemberContainer>
<EmailIcon />
</StyledMemberAvatar>
<StyledMemberInfo>
<StyledMemberName>{user.name}</StyledMemberName>
<StyledMemberEmail>
{member.user.email}
</StyledMemberEmail>
</StyledMemberInfo>
</StyledMemberNameContainer>
<StyledMemberRoleContainer>
{member.accepted
? member.type !== 99
? t('Member')
: t('Owner')
: t('Pending')}
</StyledMemberRoleContainer>
<StyledMoreVerticalButton>
{member.type === 99 ? (
<></>
) : (
<Menu
content={
<>
<MenuItem
onClick={async () => {
// FIXME: remove ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
await removeMember(member.id);
toast(
t('Member has been removed', {
name: user.name,
})
);
}}
icon={<TrashIcon />}
>
{t('Remove from workspace')}
</MenuItem>
</>
}
placement="bottom-end"
disablePortal={true}
>
<IconButton>
<MoreVerticalIcon />
</IconButton>
</Menu>
)}
</StyledMoreVerticalButton>
</StyledMemberListItem>
);
})}
</>
)}
</StyledMemberListContainer>
<StyledMemberButtonContainer>
<Button
onClick={() => {
setIsInviteModalShow(true);
}}
type="primary"
shape="circle"
>
{t('Invite Members')}
</Button>
</StyledMemberButtonContainer>
</StyledMemberContainer>
<InviteMemberModal
onClose={() => {
setIsInviteModalShow(false);
}}
onInviteSuccess={() => {
setIsInviteModalShow(false);
// refreshMembers();
}}
workspaceId={workspace.id}
open={isInviteModalShow}
></InviteMemberModal>
</>
);
}
@@ -5,7 +5,7 @@ export const StyledMemberTitleContainer = styled('li')(() => {
return {
display: 'flex',
fontWeight: '500',
marginBottom: '32px',
marginBottom: '42px',
flex: 1,
};
});
@@ -14,6 +14,7 @@ export const StyledMemberContainer = styled('div')(() => {
display: 'flex',
height: '100%',
flexDirection: 'column',
overflow: 'hidden',
};
});
@@ -40,8 +41,8 @@ export const StyledMemberRoleContainer = styled('div')(() => {
export const StyledMemberListContainer = styled('ul')(() => {
return {
overflowY: 'scroll',
width: '100%',
flex: 1,
flexGrow: 1,
paddingBottom: '58px',
};
});
@@ -80,9 +81,8 @@ export const StyledMemberEmail = styled('div')(({ theme }) => {
export const StyledMemberButtonContainer = styled('div')(() => {
return {
position: 'absolute',
bottom: '0',
marginBottom: '20px',
position: 'fixed',
bottom: '20px',
};
});
@@ -4,9 +4,8 @@ export const StyledSettingContainer = styled('div')(() => {
return {
display: 'flex',
flexDirection: 'column',
padding: '0 0 20px 48px',
height: '100vh',
marginTop: '48px',
padding: '48px 0 20px 48px',
height: 'calc(100vh - 60px)',
};
});
@@ -55,7 +54,7 @@ export const StyledSettingKey = styled.div(({ theme }) => {
});
export const StyledRow = styled(FlexWrapper)(() => {
return {
marginBottom: '32px',
marginBottom: '42px',
};
});
@@ -56,10 +56,9 @@ export const StyledListItem = styled.div<{
disabled?: boolean;
}>(({ theme, active, disabled }) => {
return {
width: '296px',
height: '32px',
marginTop: '12px',
color: active ? theme.colors.primaryColor : theme.colors.popoverColor,
color: active ? theme.colors.primaryColor : theme.colors.textColor,
paddingLeft: '12px',
borderRadius: '5px',
cursor: 'pointer',