From 81c30aae069ba9c10ae97719f3fbd0ed13d0ebb8 Mon Sep 17 00:00:00 2001 From: capJavert Date: Mon, 1 Dec 2025 16:38:07 +0100 Subject: [PATCH] feat: organization can be null and inline create --- .../OpportunityEditOrganizationModal.tsx | 45 +++++--- .../components/OpportunityMatchList.tsx | 18 +-- .../shared/src/features/opportunity/types.ts | 2 +- packages/shared/src/lib/schema/opportunity.ts | 10 ++ packages/webapp/pages/jobs/[id]/index.tsx | 104 +++++++++--------- 5 files changed, 107 insertions(+), 72 deletions(-) diff --git a/packages/shared/src/components/opportunity/OpportunityEditModal/OpportunityEditOrganizationModal.tsx b/packages/shared/src/components/opportunity/OpportunityEditModal/OpportunityEditOrganizationModal.tsx index 80e7c23e82e..6f04efc1ad9 100644 --- a/packages/shared/src/components/opportunity/OpportunityEditModal/OpportunityEditOrganizationModal.tsx +++ b/packages/shared/src/components/opportunity/OpportunityEditModal/OpportunityEditOrganizationModal.tsx @@ -14,6 +14,7 @@ import Textarea from '../../fields/Textarea'; import { Button, ButtonSize, ButtonVariant } from '../../buttons/Button'; import { labels } from '../../../lib'; import { + opportunityCreateOrganizationSchema, opportunityEditOrganizationSchema, SocialMediaType, } from '../../../lib/schema/opportunity'; @@ -345,6 +346,12 @@ export const OpportunityEditOrganizationModal = ({ ...clearOrganizationImageMutationOptions(), }); + // if there was no organization we use create schema to require name + const editSchema = + opportunity && !opportunity.organization + ? opportunityCreateOrganizationSchema + : opportunityEditOrganizationSchema; + const { register, control, @@ -354,26 +361,27 @@ export const OpportunityEditOrganizationModal = ({ setValue, watch, } = useForm({ - resolver: zodResolver(opportunityEditOrganizationSchema), + resolver: zodResolver(editSchema), defaultValues: async () => { const opportunityData = await promise; // Merge all link types into a single array - const customLinks = opportunityData.organization.customLinks || []; - const socialLinks = opportunityData.organization.socialLinks || []; - const pressLinks = opportunityData.organization.pressLinks || []; + const customLinks = opportunityData.organization?.customLinks || []; + const socialLinks = opportunityData.organization?.socialLinks || []; + const pressLinks = opportunityData.organization?.pressLinks || []; const allLinks = [...customLinks, ...socialLinks, ...pressLinks]; return { organization: { - website: opportunityData.organization.website || '', - description: opportunityData.organization.description || '', - perks: opportunityData.organization.perks || [], - founded: opportunityData.organization.founded || undefined, - location: opportunityData.organization.location || '', - category: opportunityData.organization.category || '', - size: opportunityData.organization.size || undefined, - stage: opportunityData.organization.stage || undefined, + name: opportunityData.organization?.name || '', + website: opportunityData.organization?.website || '', + description: opportunityData.organization?.description || '', + perks: opportunityData.organization?.perks || [], + founded: opportunityData.organization?.founded || undefined, + location: opportunityData.organization?.location || '', + category: opportunityData.organization?.category || '', + size: opportunityData.organization?.size || undefined, + stage: opportunityData.organization?.stage || undefined, links: allLinks, }, }; @@ -389,7 +397,7 @@ export const OpportunityEditOrganizationModal = ({ await mutateAsync({ id, - payload: data as z.infer, + payload: data as z.infer, organizationImage: organizationImageFile || undefined, }); } catch (originalError) { @@ -521,6 +529,17 @@ export const OpportunityEditOrganizationModal = ({ fileSizeLimitMB={5} /> + {editSchema === opportunityCreateOrganizationSchema && ( + + )} - + {!!opportunity.organization && ( + + )} - {opportunity.organization.name} •{' '} + {opportunity.organization?.name || 'N/A'} •{' '}
{ }); }} /> -
- + {!!opportunity.organization && ( +
+ - - {opportunity.organization.name}{' '} - Verified job + {opportunity.organization.name}{' '} + + Verified job + - -
+
+ )} {/* Recruiter */} {!!opportunity.recruiters?.[0] && (
@@ -704,7 +706,7 @@ const JobPage = (): ReactElement => { }} /> - {opportunity.organization.website && ( + {!!opportunity.organization?.website && (
{/* Company information */} -
- + {!!opportunity.organization && ( +
+ -
- - {opportunity.organization.name} - - - {companyStageMap[opportunity.organization.stage]} •{' '} - {opportunity.organization.category} - +
+ + {opportunity.organization.name} + + + {companyStageMap[opportunity.organization.stage]} •{' '} + {opportunity.organization.category} + +
-
+ )} {/* SoMe Links */} - {opportunity.organization.socialLinks?.length > 0 && ( + {opportunity.organization?.socialLinks?.length > 0 && (
{opportunity.organization.socialLinks.map( ({ link, socialType }) => ( @@ -786,7 +790,7 @@ const JobPage = (): ReactElement => { Founded - {opportunity.organization.founded} + {opportunity.organization?.founded || 'N/A'} { HQ - {opportunity.organization.location} + {opportunity.organization?.location || 'N/A'} { Employees - {companySizeMap[opportunity.organization.size]} + {companySizeMap[opportunity.organization?.size] || 'N/A'}
{/* Description */} - {opportunity.organization.description && ( + {!!opportunity.organization?.description && ( { )} {/* Perks & Benefits */} - {opportunity.organization.perks && ( + {opportunity.organization?.perks?.length > 0 && (
Perks & Benefits