Skip to content

Commit e00e2eb

Browse files
committed
refactor: simplify hackathon team countdown
1 parent 1c7d4d8 commit e00e2eb

1 file changed

Lines changed: 27 additions & 55 deletions

File tree

pages/hackathon/[id]/team/[tid].tsx

Lines changed: 27 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Avatar } from 'idea-react';
2-
import { BiTableSchema, TableCellLocation, TableCellUser, TableFormView } from 'mobx-lark';
2+
import { TableCellLocation, TableFormView } from 'mobx-lark';
33
import { observer } from 'mobx-react';
44
import { cache, compose, errorLogger } from 'next-ssr-middleware';
55
import { FC, useContext, useMemo, useState } from 'react';
@@ -21,9 +21,14 @@ import {
2121
agendaTypeLabelOf,
2222
compactDateKeyOf,
2323
compactSummaryOf,
24+
firstTextOf,
2425
formatMoment,
2526
formatPeriod,
2627
isPublicForm,
28+
relationNameOf,
29+
resolveCountdownState,
30+
textListOf,
31+
userOf,
2732
} from '../../../../components/Activity/Hackathon/utility';
2833
import { ProductCard } from '../../../../components/Activity/ProductCard';
2934
import { PageHead } from '../../../../components/Layout/PageHead';
@@ -75,33 +80,10 @@ interface ProjectPageProps {
7580
renderedAt: number;
7681
}
7782

78-
const firstText = (value: unknown) =>
79-
(Array.isArray(value) ? value.find(Boolean) : value)?.toString().trim() || '';
80-
81-
const textListOf = (value: unknown) =>
82-
Array.isArray(value)
83-
? value
84-
.map(item => item?.toString().trim())
85-
.filter(text => text && text !== '[object Object]')
86-
: firstText(value)
87-
? [firstText(value)]
88-
: [];
89-
90-
const relationNameOf = (value: unknown) =>
91-
Array.isArray(value)
92-
? value
93-
.map(item =>
94-
typeof item === 'object' && item && 'name' in item
95-
? String((item as { name?: string }).name || '')
96-
: item?.toString() || '',
97-
)
98-
.find(Boolean) || ''
99-
: firstText(value);
100-
10183
const ProjectPage: FC<ProjectPageProps> = observer(
10284
({ activity, agenda, project, members, products, renderedAt }) => {
103-
const { t } = useContext(I18nContext);
104-
const [showScoreModal, setShowScoreModal] = useState(false);
85+
const { t } = useContext(I18nContext);
86+
const [showScoreModal, setShowScoreModal] = useState(false);
10587

10688
const {
10789
name: activityName,
@@ -113,7 +95,7 @@ const ProjectPage: FC<ProjectPageProps> = observer(
11395
summary: activitySummary,
11496
type: activityType,
11597
} = activity;
116-
const { forms, formLinkMap } = databaseSchema as unknown as BiTableSchema;
98+
const { forms, formLinkMap } = databaseSchema;
11799
const {
118100
name: displayName,
119101
summary: description,
@@ -123,16 +105,16 @@ const ProjectPage: FC<ProjectPageProps> = observer(
123105
prize,
124106
group,
125107
} = project;
126-
const creator = createdBy as TableCellUser;
127-
const displayTitle = firstText(displayName) || t('projects');
108+
const creator = userOf(createdBy);
109+
const displayTitle = firstTextOf(displayName) || t('projects');
128110
const projectSummary =
129-
compactSummaryOf(description as string, firstText(activitySummary) || displayTitle, 140);
111+
compactSummaryOf(description, firstTextOf(activitySummary) || displayTitle, 140);
130112
const locationText = (location as TableCellLocation | undefined)?.full_address || '-';
131113
const eventRange = formatPeriod(startTime, endTime) || locationText;
132114
const groupName = relationNameOf(group);
133-
const scoreText = firstText(score);
134-
const rankText = firstText(rank);
135-
const prizeText = firstText(prize);
115+
const scoreText = firstTextOf(score);
116+
const rankText = firstTextOf(rank);
117+
const prizeText = firstTextOf(prize);
136118
const agendaItems = [...agenda].sort(
137119
({ startedAt: left }, { startedAt: right }) =>
138120
new Date((left as string) || 0).getTime() - new Date((right as string) || 0).getTime(),
@@ -155,13 +137,13 @@ const ProjectPage: FC<ProjectPageProps> = observer(
155137
() =>
156138
Object.values(forms || {})
157139
.flat()
158-
.filter(Boolean)
159-
.filter(isPublicForm as (value: TableFormView) => boolean),
140+
.filter((form): form is TableFormView => Boolean(form))
141+
.filter(isPublicForm),
160142
[forms],
161143
);
162144
const primaryForm =
163-
((forms?.Person || []).filter(isPublicForm as (value: TableFormView) => boolean)[0] ||
164-
(forms?.Project || []).filter(isPublicForm as (value: TableFormView) => boolean)[0] ||
145+
((forms?.Person || []).filter(isPublicForm)[0] ||
146+
(forms?.Project || []).filter(isPublicForm)[0] ||
165147
publicForms[0]);
166148
const scoreForm = Object.values(formLinkMap?.Evaluation || {})[0];
167149
const currentRoute = [
@@ -174,22 +156,12 @@ const ProjectPage: FC<ProjectPageProps> = observer(
174156
{ href: '#works', label: t('team_works') },
175157
{ href: '#creator', label: t('created_by') },
176158
];
177-
const now = renderedAt;
178-
const nextAgendaItem = agendaItems.find(({ startedAt, endedAt }) => {
179-
const started = new Date((startedAt as string) || 0).getTime();
180-
const ended = new Date((endedAt as string) || 0).getTime();
181-
182-
return Number.isFinite(started) && Number.isFinite(ended) && now <= ended;
183-
});
184-
const nextAgendaStarted = nextAgendaItem?.startedAt as string | undefined;
185-
const nextAgendaEnded = nextAgendaItem?.endedAt as string | undefined;
186-
const countdownTo =
187-
(nextAgendaStarted && new Date(nextAgendaStarted).getTime() > now
188-
? nextAgendaStarted
189-
: nextAgendaEnded) ||
190-
((startTime as string | undefined) && new Date(startTime as string).getTime() > now
191-
? (startTime as string)
192-
: (endTime as string | undefined));
159+
const { nextItem: nextAgendaItem, countdownTo } = resolveCountdownState(
160+
agendaItems,
161+
renderedAt,
162+
startTime,
163+
endTime,
164+
);
193165
const countdownLabel = nextAgendaItem
194166
? agendaTypeLabelOf(nextAgendaItem.type, t, t('agenda'))
195167
: t('event_duration');
@@ -320,8 +292,8 @@ const ProjectPage: FC<ProjectPageProps> = observer(
320292

321293
<Row as="ul" className="list-unstyled g-4" xs={1} md={2} xl={3}>
322294
{members.map(({ id, person, githubAccount, summary, skills }) => {
323-
const member = person as TableCellUser;
324-
const githubName = firstText(githubAccount);
295+
const member = userOf(person);
296+
const githubName = firstTextOf(githubAccount);
325297
const memberSummary = textListOf(summary).join(' · ');
326298
const memberSkills = textListOf(skills).slice(0, 6);
327299

0 commit comments

Comments
 (0)