Skip to content

Commit a5e8e6c

Browse files
committed
refactor(home): address hero carousel review feedback
1 parent e164187 commit a5e8e6c

4 files changed

Lines changed: 22 additions & 36 deletions

File tree

components/Activity/HeroCarousel.module.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.heroCarousel {
22
--hero-carousel-offset: 4.125rem;
3+
34
background: #050816;
45
min-height: calc(100vh - var(--hero-carousel-offset) - 2.5rem);
56

components/Activity/HeroCarousel.tsx

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { I18nContext } from '../../models/Translation';
88
import { LarkImage } from '../LarkImage';
99
import styles from './HeroCarousel.module.less';
1010

11-
const MAX_ITEMS = 5;
11+
export const HERO_CAROUSEL_ITEMS = 3;
1212

1313
const timestampOf = (value: unknown) => {
1414
if (typeof value === 'number') return value;
@@ -21,12 +21,12 @@ const timestampOf = (value: unknown) => {
2121
return 0;
2222
};
2323

24-
const formatDateLabel = (value: unknown) => {
24+
const formatDateLabel = (value: unknown, locale: string) => {
2525
const timestamp = timestampOf(value);
2626

2727
if (!timestamp) return '';
2828

29-
return new Intl.DateTimeFormat('zh-CN', {
29+
return new Intl.DateTimeFormat(locale, {
3030
month: 'short',
3131
day: 'numeric',
3232
}).format(timestamp);
@@ -40,10 +40,9 @@ const locationTextOf = ({ city, location }: Activity) =>
4040
const descriptionOf = (activity: Activity) =>
4141
(activity.summary as string) || locationTextOf(activity) || (activity.type as string) || '';
4242

43-
export const HeroCarousel: FC = () => {
44-
const { t } = useContext(I18nContext);
43+
export const HeroCarousel: FC<{ activities: Activity[] }> = ({ activities }) => {
44+
const { currentLanguage, t } = useContext(I18nContext);
4545
const [heroStyle, setHeroStyle] = useState<CSSProperties>();
46-
const [activities, setActivities] = useState<Activity[]>([]);
4746
const [descriptionRows, setDescriptionRows] = useState(3);
4847
const infoBodyStyle = { minHeight: 'clamp(0rem, 38vh, 24rem)' } as CSSProperties;
4948

@@ -64,31 +63,6 @@ export const HeroCarousel: FC = () => {
6463
return () => observer?.disconnect();
6564
}, []);
6665

67-
useEffect(() => {
68-
let mounted = true;
69-
70-
(async () => {
71-
try {
72-
const model = new ActivityModel();
73-
const data = await model.getAll();
74-
const latestActivities = data
75-
.filter(({ name }) => Boolean(name))
76-
.sort(
77-
({ startTime: left }, { startTime: right }) => timestampOf(right) - timestampOf(left),
78-
)
79-
.slice(0, MAX_ITEMS);
80-
81-
if (mounted) setActivities(latestActivities);
82-
} catch (err) {
83-
console.error('Failed to load activities:', err);
84-
}
85-
})();
86-
87-
return () => {
88-
mounted = false;
89-
};
90-
}, []);
91-
9266
useEffect(() => {
9367
const syncDescriptionRows = () => {
9468
setDescriptionRows(window.innerWidth <= 767.98 ? 4 : 3);
@@ -122,10 +96,10 @@ export const HeroCarousel: FC = () => {
12296
className={`${styles.carousel} h-100`}
12397
>
12498
{activities.map(activity => {
125-
const href = (activity.link as string) || ActivityModel.getLink(activity);
99+
const href = ActivityModel.getLink(activity);
126100
const hosts = ((activity.host as string[]) || []).slice(0, 2);
127101
const locationText = locationTextOf(activity);
128-
const dateText = formatDateLabel(activity.startTime);
102+
const dateText = formatDateLabel(activity.startTime, currentLanguage);
129103
const title = (activity.name as string) || t('activity');
130104
const description = descriptionOf(activity);
131105
const image = activity.cardImage || activity.image;

models/Activity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class ActivityModel extends BiDataTable<Activity>() {
5555
link,
5656
database,
5757
}: Pick<Activity, 'id' | 'type' | 'alias' | 'link' | 'database'>) =>
58-
database ? `/${type?.toString().toLowerCase() || 'activity'}/${alias || id}` : link + '';
58+
database ? `/${type?.toString().toLowerCase() || 'activity'}/${alias || id}` : link?.toString();
5959

6060
extractFields({
6161
id,

pages/index.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
import { observer } from 'mobx-react';
2+
import { cache, compose, errorLogger } from 'next-ssr-middleware';
23
import { FC, useContext } from 'react';
34
import { Card, Col, Row } from 'react-bootstrap';
45
import { renderToStaticMarkup } from 'react-dom/server';
56
import ReactTyped from 'react-typed-component';
67

78
import { HeroCarousel } from '../components/Activity/HeroCarousel';
89
import { PageHead } from '../components/Layout/PageHead';
10+
import { Activity, ActivityModel } from '../models/Activity';
911
import { I18nContext } from '../models/Translation';
1012
import styles from '../styles/Home.module.less';
1113

12-
const HomePage: FC = observer(() => {
14+
interface HomePageProps {
15+
activities: Activity[];
16+
}
17+
18+
export const getServerSideProps = compose<{}, HomePageProps>(cache(), errorLogger, async () => {
19+
const activities = await new ActivityModel().getList({}, 1, 3);
20+
return { props: JSON.parse(JSON.stringify({ activities })) };
21+
});
22+
23+
const HomePage: FC<HomePageProps> = observer(({ activities }) => {
1324
const { t } = useContext(I18nContext);
1425

1526
return (
1627
<>
1728
<PageHead />
1829

19-
<HeroCarousel />
30+
<HeroCarousel activities={activities} />
2031

2132
<section
2233
className={`flex-fill d-flex flex-column justify-content-center align-items-center bg-secondary bg-gradient text-dark bg-opacity-10 ${styles.main}`}

0 commit comments

Comments
 (0)