Skip to content

Commit 9cb654d

Browse files
committed
feat: Add new recommendation page
1 parent 3f59252 commit 9cb654d

File tree

4 files changed

+97
-5
lines changed

4 files changed

+97
-5
lines changed

src/domains/about-me/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { animator } from '@/shared/helpers';
1212
import { titleFont } from '@/app/fonts';
1313
import { PERSONAL_DATA } from '@/data';
1414

15-
import { RecommendationSlider } from './components/RecommendationSlider';
15+
import { RecommendationsBox } from './components/recommendations-box';
1616
import styles from './about-me.module.scss';
1717
import { renderContent } from './helper';
1818

@@ -69,7 +69,7 @@ export function AboutMePage() {
6969
>
7070
{ABOUT_ME_DATA.content.map((item: AboutMeContentItem, index: number) => {
7171
if (index === 3) {
72-
return <RecommendationSlider key="linkedIn-Recommendations" />;
72+
return <RecommendationsBox key="linkedIn-Recommendations" />;
7373
}
7474
return renderContent(index, item);
7575
})}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use client';
2+
3+
import { sendGTMEvent } from '@next/third-parties/google';
4+
import Image from 'next/image';
5+
import Link from 'next/link';
6+
import { clsx } from 'clsx';
7+
8+
9+
import type { RecommendationItem } from '@/data';
10+
import { GTM_EVENTS } from '@/shared/constants';
11+
import { animator } from '@/shared/helpers';
12+
import { titleFont } from '@/app/fonts';
13+
14+
import styles from './recommendation-card.module.scss';
15+
16+
export function RecommendationCard({
17+
data,
18+
animationDelay = '0s'
19+
}: {
20+
data: RecommendationItem;
21+
animationDelay?: string;
22+
}) {
23+
const { url, text, date, title, caption, fullName, imageURL } = data;
24+
25+
const sendEvent = () => sendGTMEvent(GTM_EVENTS.LINKEDIN_RECOMMENDATION(fullName));
26+
27+
return (
28+
<div
29+
style={{ animationDelay }}
30+
className={clsx(
31+
'w-full flex flex-col items-start gap-2 bg-white p-4 dark:bg-black/50',
32+
animator({ name: 'fadeIn' }),
33+
styles['recommendation-card']
34+
)}
35+
>
36+
<div
37+
className='mb-2 flex w-full gap-3 text-left duration-500'
38+
>
39+
{imageURL && (
40+
<Link href={url} onClick={sendEvent} target="_blank" rel="noopener noreferrer">
41+
<Image
42+
width={100}
43+
height={100}
44+
alt={fullName}
45+
src={imageURL}
46+
loading="lazy"
47+
className={clsx(
48+
'rounded-md grayscale duration-500',
49+
styles['recommendation-card__profile-image']
50+
)}
51+
/>
52+
</Link>
53+
)}
54+
<div className="flex w-full flex-col gap-1 text-left">
55+
<Link
56+
href={url}
57+
target="_blank"
58+
onClick={sendEvent}
59+
rel="noopener noreferrer"
60+
className={clsx(titleFont.className, 'text-xl font-bold text-amber-500')}
61+
>
62+
{fullName.toUpperCase()}
63+
</Link>
64+
<p>{title}</p>
65+
<div className="flex flex-wrap items-center gap-2">
66+
<span>{caption}</span>
67+
<span>( {date} )</span>
68+
</div>
69+
</div>
70+
</div>
71+
72+
<p className="w-full text-left" dangerouslySetInnerHTML={{ __html: text }} />
73+
74+
<Link
75+
href={url}
76+
target="_blank"
77+
onClick={sendEvent}
78+
rel="noopener noreferrer"
79+
className="text-amber-500"
80+
>
81+
LinkedIn
82+
</Link>
83+
</div>
84+
);
85+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.recommendation-card {
2+
&:hover & {
3+
&__profile-image {
4+
filter: grayscale(0);
5+
}
6+
}
7+
}

src/domains/recommendations/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import { ContentContainer } from '@/layout/components/content-container';
77
import { animator } from '@/shared/helpers';
88
import { titleFont } from '@/app/fonts';
99

10-
import { RecommendationCard } from './components/RecommendationCard';
10+
import { RecommendationCard } from './components/recommendation-card';
1111

1212
export const metadata: Metadata = {
1313
title: 'Recommendations'
1414
};
1515

16-
export async function RecommendationsPage() {
16+
export function RecommendationsPage() {
1717
return (
1818
<ContentContainer>
1919
<h1
@@ -33,7 +33,7 @@ export async function RecommendationsPage() {
3333
dangerouslySetInnerHTML={{ __html: RECOMMENDATION_PAGE_DATA.description }}
3434
/>
3535

36-
<div className="mt-8 flex flex-col gap-4 overflow-hidden">
36+
<div className="mt-8 flex flex-col gap-6 overflow-hidden">
3737
{RECOMMENDATIONS.map((item: RecommendationItem, index: number) => (
3838
<RecommendationCard key={item.id} data={item} animationDelay={`${(index + 1) * 0.3}s`} />
3939
))}

0 commit comments

Comments
 (0)