Skip to content

Commit ee0cf17

Browse files
TechQueryCopilot
andauthored
[refactor] use Time & Time Range components to render all Date Time texts (#74)
Co-authored-by: Copilot <copilot@github.com>
1 parent b160b03 commit ee0cf17

16 files changed

Lines changed: 445 additions & 386 deletions

File tree

components/Activity/Hackathon/ActionHub.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { FC, PropsWithChildren } from 'react';
1+
import type { FC, PropsWithChildren, ReactNode } from 'react';
22
import { Col, Container, Row } from 'react-bootstrap';
33

44
import { HackathonHeroAction } from './Hero';
@@ -14,7 +14,7 @@ export interface HackathonActionHubEntry {
1414

1515
export interface HackathonActionHubProps {
1616
entries: HackathonActionHubEntry[];
17-
facts: string[];
17+
facts: ReactNode[];
1818
primaryAction?: HackathonHeroAction;
1919
primaryDescription: string;
2020
primaryTitle: string;
@@ -90,8 +90,8 @@ export const HackathonActionHub: FC<PropsWithChildren<HackathonActionHubProps>>
9090
</nav>
9191

9292
<ul className={`list-unstyled ${styles.regFacts} d-flex flex-wrap gap-2 mt-4`}>
93-
{facts.map(fact => (
94-
<li key={fact}>{fact}</li>
93+
{facts.map((fact, index) => (
94+
<li key={index}>{fact}</li>
9595
))}
9696
</ul>
9797
</div>

components/Activity/Hackathon/AgendaCountdown.module.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
grid-template-columns: repeat(4, minmax(0, 1fr));
2121
gap: 0.8rem;
2222

23-
li {
23+
.item {
2424
gap: 0.7rem;
2525
box-shadow:
2626
inset 0 0 0 1px rgba(255, 255, 255, 0.03),

components/Activity/Hackathon/AgendaCountdown.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { TableCellValue } from 'mobx-lark';
22
import { observer } from 'mobx-react';
33
import { FC, useContext, useState } from 'react';
4+
import { Countdown, TimeUnit } from 'idea-react';
45

56
import { Agenda } from '../../../models/Hackathon';
67
import { I18nContext } from '../../../models/Translation';
7-
import { Countdown, TimeUnit } from '../../Base/Countdown';
88
import styles from './AgendaCountdown.module.less';
99
import { agendaTypeLabelOf, resolveCountdownState } from './utility';
1010

@@ -15,7 +15,7 @@ export interface AgendaCountdownProps {
1515
units: TimeUnit[];
1616
}
1717

18-
export const AgendaCountdown: FC<AgendaCountdownProps> = observer(
18+
const AgendaCountdown: FC<AgendaCountdownProps> = observer(
1919
({ agendaItems, endTime, startTime, units }) => {
2020
const { t } = useContext(I18nContext);
2121
const [referenceTime, setReferenceTime] = useState(Date.now());
@@ -38,6 +38,7 @@ export const AgendaCountdown: FC<AgendaCountdownProps> = observer(
3838

3939
<Countdown
4040
className={styles.grid}
41+
itemClassName={`${styles.item} d-flex flex-column align-items-center justify-content-center`}
4142
endTime={countdownTo}
4243
onEnd={() => setReferenceTime(Date.now())}
4344
units={units}
@@ -46,3 +47,4 @@ export const AgendaCountdown: FC<AgendaCountdownProps> = observer(
4647
);
4748
},
4849
);
50+
export default AgendaCountdown;

components/Activity/Hackathon/Hero.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { TableCellValue } from 'mobx-lark';
2-
import { FC } from 'react';
2+
import dynamic from 'next/dynamic';
3+
import { FC, ReactNode } from 'react';
34
import { Container } from 'react-bootstrap';
5+
import { TimeUnit } from 'idea-react';
46

57
import { Agenda } from '../../../models/Hackathon';
68
import { LarkImage } from '../../LarkImage';
7-
import { AgendaCountdown } from './AgendaCountdown';
8-
import { TimeUnit } from '../../Base/Countdown';
99
import styles from './Hero.module.less';
1010

11+
const AgendaCountdown = dynamic(() => import('./AgendaCountdown'), { ssr: false });
12+
1113
export type HackathonHeroNavItem = Record<'label' | 'href', string>;
1214

1315
export interface HackathonHeroAction extends HackathonHeroNavItem {
@@ -26,9 +28,9 @@ export interface HackathonHeroProps extends Record<
2628
string
2729
> {
2830
agendaItems: Agenda[];
29-
badges: string[];
31+
badges: ReactNode[];
3032
bottomCard?: HackathonHeroCard;
31-
chips?: string[];
33+
chips?: ReactNode[];
3234
countdownUnits: TimeUnit[];
3335
endTime?: TableCellValue;
3436
image?: TableCellValue;
@@ -148,7 +150,7 @@ export const HackathonHero: FC<HackathonHeroProps> = ({
148150
<ul className={`list-unstyled ${styles.heroEyebrow} d-flex flex-wrap gap-3 m-0`}>
149151
{badges.map((badge, index) => (
150152
<li
151-
key={`${badge}-${index}`}
153+
key={index}
152154
className={`${styles.heroBadge} d-inline-flex align-items-center ${BadgeToneClass[index % BadgeToneClass.length]}`}
153155
>
154156
{badge}
@@ -180,8 +182,8 @@ export const HackathonHero: FC<HackathonHeroProps> = ({
180182
<ul
181183
className={`list-unstyled ${styles.heroStats} d-flex flex-wrap gap-2 gap-md-3 m-0`}
182184
>
183-
{chips.map(chip => (
184-
<li key={chip} className={`${styles.statChip} d-inline-flex align-items-center`}>
185+
{chips.map((chip, index) => (
186+
<li key={index} className={`${styles.statChip} d-inline-flex align-items-center`}>
185187
{chip}
186188
</li>
187189
))}

components/Activity/Hackathon/Schedule.tsx

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { FC } from 'react';
1+
import { FC, ReactNode } from 'react';
22
import { Container } from 'react-bootstrap';
3+
import { TimeData } from 'web-utility';
34

5+
import { TimeRange } from '../../TimeRange';
46
import type { HackathonAwardsMeta } from './Awards';
57
import styles from './Schedule.module.less';
68

@@ -16,11 +18,13 @@ export interface HackathonScheduleFact extends HackathonAwardsMeta {
1618
}
1719

1820
export interface HackathonScheduleItem extends Record<
19-
'id' | 'phase' | 'title' | 'dateText' | 'description',
21+
'id' | 'phase' | 'title' | 'description',
2022
string
2123
> {
2224
facts: HackathonScheduleFact[];
2325

26+
endedAt?: TimeData;
27+
startedAt?: TimeData;
2428
stageGoal?: string;
2529
tone: HackathonScheduleTone;
2630
}
@@ -30,16 +34,21 @@ export interface HackathonScheduleProps extends Record<
3034
string
3135
> {
3236
items: HackathonScheduleItem[];
33-
keyDates?: Record<'date' | 'label', string>[];
34-
overviewPills: string[];
37+
keyDates?: {
38+
label: string;
39+
startedAt?: TimeData;
40+
endedAt?: TimeData;
41+
}[];
42+
overviewPills: ReactNode[];
3543
}
3644

3745
const ScheduleCard: FC<HackathonScheduleItem & Record<'phaseLabel' | 'stageGoalLabel', string>> = ({
38-
dateText,
3946
description,
47+
endedAt,
4048
facts,
4149
phase,
4250
phaseLabel,
51+
startedAt,
4352
stageGoal,
4453
stageGoalLabel,
4554
title,
@@ -52,7 +61,9 @@ const ScheduleCard: FC<HackathonScheduleItem & Record<'phaseLabel' | 'stageGoalL
5261
<span className={`${styles.dayNo} d-inline-flex align-items-center`}>
5362
{phaseLabel} {phase}
5463
</span>
55-
<time className={styles.dayDate}>{dateText}</time>
64+
<span className={styles.dayDate}>
65+
<TimeRange start={startedAt} end={endedAt} />
66+
</span>
5667
</div>
5768

5869
<h3 className={`${styles.dayTitle} mt-3 mb-2`}>{title}</h3>
@@ -108,8 +119,8 @@ export const HackathonSchedule: FC<HackathonScheduleProps & { phaseLabel: string
108119
<ul
109120
className={`list-unstyled ${styles.scheduleOverview} d-flex flex-wrap justify-content-center gap-3 mb-4`}
110121
>
111-
{overviewPills.map(pill => (
112-
<li key={pill} className={styles.schedulePill}>
122+
{overviewPills.map((pill, index) => (
123+
<li key={index} className={styles.schedulePill}>
113124
{pill}
114125
</li>
115126
))}
@@ -128,12 +139,14 @@ export const HackathonSchedule: FC<HackathonScheduleProps & { phaseLabel: string
128139

129140
{keyDates?.[0] && (
130141
<ul className={`list-unstyled ${styles.keyDates} mt-4`}>
131-
{keyDates.map(({ date, label }, index) => (
142+
{keyDates.map(({ startedAt, endedAt, label }, index) => (
132143
<li
133-
key={`${date}-${label}`}
144+
key={`${startedAt || ''}-${endedAt || ''}-${label}`}
134145
className={`${styles.keyDateCard} d-grid gap-1 ${index % 2 ? styles.keyDateCardWarn : ''}`}
135146
>
136-
<strong className={styles.keyDateValue}>{date}</strong>
147+
<strong className={styles.keyDateValue}>
148+
<TimeRange start={startedAt} end={endedAt} format="MM-DD" />
149+
</strong>
137150
<span className={styles.keyDateLabel}>{label}</span>
138151
</li>
139152
))}

components/Activity/Hackathon/constant.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
formatPeriod,
1313
normalizeAgendaType,
1414
previewText,
15+
timeOf,
1516
} from './utility';
1617

1718
export const RequiredTableKeys = [
@@ -194,13 +195,16 @@ export const buildScheduleItems = (
194195
const description = compactSummaryOf((summary as string) || reasonText, reasonText, 120);
195196
const windowValue = formatPeriod(startedAt, endedAt) || '-';
196197
const focusValue = compactSummaryOf((summary as string) || focusText, focusText, 92);
198+
const startedAtTime = timeOf(startedAt);
199+
const endedAtTime = timeOf(endedAt);
197200

198201
return {
199202
id: id as string,
200203
phase: String(index + 1).padStart(2, '0'),
201-
dateText: formatPeriod(startedAt, endedAt),
202204
title: name as string,
203205
description,
206+
startedAt: Number.isFinite(startedAtTime) ? startedAtTime : undefined,
207+
endedAt: Number.isFinite(endedAtTime) ? endedAtTime : undefined,
204208
stageGoal: stageGoalText,
205209
tone: agendaToneClassOf(type, index),
206210
facts: [

components/Activity/ProductCard.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { observer } from 'mobx-react';
22
import { FilePreview } from 'mobx-restful-table';
33
import { FC } from 'react';
44
import { CardProps, Card, Button } from 'react-bootstrap';
5-
import { formatDate } from 'web-utility';
5+
import { Time } from 'idea-react';
66

77
import { Product } from '../../models/Hackathon';
88
import styles from '../../styles/Hackathon.module.less';
@@ -68,13 +68,9 @@ export const ProductCard: FC<ProductCardProps> = observer(
6868
</div>
6969
)}
7070

71-
<time
72-
suppressHydrationWarning
73-
className="text-dark opacity-75 small"
74-
dateTime={new Date(createdAt as number).toJSON()}
75-
>
76-
📅 {formatDate(createdAt as number)}
77-
</time>
71+
<span className="text-dark opacity-75 small">
72+
📅 <Time dateTime={createdAt as number} format="YYYY-MM-DD" />
73+
</span>
7874
</Card.Body>
7975
</Card>
8076
),

components/Base/Countdown.tsx

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

0 commit comments

Comments
 (0)