Skip to content

Commit ada6a68

Browse files
committed
[offers][feat] show company logo
1 parent c6941c0 commit ada6a68

File tree

12 files changed

+143
-32
lines changed

12 files changed

+143
-32
lines changed

apps/portal/src/components/offers/dashboard/DashboardOfferCard.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
import { JobType } from '@prisma/client';
77

88
import { JobTypeLabel } from '~/components/offers/constants';
9+
import CompanyProfileImage from '~/components/shared/CompanyProfileImage';
910
import type { JobTitleType } from '~/components/shared/JobTitles';
1011
import { getLabelForJobTitleType } from '~/components/shared/JobTitles';
1112

@@ -31,8 +32,13 @@ export default function DashboardProfileCard({
3132
}: Props) {
3233
return (
3334
<div className="px-4 py-4 sm:px-6">
34-
<div className="flex items-end justify-between">
35-
<div className="col-span-1 row-span-3">
35+
<div className="flex justify-between gap-4">
36+
<CompanyProfileImage
37+
alt={company.name}
38+
className="hidden h-10 w-10 object-contain sm:block"
39+
src={company.logoUrl}
40+
/>
41+
<div className="grow">
3642
<h4 className="font-medium">
3743
{getLabelForJobTitleType(title as JobTitleType)}{' '}
3844
{jobType && <>({JobTypeLabel[jobType]})</>}
@@ -80,4 +86,4 @@ export default function DashboardProfileCard({
8086
</div>
8187
</div>
8288
);
83-
}
89+
}

apps/portal/src/components/offers/offerAnalysis/OfferProfileCard.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from '@heroicons/react/24/outline';
1111
import { JobType } from '@prisma/client';
1212

13+
import CompanyProfileImage from '~/components/shared/CompanyProfileImage';
1314
import type { JobTitleType } from '~/components/shared/JobTitles';
1415
import { getLabelForJobTitleType } from '~/components/shared/JobTitles';
1516

@@ -89,8 +90,13 @@ export default function OfferProfileCard({
8990
function BottomSection() {
9091
return (
9192
<div className="px-4 py-4 sm:px-6">
92-
<div className="flex items-end justify-between">
93-
<div className="col-span-1 row-span-3">
93+
<div className="flex justify-between gap-4">
94+
<CompanyProfileImage
95+
alt={company.name}
96+
className="hidden h-10 w-10 object-contain sm:block"
97+
src={company.logoUrl}
98+
/>
99+
<div className="grow">
94100
<h4 className="font-medium">
95101
{getLabelForJobTitleType(title as JobTitleType)}{' '}
96102
{jobType && <>({JobTypeLabel[jobType]})</>}
@@ -125,7 +131,7 @@ export default function OfferProfileCard({
125131
)}
126132
</div>
127133
</div>
128-
<div className="col-span-1 row-span-3">
134+
<div className="flex flex-col justify-center">
129135
<p className="text-end text-lg font-medium leading-6 text-slate-900">
130136
{jobType === JobType.FULLTIME
131137
? `${convertMoneyToString(income)} / year`

apps/portal/src/components/offers/profile/OfferCard.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { JobType } from '@prisma/client';
99
import { JobTypeLabel } from '~/components/offers/constants';
1010
import { InternshipCycleValuesToLabels } from '~/components/offers/InternshipCycles';
1111
import type { OfferDisplayData } from '~/components/offers/types';
12+
import CompanyProfileImage from '~/components/shared/CompanyProfileImage';
1213

1314
import { getLocationDisplayText } from '~/utils/offers/string';
1415
import { getDurationDisplayText } from '~/utils/offers/time';
@@ -21,7 +22,7 @@ export default function OfferCard({
2122
offer: {
2223
base,
2324
bonus,
24-
companyName,
25+
company,
2526
duration,
2627
internshipCycle,
2728
jobTitle,
@@ -40,19 +41,26 @@ export default function OfferCard({
4041
function UpperSection() {
4142
return (
4243
<div className="px-4 py-5 sm:px-6">
43-
<div className="flex justify-between">
44-
<div>
44+
<div className="flex justify-between gap-4">
45+
{company && (
46+
<CompanyProfileImage
47+
alt={company.name}
48+
className="h-10 w-10 object-contain"
49+
src={company.logoUrl}
50+
/>
51+
)}
52+
<div className="grow">
4553
<h3 className="text-lg font-medium leading-6 text-slate-900">
4654
{jobTitle} {jobType && <>({JobTypeLabel[jobType]})</>}
4755
</h3>
4856
<div className="mt-1 flex flex-row flex-wrap sm:mt-0">
49-
{companyName && (
57+
{company?.name != null && (
5058
<div className="mr-4 mt-2 flex items-center text-sm text-slate-500">
5159
<BuildingOfficeIcon
5260
aria-hidden="true"
5361
className="mr-1.5 h-5 w-5 flex-shrink-0 text-slate-400"
5462
/>
55-
{companyName}
63+
{company?.name}
5664
</div>
5765
)}
5866
{location && (

apps/portal/src/components/offers/profile/ProfileDetails.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,21 @@ function ProfileOffers({ offers }: ProfileOffersProps) {
3434
}
3535

3636
return (
37-
<div className="space-y-4 p-4">
38-
{offers.map((offer) => (
39-
<OfferCard key={offer.id} offer={offer} />
40-
))}
37+
<div className="p-4">
38+
<div className="space-y-4">
39+
{offers.map((offer) => (
40+
<OfferCard key={offer.id} offer={offer} />
41+
))}
42+
</div>
43+
<div className="mt-1 text-end">
44+
<a
45+
className="text-xs text-slate-500"
46+
href="https://clearbit.com"
47+
rel="noreferrer"
48+
target="_blank">
49+
Logos provided by Clearbit
50+
</a>
51+
</div>
4152
</div>
4253
);
4354
}
@@ -140,6 +151,15 @@ function ProfileAnalysis({
140151
/>
141152
</div>
142153
)}
154+
<div className="text-end">
155+
<a
156+
className="text-xs text-slate-500"
157+
href="https://clearbit.com"
158+
rel="noreferrer"
159+
target="_blank">
160+
Logos provided by Clearbit
161+
</a>
162+
</div>
143163
</div>
144164
);
145165
}
@@ -188,5 +208,6 @@ export default function ProfileDetails({
188208
/>
189209
);
190210
}
211+
191212
return null;
192213
}

apps/portal/src/components/offers/profile/ProfileHeader.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export default function ProfileHeader({
243243
<h2 className="flex text-2xl font-bold">
244244
{profileName ?? 'anonymous'}
245245
</h2>
246-
{(experiences[0]?.companyName ||
246+
{(experiences[0]?.company?.name ||
247247
experiences[0]?.jobLevel ||
248248
experiences[0]?.jobTitle) && (
249249
<div className="flex items-center text-sm text-slate-600">
@@ -252,7 +252,7 @@ export default function ProfileHeader({
252252
</span>
253253
<p>
254254
<span className="mr-2 font-bold">Current:</span>
255-
{`${experiences[0].companyName || ''} ${
255+
{`${experiences[0].company?.name || ''} ${
256256
experiences[0].jobLevel || ''
257257
} ${experiences[0].jobTitle || ''} ${
258258
experiences[0].jobType

apps/portal/src/components/offers/table/OffersRow.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import clsx from 'clsx';
22
import Link from 'next/link';
33
import { JobType } from '@prisma/client';
44

5+
import CompanyProfileImage from '~/components/shared/CompanyProfileImage';
56
import type { JobTitleType } from '~/components/shared/JobTitles';
67
import { getLabelForJobTitleType } from '~/components/shared/JobTitles';
78

@@ -34,10 +35,19 @@ export default function OfferTableRow({
3435
}: OfferTableRowProps) {
3536
return (
3637
<tr key={id} className="divide-x divide-slate-200 border-b bg-white">
37-
<td className="space-y-0.5 py-2 px-4" scope="row">
38-
<div className="font-medium">{company.name}</div>
39-
<div className="text-xs text-slate-500">
40-
{location.cityName} ({location.countryCode})
38+
<td className="flex items-center gap-3 space-y-0.5 py-2 px-4" scope="row">
39+
<CompanyProfileImage
40+
alt={company.name}
41+
className="hidden h-6 w-6 object-contain sm:block"
42+
src={company.logoUrl}
43+
/>
44+
<div>
45+
<div className="line-clamp-2 sm:line-clamp-1 font-medium">
46+
{company.name}
47+
</div>
48+
<div className="text-xs text-slate-500">
49+
{location.cityName} ({location.countryCode})
50+
</div>
4151
</div>
4252
</td>
4353
<td className="py-2 px-4">

apps/portal/src/components/offers/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type { JobType } from '@prisma/client';
22

33
import type { MonthYear } from '~/components/shared/MonthYearPicker';
44

5+
import type { OffersCompany } from '../../types/offers';
6+
57
import type { Location } from '~/types/offers';
68

79
/**
@@ -177,7 +179,7 @@ export type EducationDisplayData = {
177179
export type OfferDisplayData = {
178180
base?: string | null;
179181
bonus?: string | null;
180-
companyName?: string | null;
182+
company?: OffersCompany | null;
181183
duration?: number | null;
182184
id?: string;
183185
internshipCycle?: string;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import clsx from 'clsx';
2+
import { useState } from 'react';
3+
import { BuildingOffice2Icon } from '@heroicons/react/24/outline';
4+
type Props = Readonly<{
5+
alt: string;
6+
className: string;
7+
src: string;
8+
}>;
9+
10+
export default function CompanyProfileImage({ alt, className, src }: Props) {
11+
const [hasError, setHasError] = useState(false);
12+
13+
return hasError ? (
14+
<div
15+
className={clsx(
16+
'shrink-0 rounded bg-slate-50 p-0.5 text-slate-400',
17+
className,
18+
)}>
19+
<BuildingOffice2Icon />
20+
</div>
21+
) : (
22+
<img
23+
alt={alt}
24+
className={clsx('object-contain', className)}
25+
src={src}
26+
onError={() => {
27+
setHasError(true);
28+
}}
29+
/>
30+
);
31+
}

apps/portal/src/pages/offers/dashboard.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,29 @@ export default function ProfilesDashboard() {
8585
{!userProfilesQuery.isLoading && (
8686
<div className="overflow-y-auto py-8">
8787
<h1 className="mx-auto mb-4 text-start text-4xl font-bold text-slate-900">
88-
My dashboard
88+
Dashboard
8989
</h1>
9090
<p className="mt-4 text-xl leading-8 text-slate-500">
91-
Save your offer profiles to your dashboard to easily access and
92-
edit them later.
91+
Save offer profiles to your dashboard to easily access and edit
92+
them later.
9393
</p>
94-
<div className="mt-8 flex justify-center">
94+
<div className="mt-8">
9595
<ul className="w-full space-y-4" role="list">
9696
{userProfiles?.map((profile) => (
9797
<li key={profile.id}>
9898
<DashboardProfileCard key={profile.id} profile={profile} />
9999
</li>
100100
))}
101101
</ul>
102+
<div className="mt-2 text-end">
103+
<a
104+
className="text-xs text-slate-500"
105+
href="https://clearbit.com"
106+
rel="noreferrer"
107+
target="_blank">
108+
Logos provided by Clearbit
109+
</a>
110+
</div>
102111
</div>
103112
</div>
104113
)}

apps/portal/src/pages/offers/index.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ export default function OffersHomePage({
186186
selectedSortType={selectedSortType}
187187
onSort={onSort}
188188
/>
189+
<div className="mt-1 text-end">
190+
<a
191+
className="text-xs text-slate-500"
192+
href="https://clearbit.com"
193+
rel="noreferrer"
194+
target="_blank">
195+
Logos provided by Clearbit
196+
</a>
197+
</div>
189198
</Container>
190199
</main>
191200
</>

0 commit comments

Comments
 (0)