Skip to content

Commit 009429c

Browse files
fix: allow adding continent to opportunity (#5024)
Co-authored-by: Chris Bongers <chrisbongers@gmail.com>
1 parent c55fa62 commit 009429c

3 files changed

Lines changed: 74 additions & 26 deletions

File tree

packages/shared/src/components/opportunity/OpportunityEditModal/OpportunityEditInfoModal.tsx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,18 @@ export const OpportunityEditInfoModal = ({
211211
<Typography bold type={TypographyType.Caption1} className="-mb-2">
212212
Role location*
213213
</Typography>
214-
<div className="flex gap-4">
214+
{!!errors.location?.[0] &&
215+
errors.location?.[0]?.type === 'custom' && (
216+
<Typography
217+
type={TypographyType.Caption2}
218+
color={TypographyColor.StatusError}
219+
>
220+
{errors.location?.[0]?.message}
221+
</Typography>
222+
)}
223+
<div className="grid grid-cols-2 gap-4">
215224
<TextField
216225
{...register('location.0.country')}
217-
className={{
218-
container: 'flex-1',
219-
}}
220226
defaultValue={opportunity.location[0]?.country}
221227
type="text"
222228
inputId="opportunityCountry"
@@ -226,9 +232,6 @@ export const OpportunityEditInfoModal = ({
226232
/>
227233
<TextField
228234
{...register('location.0.city')}
229-
className={{
230-
container: 'flex-1',
231-
}}
232235
defaultValue={opportunity.location[0]?.city}
233236
type="text"
234237
label="City"
@@ -238,16 +241,22 @@ export const OpportunityEditInfoModal = ({
238241
/>
239242
<TextField
240243
{...register('location.0.subdivision')}
241-
className={{
242-
container: 'flex-1',
243-
}}
244244
defaultValue={opportunity.location[0]?.subdivision}
245245
type="text"
246246
label="Subdivision"
247247
inputId="opportunitySubdivision"
248248
valid={!errors.location?.[0]?.subdivision}
249249
hint={errors.location?.[0]?.subdivision?.message}
250250
/>
251+
<TextField
252+
{...register('location.0.continent')}
253+
defaultValue={opportunity.location[0]?.continent}
254+
type="text"
255+
label="Continent"
256+
inputId="opportunityContinent"
257+
valid={!errors.location?.[0]?.continent}
258+
hint={errors.location?.[0]?.continent?.message}
259+
/>
251260
</div>
252261
<Controller
253262
name="location.0.type"
@@ -271,7 +280,7 @@ export const OpportunityEditInfoModal = ({
271280
onChange={(value) => {
272281
field.onChange(value);
273282
}}
274-
valid={!errors.location?.[0]?.type}
283+
valid={typeof errors.location?.[0]?.type !== 'object'}
275284
/>
276285
);
277286
}}

packages/shared/src/lib/schema/opportunity.ts

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ const processSalaryValue = (val: unknown) => {
1111
return val;
1212
};
1313

14+
const capitalize = (s: string) => {
15+
if (s == null || typeof s !== 'string') {
16+
return s;
17+
}
18+
19+
return s.trim().length === 0
20+
? ''
21+
: s
22+
.trim()
23+
.toLowerCase()
24+
.replace(/\b\w/g, (c) => c.toUpperCase());
25+
};
26+
1427
export const opportunityEditInfoSchema = z.object({
1528
title: z.string().nonempty(labels.form.required).max(240),
1629
tldr: z.string().nonempty(labels.form.required).max(480),
@@ -23,16 +36,37 @@ export const opportunityEditInfoSchema = z.object({
2336
.min(1, labels.form.required)
2437
.max(100),
2538
location: z.array(
26-
z.object({
27-
country: z.string().nonempty(labels.form.required).max(240),
28-
city: z.string().nonempty(labels.form.required).max(240).optional(),
29-
subdivision: z
30-
.string()
31-
.nonempty(labels.form.required)
32-
.max(240)
33-
.optional(),
34-
type: z.coerce.number(labels.form.required).min(1),
35-
}),
39+
z
40+
.object({
41+
country: z.string().max(240),
42+
city: z.string().max(240).optional(),
43+
subdivision: z.string().max(240).optional(),
44+
continent: z
45+
.preprocess(
46+
capitalize,
47+
z.union([z.literal('Europe'), z.literal(''), z.undefined()]),
48+
)
49+
.optional(),
50+
type: z.coerce.number().min(1),
51+
})
52+
.superRefine((val, ctx) => {
53+
const present = [
54+
val.country && val.country.trim() !== '',
55+
val.city && val.city.trim() !== '',
56+
val.subdivision && val.subdivision.trim() !== '',
57+
// continent counts only if it is "Europe" (empty string should not count)
58+
val.continent === 'Europe',
59+
].some(Boolean);
60+
61+
if (!present) {
62+
ctx.addIssue({
63+
code: 'custom',
64+
message:
65+
'At least one of country, city, subdivision, or continent must be provided.',
66+
path: [''], // form-level error
67+
});
68+
}
69+
}),
3670
),
3771
meta: z.object({
3872
employmentType: z.coerce.number().min(1, {

packages/webapp/pages/opportunity/[id]/index.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,16 @@ const metaMap = {
216216
return 'N/A';
217217
}
218218

219-
const output = `${location.city ? `${location.city}` : ''}${
220-
location.subdivision ? `, ${location.subdivision}` : ''
221-
}${location.country ? `, ${location.country}` : ''}`;
222-
223-
return output || 'N/A';
219+
return (
220+
[
221+
location.city,
222+
location.subdivision,
223+
location.country,
224+
location.continent,
225+
]
226+
.filter(Boolean)
227+
.join(', ') || 'N/A'
228+
);
224229
},
225230
},
226231
salary: {

0 commit comments

Comments
 (0)