Skip to content

Commit 91069e7

Browse files
committed
feat: implement generic RecordTile component for experience and education
1 parent 787bc2a commit 91069e7

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

src/components/Tiles/RecordTile.tsx

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import React from 'react';
2+
3+
import LinkWithArrow from '@/components/ui/LinkWithArrow';
4+
import { useMediaQuery } from '@/hooks/useMediaQuery';
5+
// import Image from 'next/image';
6+
7+
export type RecordTileProps = {
8+
organizationLogo: string;
9+
organizationName: string;
10+
organizationLink: string;
11+
role: string;
12+
duration: string;
13+
details?: React.ReactNode;
14+
organizationBeforeRole?: boolean;
15+
};
16+
17+
function jobDescriptorSection(
18+
organization: string,
19+
link: string,
20+
role: string,
21+
duration: string,
22+
isOrganizationBeforeRole: boolean = false,
23+
isWidth768pxOrMore: boolean,
24+
) {
25+
// styling for:
26+
// h2 - text-xl font-bold
27+
// h3 - text-lg font-semibold
28+
29+
const organizationNameHeadingTag = isOrganizationBeforeRole ? 'h2' : 'h3';
30+
const organizationNameHeading = React.createElement(
31+
LinkWithArrow,
32+
{
33+
href: link,
34+
target: '_blank',
35+
rel: 'noopener noreferrer',
36+
'aria-label': `Link to ${organization}`,
37+
},
38+
React.createElement(
39+
organizationNameHeadingTag,
40+
{ className: isOrganizationBeforeRole ? 'text-xl font-bold' : 'text-lg font-semibold' },
41+
organization,
42+
),
43+
);
44+
const roleHeadingTag = !isOrganizationBeforeRole ? 'h2' : 'h3';
45+
const roleHeading = React.createElement(
46+
roleHeadingTag,
47+
{ className: !isOrganizationBeforeRole ? 'text-xl font-bold' : 'text-lg font-semibold' },
48+
role,
49+
);
50+
51+
return (
52+
<div className="flex flex-col justify-between sm:flex-row md:items-start">
53+
<div>
54+
{isOrganizationBeforeRole ? organizationNameHeading : roleHeading}
55+
{!isOrganizationBeforeRole ? organizationNameHeading : roleHeading}
56+
{!isWidth768pxOrMore && (
57+
<h3 className="font-typewriter text-gray-600 dark:text-gray-400">{duration}</h3>
58+
)}
59+
</div>
60+
{isWidth768pxOrMore && (
61+
<h3 className="font-typewriter text-gray-600 dark:text-gray-400">{duration}</h3>
62+
)}
63+
</div>
64+
);
65+
}
66+
67+
export function RecordTile({
68+
organizationLogo,
69+
organizationName,
70+
organizationLink,
71+
role,
72+
duration,
73+
details,
74+
organizationBeforeRole = false,
75+
}: RecordTileProps) {
76+
const isTablet = useMediaQuery('(min-width: 768px)');
77+
const isDesktop = useMediaQuery('(min-width: 1280px)');
78+
79+
// const topRow = (
80+
// <h2 className="text-xl font-bold">{!organizationBeforeRole ? role : organizationName}</h2>
81+
// );
82+
// const bottomRow = "";
83+
return (
84+
<div className="-mb-2 flex items-center">
85+
<div className="group relative flex-grow lg:-ml-[132px] xl:-ml-40 2xl:-ml-52">
86+
{isTablet && (
87+
<div className="opacity-0 transition-opacity delay-100 md:group-hover:opacity-100">
88+
<div className="absolute top-1/2 aspect-square -translate-y-1/2 transform rounded-lg bg-transparent">
89+
{/* // center the bullet : `top-1/2 transform -translate-y-1/2` */}
90+
<img
91+
src={organizationLogo}
92+
alt={`${organizationName} logo`}
93+
width={isDesktop ? 80 : 70}
94+
height={isDesktop ? 80 : 70}
95+
className="rounded-md"
96+
/>
97+
</div>
98+
</div>
99+
)}
100+
<div className="py-3 lg:pl-[132px] xl:pl-40 2xl:pl-52">
101+
{jobDescriptorSection(
102+
organizationName,
103+
organizationLink,
104+
role,
105+
duration,
106+
organizationBeforeRole,
107+
isTablet,
108+
)}
109+
{details}
110+
</div>
111+
</div>
112+
</div>
113+
);
114+
}

0 commit comments

Comments
 (0)