Skip to content

Commit 01946c8

Browse files
committed
[add] Team Rank component
Signed-off-by: TechQuery <[email protected]>
1 parent 0dde9b3 commit 01946c8

File tree

7 files changed

+84
-29
lines changed

7 files changed

+84
-29
lines changed

components/Team/TeamAwardList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Team } from '@kaiyuanshe/openhackathon-service';
21
import { ScrollList, ScrollListProps } from 'mobx-restful-table';
32
import { FC, PureComponent } from 'react';
43
import { Col, Row } from 'react-bootstrap';
54

5+
import { Team } from '../../models/Activity/Team';
66
import { i18n } from '../../models/Base/Translation';
77
import { XScrollListProps } from '../layout/ScrollList';
88
import { TeamAwardCard } from './TeamAwardCard';

components/Team/TeamList.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
import { Team } from '@kaiyuanshe/openhackathon-service';
21
import { ScrollListProps } from 'mobx-restful-table';
32
import { Col, Row } from 'react-bootstrap';
43

5-
import { TeamModel } from '../../models/Activity/Team';
4+
import { Team, TeamModel } from '../../models/Activity/Team';
65
import { TeamCard } from './TeamCard';
76

87
export interface TeamListProps extends ScrollListProps<Team> {
98
store: TeamModel;
109
}
1110

