mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-17 10:06:17 +08:00
feat: modify invite page & 404 page (#1097)
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user