Skip to content

Commit 7017af6

Browse files
committed
[refactor] simplify Team Participant & Role table with REST Table component
Signed-off-by: TechQuery <shiy2008@gmail.com>
1 parent c04a757 commit 7017af6

File tree

5 files changed

+112
-221
lines changed

5 files changed

+112
-221
lines changed

components/Team/TeamAdministratorTable.tsx

Lines changed: 0 additions & 86 deletions
This file was deleted.

components/Team/TeamParticipantTable.tsx

Lines changed: 0 additions & 94 deletions
This file was deleted.

components/User/HackathonAdminList.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
import { PlatformAdmin } from '@kaiyuanshe/openhackathon-service';
1+
import { PlatformAdmin, User } from '@kaiyuanshe/openhackathon-service';
22
import { Column, RestForm, SearchableInput } from 'mobx-restful-table';
3+
import { FC } from 'react';
34

45
import { i18n } from '../../models/Base/Translation';
56
import userStore from '../../models/User';
67

8+
export const UserBadge: FC<User> = ({ name, email, mobilePhone }) => (
9+
<div className="d-flex align-items-center gap-1">
10+
{name}
11+
<a href={`mailto:${email}`}>📧</a>
12+
<a href={`tel:${mobilePhone}`}>📱</a>
13+
</div>
14+
);
15+
716
export const adminColumns = <T extends PlatformAdmin>(translator: typeof i18n): Column<T>[] => [
817
{
918
key: 'user',
1019
renderHead: translator.t('user'),
11-
renderBody: ({ user: { name, email, mobilePhone } }) => (
12-
<div className="d-flex align-items-center gap-1">
13-
{name}
14-
<a href={`mailto:${email}`}>📧</a>
15-
<a href={`tel:${mobilePhone}`}>📱</a>
16-
</div>
17-
),
20+
renderBody: ({ user }) => <UserBadge {...user} />,
1821
renderInput: ({ user }, { key, ...meta }) => (
1922
<RestForm.FieldBox name={key} {...meta}>
2023
<SearchableInput

pages/activity/[name]/team/[tid]/manage/participant.tsx

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
1+
import { TeamMember, TeamMemberStatus } from '@kaiyuanshe/openhackathon-service';
2+
import { Loading } from 'idea-react';
3+
import { computed } from 'mobx';
14
import { observer } from 'mobx-react';
25
import { ObservedComponent } from 'mobx-react-helper';
3-
import { ScrollList } from 'mobx-restful-table';
6+
import { Column, FormField, RestTable } from 'mobx-restful-table';
47
import { compose, router } from 'next-ssr-middleware';
58

69
import {
710
TeamManageBaseParams,
811
TeamManageBaseProps,
912
TeamManageFrame,
1013
} from '../../../../../../components/Team/TeamManageFrame';
11-
import { TeamParticipantTableLayout } from '../../../../../../components/Team/TeamParticipantTable';
14+
import { UserBadge } from '../../../../../../components/User/HackathonAdminList';
1215
import activityStore from '../../../../../../models/Activity';
1316
import { i18n, I18nContext } from '../../../../../../models/Base/Translation';
17+
import { convertDatetime } from '../../../../../../utils/time';
1418
import { sessionGuard } from '../../../../../api/core';
1519

20+
const StatusName = ({ t }: typeof i18n): Record<TeamMemberStatus, string> => ({
21+
approved: t('status_approved'),
22+
pendingApproval: t('status_pending'),
23+
});
24+
1625
export const getServerSideProps = compose<TeamManageBaseParams>(router, sessionGuard);
1726

1827
@observer
@@ -26,11 +35,48 @@ export default class TeamParticipantPage extends ObservedComponent<
2635
.teamOf(this.props.route.params!.name)
2736
.memberOf(+this.props.route.params!.tid);
2837

38+
@computed
39+
get columns(): Column<TeamMember>[] {
40+
const i18n = this.observedContext;
41+
const { t } = i18n;
42+
43+
return [
44+
{ key: 'user', renderHead: t('user'), renderBody: ({ user }) => <UserBadge {...user} /> },
45+
{
46+
key: 'createdAt',
47+
renderHead: t('apply_time'),
48+
renderBody: ({ createdAt }) => convertDatetime(createdAt),
49+
},
50+
{
51+
key: 'role',
52+
renderHead: t('apply_role'),
53+
renderBody: ({ role }) => (role === 'admin' ? t('admin') : t('member')),
54+
},
55+
{ key: 'description', renderHead: t('remark') },
56+
{
57+
key: 'status',
58+
renderHead: t('status'),
59+
renderBody: ({ status, user: { id } }) => (
60+
<FormField
61+
label={t('status')}
62+
options={Object.entries(StatusName(i18n)).map(([value, label]) => ({ value, label }))}
63+
defaultValue={status}
64+
onChange={({ currentTarget: { value } }) =>
65+
this.store.updateOne({ status: value as TeamMemberStatus }, id)
66+
}
67+
/>
68+
),
69+
},
70+
];
71+
}
72+
2973
render() {
30-
const { store } = this,
74+
const { props, store, columns } = this,
3175
{ t } = this.observedContext;
32-
const { resolvedUrl, params } = this.props.route;
33-
const { name, tid } = params!;
76+
const { resolvedUrl, params } = props.route,
77+
{ downloading, uploading } = store;
78+
const { name, tid } = params!,
79+
loading = downloading > 0 || uploading > 0;
3480

3581
return (
3682
<TeamManageFrame
@@ -40,16 +86,9 @@ export default class TeamParticipantPage extends ObservedComponent<
4086
path={resolvedUrl}
4187
title={t('team_registration')}
4288
>
43-
<ScrollList
44-
translator={i18n}
45-
store={store}
46-
renderList={allItems => (
47-
<TeamParticipantTableLayout
48-
defaultData={allItems}
49-
onApprove={(userId, status) => store.updateOne({ status }, userId)}
50-
/>
51-
)}
52-
/>
89+
<RestTable translator={i18n} {...{ store, columns }} />
90+
91+
{loading && <Loading />}
5392
</TeamManageFrame>
5493
);
5594
}

0 commit comments

Comments
 (0)