12-
export const TeamListLayout = ({
13-
defaultData = [],
14-
}: Pick<TeamListProps, 'defaultData'>) => (
11+
export const TeamListLayout = ({ defaultData = [] }: Pick<TeamListProps, 'defaultData'>) => (
1512
<Row className="g-4" xs={1} md={2} lg={2} xxl={2}>
1613
{defaultData.map(item => (
1714
<Col key={item.id}>

components/Team/TeamRank.tsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { UserRankView } from 'idea-react';
2+
import { observer } from 'mobx-react';
3+
import { ObservedComponent } from 'mobx-react-helper';
4+
5+
import { TeamModel } from '../../models/Activity/Team';
6+
import { i18n, I18nContext } from '../../models/Base/Translation';
7+
8+
export interface TeamRankProps {
9+
activityName: string;
10+
teamStore: TeamModel;
11+
}
12+
13+
@observer
14+
export class TeamRank extends ObservedComponent<TeamRankProps, typeof i18n> {
15+
static contextType = I18nContext;
16+
17+
componentDidMount() {
18+
this.props.teamStore.getAll();
19+
}
20+
21+
render() {
22+
const { t } = this.observedContext,
23+
{ activityName, teamStore } = this.props;
24+
const { allItems } = teamStore;
25+
26+
return (
27+
<UserRankView
28+
style={{
29+
// @ts-expect-error remove in React 19
30+
'--logo-image':
31+
'url(https://hackathon-api.static.kaiyuanshe.cn/6342619375fa1817e0f56ce1/2022/10/09/logo22.jpg)',
32+
}}
33+
title={t('hacker_pavilion')}
34+
rank={allItems.map(
35+
({ id, displayName: name, createdBy: { avatar, email }, score = 0 }) => ({
36+
id,
37+
name,
38+
avatar,
39+
email,
40+
score,
41+
}),
42+
)}
43+
linkOf={({ id }) => `/hackathon/${activityName}/team/${id}`}
44+
/>
45+
);
46+
}
47+
}

models/Activity/Team.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import {
22
BaseFilter,
3-
Team,
3+
Team as _Team,
44
TeamMember,
55
TeamMemberFilter,
66
TeamWork,
77
TeamWorkFilter,
8+
Score,
89
} from '@kaiyuanshe/openhackathon-service';
910
import { action, computed, observable } from 'mobx';
1011
import { ListModel, persist, restore, Stream, toggle } from 'mobx-restful';
@@ -17,6 +18,12 @@ import sessionStore from '../User/Session';
1718
import { AwardAssignment } from './Award';
1819
import { EvaluationModel } from './Evaluation';
1920

21+
export interface Team extends _Team {
22+
scores?: Score[];
23+
score?: number;
24+
rank?: number;
25+
}
26+
2027
export type TeamFilter = Filter<Team> & BaseFilter;
2128

2229
export type MemberFilter = Filter<TeamMember> & TeamMemberFilter;

models/Activity/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ export class ActivityModel extends TableModel<Hackathon, ActivityFilter> {
8888
return (this.currentOrganization = new OrganizerModel(`hackathon/${name}`));
8989
}
9090

91+
static isEvaluatable({ judgeStartedAt, judgeEndedAt }: Hackathon) {
92+
const now = Date.now();
93+
94+
return +new Date(judgeStartedAt) <= now && now <= +new Date(judgeEndedAt);
95+
}
96+
9197
@toggle('uploading')
9298
async updateOne(data: InputData<Hackathon>, name?: string) {
9399
if (!name) {

pages/activity/[name]/index.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ import { cache, compose, errorLogger } from 'next-ssr-middleware';
1818
import { Button, Carousel, Col, Container, Image, Row, Tab, Tabs } from 'react-bootstrap';
1919

2020
import { getActivityStatusText } from '../../../components/Activity/ActivityEntry';
21+
import { AwardList } from '../../../components/Activity/AwardList';
2122
import { CommentBox } from '../../../components/CommentBox';
2223
import { PageHead } from '../../../components/layout/PageHead';
2324
import { AnnouncementList } from '../../../components/Message/MessageList';
2425
import { OrganizationCard } from '../../../components/Organization/OrganizationCard';
2526
import { TeamCard } from '../../../components/Team/TeamCard';
2627
import { TeamCreateModal } from '../../../components/Team/TeamCreateModal';
2728
import { TeamListLayout } from '../../../components/Team/TeamList';
29+
import { TeamRank } from '../../../components/Team/TeamRank';
2830
import { isServer } from '../../../configuration';
2931
import activityStore, { ActivityModel } from '../../../models/Activity';
3032
import { i18n, I18nContext } from '../../../models/Base/Translation';
@@ -64,6 +66,7 @@ const StatusName = ({ t }: typeof i18n): Record<EnrollmentStatus, string> => ({
6466
export default class ActivityPage extends ObservedComponent<ActivityPageProps, typeof i18n> {
6567
static contextType = I18nContext;
6668

69+
awardStore = activityStore.awardOf(this.props.activity.name);
6770
logStore = activityStore.logOf(this.props.activity.id);
6871
enrollmentStore = activityStore.enrollmentOf(this.props.activity.name);
6972
teamStore = activityStore.teamOf(this.props.activity.name);
@@ -231,9 +234,9 @@ export default class ActivityPage extends ObservedComponent<ActivityPageProps, t
231234

232235
render() {
233236
const { t } = this.observedContext,
234-
{ name, displayName, tags, banners, location, detail } = this.props.activity,
237+
{ activity, organizationList } = this.props;
238+
const { name, displayName, tags, banners, location, detail } = activity,
235239
{ showCreateTeam, loading } = this,
236-
{ organizationList } = this.props,
237240
myTeam = activityStore.currentTeam?.sessionOne,
238241
myMessage = this.messageStore;
239242

@@ -302,6 +305,14 @@ export default class ActivityPage extends ObservedComponent<ActivityPageProps, t
302305
/>
303306
</Tab>
304307
</Tabs>
308+
<Tab eventKey="award" title={t('award')} className="pt-2">
309+
<AwardList store={this.awardStore} />
310+
</Tab>
311+
{ActivityModel.isEvaluatable(activity) && (
312+
<Tab eventKey="team-rank" title={t('works_awards')} className="pt-2">
313+
<TeamRank activityName={name} teamStore={this.teamStore} />
314+
</Tab>
315+
)}
305316
</Col>
306317
<Col className="d-flex flex-column">
307318
{organizationList.length > 0 && (

pages/activity/[name]/team/[tid]/index.tsx

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,6 @@ export default class TeamPage extends ObservedComponent<TeamPageProps, typeof i1
9292
return activityStore.currentTeam?.sessionOne?.id === this.observedProps.team.id;
9393
}
9494

95-
@computed
96-
get evaluatable() {
97-
const now = Date.now(),
98-
{ judgeStartedAt, judgeEndedAt } = this.observedProps.activity;
99-
100-
return +new Date(judgeStartedAt) <= now && now <= +new Date(judgeEndedAt);
101-
}
102-
10395
async componentDidMount() {
10496
if (isServer()) return;
10597

@@ -154,14 +146,9 @@ export default class TeamPage extends ObservedComponent<TeamPageProps, typeof i1
154146

155147
render() {
156148
const { t } = this.observedContext,
157-
{ name, displayName: hackathonDisplayName } = this.props.activity,
158-
{
159-
id,
160-
displayName,
161-
description,
162-
createdBy: { avatar },
163-
} = this.props.team,
164-
{ teamMemberList, teamWorkList } = this.props,
149+
{ activity, team, teamMemberList, teamWorkList } = this.props;
150+
const { name, displayName: hackathonDisplayName } = activity,
151+
{ id, displayName, description, createdBy } = team,
165152
{
166153
currentRoute,
167154
currentUserInThisTeam,
@@ -170,7 +157,6 @@ export default class TeamPage extends ObservedComponent<TeamPageProps, typeof i1
170157
handleJoinTeam,
171158
isShowJoinTeamBtn,
172159
isShowLeaveTeamBtn,
173-
evaluatable,
174160
} = this;
175161

176162
return (
@@ -185,7 +171,7 @@ export default class TeamPage extends ObservedComponent<TeamPageProps, typeof i1
185171
<Card.Header className="bg-white">
186172
<Card.Img
187173
variant="top"
188-
src={avatar}
174+
src={createdBy.avatar}
189175
className="d-block m-auto"
190176
style={{ maxWidth: '15rem' }}
191177
/>
@@ -241,8 +227,9 @@ export default class TeamPage extends ObservedComponent<TeamPageProps, typeof i1
241227
</Tabs>
242228
</Col>
243229
</Row>
244-
{evaluatable && <EvaluationForm activityName={name} teamId={id} />}
245-
230+
{ActivityModel.isEvaluatable(activity) && (
231+
<EvaluationForm activityName={name} teamId={id} />
232+
)}
246233
<CommentBox />
247234

248235
<JoinTeamModal

0 commit comments

Comments
 (0)