From 7b960a0b87c6f82a247697fa96872e9174d14c71 Mon Sep 17 00:00:00 2001 From: Bryann Yeap Kok Keong Date: Mon, 31 Oct 2022 14:09:57 +0800 Subject: [PATCH 1/8] [offers][chore] Change location in schema --- apps/portal/prisma/schema.prisma | 8 +- .../router/offers/offers-profile-router.ts | 73 +++++++++++++++++-- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/apps/portal/prisma/schema.prisma b/apps/portal/prisma/schema.prisma index b2820c3c..b6873fde 100644 --- a/apps/portal/prisma/schema.prisma +++ b/apps/portal/prisma/schema.prisma @@ -131,6 +131,8 @@ model City { stateId String state State @relation(fields: [stateId], references: [id]) questionsQuestionEncounters QuestionsQuestionEncounter[] + OffersExperience OffersExperience[] + OffersOffer OffersOffer[] @@unique([name, stateId]) } @@ -265,7 +267,8 @@ model OffersExperience { // Add more fields durationInMonths Int? - location String? + location City? @relation(fields: [cityId], references: [id]) + cityId String? // FULLTIME fields level String? @@ -348,8 +351,9 @@ model OffersOffer { company Company @relation(fields: [companyId], references: [id]) companyId String + location City @relation(fields: [cityId], references: [id]) + cityId String monthYearReceived DateTime - location String negotiationStrategy String comments String diff --git a/apps/portal/src/server/router/offers/offers-profile-router.ts b/apps/portal/src/server/router/offers/offers-profile-router.ts index 48c8fb74..7e4ed3c5 100644 --- a/apps/portal/src/server/router/offers/offers-profile-router.ts +++ b/apps/portal/src/server/router/offers/offers-profile-router.ts @@ -110,12 +110,12 @@ export const offersProfileRouter = createRouter() async resolve({ ctx, input }) { const profile = await ctx.prisma.offersProfile.findFirst({ where: { - id: input.profileId - } - }) + id: input.profileId, + }, + }); - return profile?.editToken === input.token - } + return profile?.editToken === input.token; + }, }) .query('listOne', { input: z.object({ @@ -133,6 +133,15 @@ export const offersProfileRouter = createRouter() topSimilarOffers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -150,6 +159,15 @@ export const offersProfileRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, }, }, }, @@ -165,6 +183,15 @@ export const offersProfileRouter = createRouter() topSimilarOffers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -182,6 +209,15 @@ export const offersProfileRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, }, }, }, @@ -195,6 +231,15 @@ export const offersProfileRouter = createRouter() overallHighestOffer: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -220,6 +265,15 @@ export const offersProfileRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, monthlySalary: true, totalCompensation: true, }, @@ -237,6 +291,15 @@ export const offersProfileRouter = createRouter() offers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { baseSalary: true, From b5b42ced4b667c92c43ea66c4686e9e09f6b90bc Mon Sep 17 00:00:00 2001 From: Bryann Yeap Kok Keong Date: Mon, 31 Oct 2022 14:47:05 +0800 Subject: [PATCH 2/8] Include City, State, and Country in profileDtoMapper params --- apps/portal/src/mappers/offers-mappers.ts | 24 +++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/portal/src/mappers/offers-mappers.ts b/apps/portal/src/mappers/offers-mappers.ts index 7ce52626..a2a7c80f 100644 --- a/apps/portal/src/mappers/offers-mappers.ts +++ b/apps/portal/src/mappers/offers-mappers.ts @@ -1,5 +1,7 @@ import type { + City, Company, + Country, OffersAnalysis, OffersAnalysisUnit, OffersBackground, @@ -12,6 +14,7 @@ import type { OffersProfile, OffersReply, OffersSpecificYoe, + State, User, } from '@prisma/client'; import { JobType } from '@prisma/client'; @@ -449,6 +452,7 @@ export const profileDtoMapper = ( topSimilarOffers: Array< OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -459,7 +463,14 @@ export const profileDtoMapper = ( background: | (OffersBackground & { experiences: Array< - OffersExperience & { company: Company | null } + OffersExperience & { + company: Company | null; + location: + | (City & { + state: State & { country: Country }; + }) + | null; + } >; }) | null; @@ -472,6 +483,7 @@ export const profileDtoMapper = ( topSimilarOffers: Array< OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -482,7 +494,12 @@ export const profileDtoMapper = ( background: | (OffersBackground & { experiences: Array< - OffersExperience & { company: Company | null } + OffersExperience & { + company: Company | null; + location: + | (City & { state: State & { country: Country } }) + | null; + } >; }) | null; @@ -492,6 +509,7 @@ export const profileDtoMapper = ( }; overallHighestOffer: OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -508,6 +526,7 @@ export const profileDtoMapper = ( experiences: Array< OffersExperience & { company: Company | null; + location: (City & { state: State & { country: Country } }) | null; monthlySalary: OffersCurrency | null; totalCompensation: OffersCurrency | null; } @@ -525,6 +544,7 @@ export const profileDtoMapper = ( offers: Array< OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { baseSalary: OffersCurrency | null; From 02a90d27361b7fb3acbf673acc373f04cc99f21c Mon Sep 17 00:00:00 2001 From: Bryann Yeap Kok Keong Date: Wed, 2 Nov 2022 04:09:11 +0800 Subject: [PATCH 3/8] [offers][chore] Change backend endpoints to new location field --- apps/portal/src/mappers/offers-mappers.ts | 72 ++++++++-- .../router/offers/offers-analysis-router.ts | 128 +++++++++++++++++- .../offers/offers-user-profile-router.ts | 9 ++ .../portal/src/server/router/offers/offers.ts | 8 +- apps/portal/src/types/offers.d.ts | 20 ++- 5 files changed, 217 insertions(+), 20 deletions(-) diff --git a/apps/portal/src/mappers/offers-mappers.ts b/apps/portal/src/mappers/offers-mappers.ts index a2a7c80f..e0cea797 100644 --- a/apps/portal/src/mappers/offers-mappers.ts +++ b/apps/portal/src/mappers/offers-mappers.ts @@ -31,6 +31,7 @@ import type { Education, Experience, GetOffersResponse, + Location, OffersCompany, Paging, Profile, @@ -45,6 +46,7 @@ import type { const analysisOfferDtoMapper = ( offer: OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -52,7 +54,14 @@ const analysisOfferDtoMapper = ( profile: OffersProfile & { background: | (OffersBackground & { - experiences: Array; + experiences: Array< + OffersExperience & { + company: Company | null; + location: + | (City & { state: State & { country: Country } }) + | null; + } + >; }) | null; }; @@ -71,7 +80,7 @@ const analysisOfferDtoMapper = ( }, jobType: offer.jobType, level: offer.offersFullTime?.level ?? '', - location: offer.location, + location: locationDtoMapper(offer.location), monthYearReceived: offer.monthYearReceived, negotiationStrategy: offer.negotiationStrategy, previousCompanies: @@ -120,6 +129,7 @@ const analysisUnitDtoMapper = ( topSimilarOffers: Array< OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -128,7 +138,12 @@ const analysisUnitDtoMapper = ( background: | (OffersBackground & { experiences: Array< - OffersExperience & { company: Company | null } + OffersExperience & { + company: Company | null; + location: + | (City & { state: State & { country: Country } }) + | null; + } >; }) | null; @@ -151,6 +166,7 @@ const analysisUnitDtoMapper = ( const analysisHighestOfferDtoMapper = ( offer: OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -162,7 +178,7 @@ const analysisHighestOfferDtoMapper = ( company: offersCompanyDtoMapper(offer.company), id: offer.id, level: offer.offersFullTime?.level ?? '', - location: offer.location, + location: locationDtoMapper(offer.location), totalYoe: offer.profile.background?.totalYoe ?? -1, }; return analysisHighestOfferDto; @@ -176,6 +192,7 @@ export const profileAnalysisDtoMapper = ( topSimilarOffers: Array< OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -186,7 +203,12 @@ export const profileAnalysisDtoMapper = ( background: | (OffersBackground & { experiences: Array< - OffersExperience & { company: Company | null } + OffersExperience & { + company: Company | null; + location: + | (City & { state: State & { country: Country } }) + | null; + } >; }) | null; @@ -199,6 +221,7 @@ export const profileAnalysisDtoMapper = ( topSimilarOffers: Array< OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -209,7 +232,12 @@ export const profileAnalysisDtoMapper = ( background: | (OffersBackground & { experiences: Array< - OffersExperience & { company: Company | null } + OffersExperience & { + company: Company | null; + location: + | (City & { state: State & { country: Country } }) + | null; + } >; }) | null; @@ -219,6 +247,7 @@ export const profileAnalysisDtoMapper = ( }; overallHighestOffer: OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -250,6 +279,23 @@ export const profileAnalysisDtoMapper = ( return profileAnalysisDto; }; +export const locationDtoMapper = ( + city: City & { state: State & { country: Country } }, +) => { + const { state } = city; + const { country } = state; + const locationDto: Location = { + cityId: city.id, + cityName: city.name, + countryCode: country.code, + countryId: country.id, + countryName: country.name, + stateId: state.id, + stateName: state.name, + }; + return locationDto; +}; + export const valuationDtoMapper = (currency: { baseCurrency: string; baseValue: number; @@ -303,6 +349,7 @@ export const educationDtoMapper = (education: { export const experienceDtoMapper = ( experience: OffersExperience & { company: Company | null; + location: (City & { state: State & { country: Country } }) | null; monthlySalary: OffersCurrency | null; totalCompensation: OffersCurrency | null; }, @@ -315,7 +362,10 @@ export const experienceDtoMapper = ( id: experience.id, jobType: experience.jobType, level: experience.level, - location: experience.location, + location: + experience.location != null + ? locationDtoMapper(experience.location) + : null, monthlySalary: experience.monthlySalary ? valuationDtoMapper(experience.monthlySalary) : null, @@ -348,6 +398,7 @@ export const backgroundDtoMapper = ( experiences: Array< OffersExperience & { company: Company | null; + location: (City & { state: State & { country: Country } }) | null; monthlySalary: OffersCurrency | null; totalCompensation: OffersCurrency | null; } @@ -386,6 +437,7 @@ export const backgroundDtoMapper = ( export const profileOfferDtoMapper = ( offer: OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { baseSalary: OffersCurrency | null; @@ -402,7 +454,7 @@ export const profileOfferDtoMapper = ( company: offersCompanyDtoMapper(offer.company), id: offer.id, jobType: offer.jobType, - location: offer.location, + location: locationDtoMapper(offer.location), monthYearReceived: offer.monthYearReceived, negotiationStrategy: offer.negotiationStrategy, offersFullTime: offer.offersFullTime, @@ -676,6 +728,7 @@ export const getUserProfileResponseMapper = ( offers: Array< OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -711,6 +764,7 @@ export const getUserProfileResponseMapper = ( const userProfileOfferDtoMapper = ( offer: OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: | (OffersFullTime & { totalCompensation: OffersCurrency }) | null; @@ -729,7 +783,7 @@ const userProfileOfferDtoMapper = ( }, jobType: offer.jobType, level: offer.offersFullTime?.level ?? '', - location: offer.location, + location: locationDtoMapper(offer.location), monthYearReceived: offer.monthYearReceived, title: offer.jobType === JobType.FULLTIME diff --git a/apps/portal/src/server/router/offers/offers-analysis-router.ts b/apps/portal/src/server/router/offers/offers-analysis-router.ts index b42da967..f86cdc75 100644 --- a/apps/portal/src/server/router/offers/offers-analysis-router.ts +++ b/apps/portal/src/server/router/offers/offers-analysis-router.ts @@ -1,12 +1,15 @@ import { z } from 'zod'; import type { + City, Company, + Country, OffersBackground, OffersCurrency, OffersFullTime, OffersIntern, OffersOffer, OffersProfile, + State, } from '@prisma/client'; import { TRPCError } from '@trpc/server'; @@ -16,8 +19,14 @@ import { createRouter } from '../context'; type Offer = OffersOffer & { company: Company; + location: City & { state: State & { country: Country } }; offersFullTime: - | (OffersFullTime & { totalCompensation: OffersCurrency }) + | (OffersFullTime & { + baseSalary: OffersCurrency | null; + bonus: OffersCurrency | null; + stocks: OffersCurrency | null; + totalCompensation: OffersCurrency; + }) | null; offersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null; profile: OffersProfile & { background: OffersBackground | null }; @@ -60,6 +69,15 @@ export const offersAnalysisRouter = createRouter() topSimilarOffers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -77,6 +95,15 @@ export const offersAnalysisRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, }, }, }, @@ -92,6 +119,15 @@ export const offersAnalysisRouter = createRouter() topSimilarOffers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -109,6 +145,15 @@ export const offersAnalysisRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, }, }, }, @@ -122,6 +167,15 @@ export const offersAnalysisRouter = createRouter() overallHighestOffer: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -169,6 +223,15 @@ export const offersAnalysisRouter = createRouter() const offers = await ctx.prisma.offersOffer.findMany({ include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { baseSalary: true, @@ -235,6 +298,15 @@ export const offersAnalysisRouter = createRouter() let similarOffers = await ctx.prisma.offersOffer.findMany({ include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -252,6 +324,15 @@ export const offersAnalysisRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, }, }, }, @@ -434,6 +515,15 @@ export const offersAnalysisRouter = createRouter() topSimilarOffers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -451,6 +541,15 @@ export const offersAnalysisRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, }, }, }, @@ -466,6 +565,15 @@ export const offersAnalysisRouter = createRouter() topSimilarOffers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, @@ -483,6 +591,15 @@ export const offersAnalysisRouter = createRouter() experiences: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, }, }, }, @@ -496,6 +613,15 @@ export const offersAnalysisRouter = createRouter() overallHighestOffer: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, diff --git a/apps/portal/src/server/router/offers/offers-user-profile-router.ts b/apps/portal/src/server/router/offers/offers-user-profile-router.ts index 48994044..ae816261 100644 --- a/apps/portal/src/server/router/offers/offers-user-profile-router.ts +++ b/apps/portal/src/server/router/offers/offers-user-profile-router.ts @@ -57,6 +57,15 @@ export const offersUserProfileRouter = createProtectedRouter() offers: { include: { company: true, + location: { + include: { + state: { + include: { + country: true, + }, + }, + }, + }, offersFullTime: { include: { totalCompensation: true, diff --git a/apps/portal/src/server/router/offers/offers.ts b/apps/portal/src/server/router/offers/offers.ts index 86cd29ef..916dcb57 100644 --- a/apps/portal/src/server/router/offers/offers.ts +++ b/apps/portal/src/server/router/offers/offers.ts @@ -43,12 +43,12 @@ const getYoeRange = (yoeCategory: number) => { export const offersRouter = createRouter().query('list', { input: z.object({ + cityId: z.string(), companyId: z.string().nullish(), currency: z.string().nullish(), dateEnd: z.date().nullish(), dateStart: z.date().nullish(), limit: z.number().positive(), - location: z.string(), offset: z.number().nonnegative(), salaryMax: z.number().nonnegative().nullish(), salaryMin: z.number().nonnegative().nullish(), @@ -132,8 +132,7 @@ export const offersRouter = createRouter().query('list', { where: { AND: [ { - location: - input.location.length === 0 ? undefined : input.location, + cityId: input.cityId.length === 0 ? undefined : input.cityId, }, { offersIntern: { @@ -246,8 +245,7 @@ export const offersRouter = createRouter().query('list', { where: { AND: [ { - location: - input.location.length === 0 ? undefined : input.location, + cityId: input.cityId.length === 0 ? undefined : input.cityId, }, { offersIntern: { diff --git a/apps/portal/src/types/offers.d.ts b/apps/portal/src/types/offers.d.ts index 2ff82a16..3dcba938 100644 --- a/apps/portal/src/types/offers.d.ts +++ b/apps/portal/src/types/offers.d.ts @@ -25,7 +25,7 @@ export type Experience = { id: string; jobType: JobType?; level: string?; - location: string?; + location: Location?; monthlySalary: Valuation?; title: string?; totalCompensation: Valuation?; @@ -79,7 +79,7 @@ export type ProfileOffer = { company: OffersCompany; id: string; jobType: JobType; - location: string; + location: Location; monthYearReceived: Date; negotiationStrategy: string; offersFullTime: FullTime?; @@ -163,7 +163,7 @@ export type AnalysisHighestOffer = { company: OffersCompany; id: string; level: string; - location: string; + location: Location; totalYoe: number; }; @@ -173,7 +173,7 @@ export type AnalysisOffer = { income: Valuation; jobType: JobType; level: string; - location: string; + location: Location; monthYearReceived: Date; negotiationStrategy: string; previousCompanies: Array; @@ -202,7 +202,17 @@ export type UserProfileOffer = { income: Valuation; jobType: JobType; level: string; - location: string; + location: Location; monthYearReceived: Date; title: string; }; + +export type Location = { + cityId: string; + cityName: string; + countryCode: string; + countryId: string; + countryName: string; + stateId: string; + stateName: string; +}; From 89644e8c2b2d2cde6d78269552055f205010ce9f Mon Sep 17 00:00:00 2001 From: Stuart Long Chay Boon Date: Wed, 2 Nov 2022 16:11:06 +0800 Subject: [PATCH 4/8] [offers][feat] integrate cityId into create profile endpoint --- .../router/offers/offers-profile-router.ts | 149 +++++++++++++++++- 1 file changed, 144 insertions(+), 5 deletions(-) diff --git a/apps/portal/src/server/router/offers/offers-profile-router.ts b/apps/portal/src/server/router/offers/offers-profile-router.ts index 7e4ed3c5..505c6ac9 100644 --- a/apps/portal/src/server/router/offers/offers-profile-router.ts +++ b/apps/portal/src/server/router/offers/offers-profile-router.ts @@ -34,12 +34,12 @@ const company = z.object({ }); const offer = z.object({ + cityId: z.string(), comments: z.string(), company: company.nullish(), companyId: z.string(), id: z.string().optional(), jobType: z.string().regex(createValidationRegex(Object.keys(JobType), null)), - location: z.string(), monthYearReceived: z.date(), negotiationStrategy: z.string(), offersFullTime: z @@ -74,6 +74,7 @@ const offer = z.object({ const experience = z.object({ backgroundId: z.string().nullish(), + cityId: z.string().nullish(), company: company.nullish(), companyId: z.string().nullish(), durationInMonths: z.number().nullish(), @@ -83,7 +84,6 @@ const experience = z.object({ .regex(createValidationRegex(Object.keys(JobType), null)) .nullish(), level: z.string().nullish(), - location: z.string().nullish(), monthlySalary: valuation.nullish(), monthlySalaryId: z.string().nullish(), title: z.string().nullish(), @@ -375,6 +375,39 @@ export const offersProfileRouter = createRouter() input.background.experiences.map(async (x) => { if (x.jobType === JobType.FULLTIME) { if (x.companyId) { + if (x.cityId) { + return { + company: { + connect: { + id: x.companyId, + }, + }, + durationInMonths: x.durationInMonths, + jobType: x.jobType, + level: x.level, + location: { + connect: { + id: x.cityId + } + }, + title: x.title, + totalCompensation: + x.totalCompensation != null + ? { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + x.totalCompensation.value, + x.totalCompensation.currency, + baseCurrencyString, + ), + currency: x.totalCompensation.currency, + value: x.totalCompensation.value, + }, + } + : undefined, + }; + } return { company: { connect: { @@ -402,11 +435,40 @@ export const offersProfileRouter = createRouter() : undefined, }; } + if (x.cityId) { + return { + durationInMonths: x.durationInMonths, + jobType: x.jobType, + level: x.level, + location: { + connect: { + where: { + id: x.cityId + } + } + }, + title: x.title, + totalCompensation: + x.totalCompensation != null + ? { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + x.totalCompensation.value, + x.totalCompensation.currency, + baseCurrencyString, + ), + currency: x.totalCompensation.currency, + value: x.totalCompensation.value, + }, + } + : undefined, + }; + } return { durationInMonths: x.durationInMonths, jobType: x.jobType, level: x.level, - location: x.location, title: x.title, totalCompensation: x.totalCompensation != null @@ -427,6 +489,40 @@ export const offersProfileRouter = createRouter() } if (x.jobType === JobType.INTERN) { if (x.companyId) { + if (x.cityId) { + return { + company: { + connect: { + id: x.companyId, + }, + }, + durationInMonths: x.durationInMonths, + jobType: x.jobType, + location: { + connect: { + where: { + id: x.cityId + } + } + }, + monthlySalary: + x.monthlySalary != null + ? { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + x.monthlySalary.value, + x.monthlySalary.currency, + baseCurrencyString, + ), + currency: x.monthlySalary.currency, + value: x.monthlySalary.value, + }, + } + : undefined, + title: x.title, + }; + } return { company: { connect: { @@ -453,6 +549,37 @@ export const offersProfileRouter = createRouter() title: x.title, }; } + + if (x.cityId) { + return { + durationInMonths: x.durationInMonths, + jobType: x.jobType, + location: { + connect: { + where: { + id: x.cityId + } + } + }, + monthlySalary: + x.monthlySalary != null + ? { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + x.monthlySalary.value, + x.monthlySalary.currency, + baseCurrencyString, + ), + currency: x.monthlySalary.currency, + value: x.monthlySalary.value, + }, + } + : undefined, + title: x.title, + }; + } + return { durationInMonths: x.durationInMonths, jobType: x.jobType, @@ -513,7 +640,13 @@ export const offersProfileRouter = createRouter() }, }, jobType: x.jobType, - location: x.location, + location: { + connect: { + where: { + id: x.cityId + } + } + }, monthYearReceived: x.monthYearReceived, negotiationStrategy: x.negotiationStrategy, offersIntern: { @@ -553,7 +686,13 @@ export const offersProfileRouter = createRouter() }, }, jobType: x.jobType, - location: x.location, + location: { + connect: { + where: { + id: x.cityId + } + } + }, monthYearReceived: x.monthYearReceived, negotiationStrategy: x.negotiationStrategy, offersFullTime: { From bebbebf9dcef480699019512a4311cb7f040b50c Mon Sep 17 00:00:00 2001 From: Stuart Long Chay Boon Date: Wed, 2 Nov 2022 16:30:08 +0800 Subject: [PATCH 5/8] [offers][feat] integrate location with update profile endpoint --- .../router/offers/offers-profile-router.ts | 344 +++++++++++++++--- 1 file changed, 298 insertions(+), 46 deletions(-) diff --git a/apps/portal/src/server/router/offers/offers-profile-router.ts b/apps/portal/src/server/router/offers/offers-profile-router.ts index 505c6ac9..81f73458 100644 --- a/apps/portal/src/server/router/offers/offers-profile-router.ts +++ b/apps/portal/src/server/router/offers/offers-profile-router.ts @@ -1035,35 +1035,110 @@ export const offersProfileRouter = createRouter() exp.totalCompensation?.currency != null && exp.totalCompensation?.value != null ) { + // FULLTIME if (exp.companyId) { + if (exp.cityId) { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + level: exp.level, + location: { + connect: { + id: exp.cityId + } + }, + title: exp.title, + totalCompensation: exp.totalCompensation + ? { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.totalCompensation.value, + exp.totalCompensation.currency, + baseCurrencyString, + ), + currency: exp.totalCompensation.currency, + value: exp.totalCompensation.value, + }, + } + : undefined, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } else { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + level: exp.level, + title: exp.title, + totalCompensation: exp.totalCompensation + ? { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.totalCompensation.value, + exp.totalCompensation.currency, + baseCurrencyString, + ), + currency: exp.totalCompensation.currency, + value: exp.totalCompensation.value, + }, + } + : undefined, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } + } else if (exp.cityId) { await ctx.prisma.offersBackground.update({ data: { experiences: { create: { - company: { - connect: { - id: exp.companyId, - }, - }, durationInMonths: exp.durationInMonths, jobType: exp.jobType, level: exp.level, - location: exp.location, + location: { + connect: { + id: exp.cityId + } + }, title: exp.title, - totalCompensation: exp.totalCompensation - ? { - create: { - baseCurrency: baseCurrencyString, - baseValue: await convert( - exp.totalCompensation.value, - exp.totalCompensation.currency, - baseCurrencyString, - ), - currency: exp.totalCompensation.currency, - value: exp.totalCompensation.value, - }, - } - : undefined, + totalCompensation: { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.totalCompensation.value, + exp.totalCompensation.currency, + baseCurrencyString, + ), + currency: exp.totalCompensation.currency, + value: exp.totalCompensation.value, + }, + }, }, }, }, @@ -1079,7 +1154,6 @@ export const offersProfileRouter = createRouter() durationInMonths: exp.durationInMonths, jobType: exp.jobType, level: exp.level, - location: exp.location, title: exp.title, totalCompensation: { create: { @@ -1102,19 +1176,67 @@ export const offersProfileRouter = createRouter() }); } } else if (exp.companyId) { + if (exp.cityId) { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + level: exp.level, + location: { + connect: { + id: exp.cityId + } + }, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } else { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + level: exp.level, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } + } else if (exp.cityId) { await ctx.prisma.offersBackground.update({ data: { experiences: { create: { - company: { - connect: { - id: exp.companyId, - }, - }, durationInMonths: exp.durationInMonths, jobType: exp.jobType, level: exp.level, - location: exp.location, + location: { + connect: { + id: exp.cityId + } + }, title: exp.title, }, }, @@ -1131,7 +1253,6 @@ export const offersProfileRouter = createRouter() durationInMonths: exp.durationInMonths, jobType: exp.jobType, level: exp.level, - location: exp.location, title: exp.title, }, }, @@ -1146,19 +1267,90 @@ export const offersProfileRouter = createRouter() exp.monthlySalary?.currency != null && exp.monthlySalary?.value != null ) { + // INTERN if (exp.companyId) { + if (exp.cityId) { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + location: { + connect: { + id: exp.cityId + } + }, + monthlySalary: { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.monthlySalary.value, + exp.monthlySalary.currency, + baseCurrencyString, + ), + currency: exp.monthlySalary.currency, + value: exp.monthlySalary.value, + }, + }, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } else { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + monthlySalary: { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.monthlySalary.value, + exp.monthlySalary.currency, + baseCurrencyString, + ), + currency: exp.monthlySalary.currency, + value: exp.monthlySalary.value, + }, + }, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } + } else if (exp.cityId) { await ctx.prisma.offersBackground.update({ data: { experiences: { create: { - company: { - connect: { - id: exp.companyId, - }, - }, durationInMonths: exp.durationInMonths, jobType: exp.jobType, - location: exp.location, + location: { + connect: { + id: exp.cityId + } + }, monthlySalary: { create: { baseCurrency: baseCurrencyString, @@ -1186,7 +1378,6 @@ export const offersProfileRouter = createRouter() create: { durationInMonths: exp.durationInMonths, jobType: exp.jobType, - location: exp.location, monthlySalary: { create: { baseCurrency: baseCurrencyString, @@ -1209,18 +1400,64 @@ export const offersProfileRouter = createRouter() }); } } else if (exp.companyId) { + if (exp.cityId) { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + location: { + connect: { + id: exp.cityId, + } + }, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } else { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } + } else if (exp.cityId) { await ctx.prisma.offersBackground.update({ data: { experiences: { create: { - company: { - connect: { - id: exp.companyId, - }, - }, durationInMonths: exp.durationInMonths, jobType: exp.jobType, - location: exp.location, + location: { + connect: { + id: exp.cityId + } + }, title: exp.title, }, }, @@ -1236,7 +1473,6 @@ export const offersProfileRouter = createRouter() create: { durationInMonths: exp.durationInMonths, jobType: exp.jobType, - location: exp.location, title: exp.title, }, }, @@ -1324,12 +1560,20 @@ export const offersProfileRouter = createRouter() await ctx.prisma.offersOffer.update({ data: { comments: offerToUpdate.comments, - companyId: offerToUpdate.companyId, + company: { + connect: { + id: offerToUpdate.companyId + } + }, jobType: offerToUpdate.jobType === JobType.FULLTIME ? JobType.FULLTIME : JobType.INTERN, - location: offerToUpdate.location, + location: { + connect: { + id: offerToUpdate.cityId + } + }, monthYearReceived: offerToUpdate.monthYearReceived, negotiationStrategy: offerToUpdate.negotiationStrategy, }, @@ -1466,7 +1710,11 @@ export const offersProfileRouter = createRouter() }, }, jobType: offerToUpdate.jobType, - location: offerToUpdate.location, + location: { + connect: { + id: offerToUpdate.cityId + } + }, monthYearReceived: offerToUpdate.monthYearReceived, negotiationStrategy: offerToUpdate.negotiationStrategy, offersIntern: { @@ -1520,7 +1768,11 @@ export const offersProfileRouter = createRouter() }, }, jobType: offerToUpdate.jobType, - location: offerToUpdate.location, + location: { + connect: { + id: offerToUpdate.cityId + } + }, monthYearReceived: offerToUpdate.monthYearReceived, negotiationStrategy: offerToUpdate.negotiationStrategy, offersFullTime: { From ac2d047d942613a69bc2d8fbbb98d4a00fc8b172 Mon Sep 17 00:00:00 2001 From: Zhang Ziqing Date: Wed, 2 Nov 2022 17:22:46 +0800 Subject: [PATCH 6/8] [offers][feat] integrate location for offer table and profile --- .../offers/dashboard/DashboardOfferCard.tsx | 2 +- .../components/offers/profile/OfferCard.tsx | 8 +++--- .../components/offers/table/OffersTable.tsx | 9 ++++--- apps/portal/src/components/offers/types.ts | 6 +++-- apps/portal/src/pages/offers/index.tsx | 26 ++++++++++++++++++- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/apps/portal/src/components/offers/dashboard/DashboardOfferCard.tsx b/apps/portal/src/components/offers/dashboard/DashboardOfferCard.tsx index df49ada9..748a4142 100644 --- a/apps/portal/src/components/offers/dashboard/DashboardOfferCard.tsx +++ b/apps/portal/src/components/offers/dashboard/DashboardOfferCard.tsx @@ -36,7 +36,7 @@ export default function DashboardProfileCard({

{location - ? `Company: ${company.name}, ${location}` + ? `Company: ${company.name}, ${location.cityName}` : `Company: ${company.name}`}

{level &&

Level: {level}

} diff --git a/apps/portal/src/components/offers/profile/OfferCard.tsx b/apps/portal/src/components/offers/profile/OfferCard.tsx index 6d02f134..0fcc9823 100644 --- a/apps/portal/src/components/offers/profile/OfferCard.tsx +++ b/apps/portal/src/components/offers/profile/OfferCard.tsx @@ -40,7 +40,7 @@ export default function OfferCard({ - {location ? `${companyName}, ${location}` : companyName} + {location ? `${companyName}, ${location.cityName}` : companyName}
@@ -92,11 +92,11 @@ export default function OfferCard({
)} - {totalCompensation && ( + {(base || stocks || bonus) && totalCompensation && (

- Base / year: {base} ⋅ Stocks / year: {stocks} ⋅ Bonus / year:{' '} - {bonus} + Base / year: {base ?? 'N/A'} ⋅ Stocks / year:{' '} + {stocks ?? 'N/A'} ⋅ Bonus / year: {bonus ?? 'N/A'}

)} diff --git a/apps/portal/src/components/offers/table/OffersTable.tsx b/apps/portal/src/components/offers/table/OffersTable.tsx index 627cb330..9a400b76 100644 --- a/apps/portal/src/components/offers/table/OffersTable.tsx +++ b/apps/portal/src/components/offers/table/OffersTable.tsx @@ -21,10 +21,12 @@ import type { DashboardOffer, GetOffersResponse, Paging } from '~/types/offers'; const NUMBER_OF_OFFERS_IN_PAGE = 10; export type OffersTableProps = Readonly<{ + cityFilter: string; companyFilter: string; jobTitleFilter: string; }>; export default function OffersTable({ + cityFilter, companyFilter, jobTitleFilter, }: OffersTableProps) { @@ -53,10 +55,11 @@ export default function OffersTable({ [ 'offers.list', { + // Location: 'Singapore, Singapore', // TODO: Geolocation + cityId: cityFilter, companyId: companyFilter, currency, limit: NUMBER_OF_OFFERS_IN_PAGE, - location: 'Singapore, Singapore', // TODO: Geolocation offset: pagination.currentPage, sortBy: OfferTableSortBy[selectedFilter] ?? '-monthYearReceived', title: jobTitleFilter, @@ -102,8 +105,8 @@ export default function OffersTable({ ))}
-
- View all offers in +
+ Display offers in setCurrency(value)} selectedCurrency={currency} diff --git a/apps/portal/src/components/offers/types.ts b/apps/portal/src/components/offers/types.ts index 366ca25b..1ee07a15 100644 --- a/apps/portal/src/components/offers/types.ts +++ b/apps/portal/src/components/offers/types.ts @@ -2,6 +2,8 @@ import type { JobType } from '@prisma/client'; import type { MonthYear } from '~/components/shared/MonthYearPicker'; +import type { Location } from '~/types/offers'; + export const HOME_URL = '/offers'; /* @@ -50,7 +52,7 @@ type ExperiencePostData = { id?: string; jobType?: string | null; level?: string | null; - location?: string | null; + location?: Location | null; monthlySalary?: Money | null; title?: string | null; totalCompensation?: Money | null; @@ -132,7 +134,7 @@ export type OfferDisplayData = { jobLevel?: string | null; jobTitle?: string | null; jobType?: JobType; - location?: string | null; + location?: Location | null; monthlySalary?: string | null; negotiationStrategy?: string | null; otherComment?: string | null; diff --git a/apps/portal/src/pages/offers/index.tsx b/apps/portal/src/pages/offers/index.tsx index e696ca10..07bd3f8c 100644 --- a/apps/portal/src/pages/offers/index.tsx +++ b/apps/portal/src/pages/offers/index.tsx @@ -1,5 +1,6 @@ import Link from 'next/link'; import { useState } from 'react'; +import { MapPinIcon } from '@heroicons/react/24/outline'; import { Banner } from '@tih/ui'; import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics'; @@ -7,9 +8,12 @@ import OffersTable from '~/components/offers/table/OffersTable'; import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; import JobTitlesTypeahead from '~/components/shared/JobTitlesTypahead'; +import CitiesTypeahead from '../../components/shared/CitiesTypeahead'; + export default function OffersHomePage() { const [jobTitleFilter, setjobTitleFilter] = useState('software-engineer'); const [companyFilter, setCompanyFilter] = useState(''); + const [cityFilter, setCityFilter] = useState(''); const { event: gaEvent } = useGoogleAnalytics(); return ( @@ -21,6 +25,25 @@ export default function OffersHomePage() { . ⭐ +
+ + + + { + if (option) { + setCityFilter(option.value); + gaEvent({ + action: `offers.table_filter_city_${option.value}`, + category: 'engagement', + label: 'Filter by city', + }); + } + }} + /> +
@@ -58,7 +81,7 @@ export default function OffersHomePage() { if (option) { setCompanyFilter(option.value); gaEvent({ - action: 'offers.table_filter_company', + action: `offers.table_filter_company_${option.value}`, category: 'engagement', label: 'Filter by company', }); @@ -70,6 +93,7 @@ export default function OffersHomePage() {
From d6d25df35b0f453319a32b8fea59127ca29814c2 Mon Sep 17 00:00:00 2001 From: Zhang Ziqing Date: Wed, 2 Nov 2022 18:01:04 +0800 Subject: [PATCH 7/8] [offers][chore] fix import of cities typeahead --- apps/portal/src/pages/offers/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/portal/src/pages/offers/index.tsx b/apps/portal/src/pages/offers/index.tsx index 07bd3f8c..ad0ff41c 100644 --- a/apps/portal/src/pages/offers/index.tsx +++ b/apps/portal/src/pages/offers/index.tsx @@ -5,11 +5,10 @@ import { Banner } from '@tih/ui'; import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics'; import OffersTable from '~/components/offers/table/OffersTable'; +import CitiesTypeahead from '~/components/shared/CitiesTypeahead'; import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; import JobTitlesTypeahead from '~/components/shared/JobTitlesTypahead'; -import CitiesTypeahead from '../../components/shared/CitiesTypeahead'; - export default function OffersHomePage() { const [jobTitleFilter, setjobTitleFilter] = useState('software-engineer'); const [companyFilter, setCompanyFilter] = useState(''); From a31230f7c30a004c34f165390401934af35c681f Mon Sep 17 00:00:00 2001 From: Ai Ling Date: Wed, 2 Nov 2022 19:55:08 +0800 Subject: [PATCH 8/8] [offers][feat] Use city typeahead for location field --- .../portal/src/components/offers/constants.ts | 15 ---- .../offersSubmission/OffersSubmissionForm.tsx | 4 +- .../submissionForm/BackgroundForm.tsx | 53 ++++++++--- .../submissionForm/OfferDetailsForm.tsx | 90 ++++++++++++------- apps/portal/src/components/offers/types.ts | 6 +- .../offers/profile/edit/[offerProfileId].tsx | 6 +- 6 files changed, 110 insertions(+), 64 deletions(-) diff --git a/apps/portal/src/components/offers/constants.ts b/apps/portal/src/components/offers/constants.ts index e2b14d96..d49dca1a 100644 --- a/apps/portal/src/components/offers/constants.ts +++ b/apps/portal/src/components/offers/constants.ts @@ -2,21 +2,6 @@ import { EducationBackgroundType } from './types'; export const emptyOption = '----'; -export const locationOptions = [ - { - label: 'Singapore, Singapore', - value: 'Singapore, Singapore', - }, - { - label: 'New York, US', - value: 'New York, US', - }, - { - label: 'San Francisco, US', - value: 'San Francisco, US', - }, -]; - export const internshipCycleOptions = [ { label: 'Summer', diff --git a/apps/portal/src/components/offers/offersSubmission/OffersSubmissionForm.tsx b/apps/portal/src/components/offers/offersSubmission/OffersSubmissionForm.tsx index 325c9afc..98e9146a 100644 --- a/apps/portal/src/components/offers/offersSubmission/OffersSubmissionForm.tsx +++ b/apps/portal/src/components/offers/offersSubmission/OffersSubmissionForm.tsx @@ -26,11 +26,11 @@ import { getCurrentMonth, getCurrentYear } from '~/utils/offers/time'; import { trpc } from '~/utils/trpc'; const defaultOfferValues = { + cityId: '', comments: '', companyId: '', jobTitle: '', jobType: JobType.FULLTIME, - location: '', monthYearReceived: { month: getCurrentMonth() as Month, year: getCurrentYear(), @@ -277,7 +277,7 @@ export default function OffersSubmissionForm({
{steps[step]} - {/*
{JSON.stringify(formMethods.watch(), null, 2)}
*/} +
{JSON.stringify(formMethods.watch(), null, 2)}
{step === 0 && (
@@ -210,6 +227,12 @@ function InternshipJobFields() { const watchCompanyName = useWatch({ name: 'background.experiences.0.companyName', }); + const watchCityId = useWatch({ + name: 'background.experiences.0.cityId', + }); + const watchCityName = useWatch({ + name: 'background.experiences.0.cityName', + }); return ( <> @@ -271,12 +294,22 @@ function InternshipJobFields() {
- { + if (option) { + setValue('background.experiences.0.cityId', option.value); + setValue('background.experiences.0.cityName', option.label); + } else { + setValue('background.experiences.0.cityId', ''); + setValue('background.experiences.0.cityName', ''); + } + }} />
diff --git a/apps/portal/src/components/offers/offersSubmission/submissionForm/OfferDetailsForm.tsx b/apps/portal/src/components/offers/offersSubmission/submissionForm/OfferDetailsForm.tsx index 63abe7d1..6eed3983 100644 --- a/apps/portal/src/components/offers/offersSubmission/submissionForm/OfferDetailsForm.tsx +++ b/apps/portal/src/components/offers/offersSubmission/submissionForm/OfferDetailsForm.tsx @@ -12,6 +12,7 @@ import { TrashIcon } from '@heroicons/react/24/outline'; import { JobType } from '@prisma/client'; import { Button, Dialog } from '@tih/ui'; +import CitiesTypeahead from '~/components/shared/CitiesTypeahead'; import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; import type { JobTitleType } from '~/components/shared/JobTitles'; import { getLabelForJobTitleType } from '~/components/shared/JobTitles'; @@ -25,7 +26,6 @@ import { emptyOption, FieldError, internshipCycleOptions, - locationOptions, yearOptions, } from '../../constants'; import FormMonthYearPicker from '../../forms/FormMonthYearPicker'; @@ -62,6 +62,12 @@ function FullTimeOfferDetailsForm({ const watchCompanyName = useWatch({ name: `offers.${index}.companyName`, }); + const watchCityId = useWatch({ + name: `offers.${index}.cityId`, + }); + const watchCityName = useWatch({ + name: `offers.${index}.cityName`, + }); const watchCurrency = useWatch({ name: `offers.${index}.offersFullTime.totalCompensation.currency`, }); @@ -104,32 +110,37 @@ function FullTimeOfferDetailsForm({ />
-
- { - if (option) { - setValue(`offers.${index}.companyId`, option.value); - setValue(`offers.${index}.companyName`, option.label); - } - }} - /> -
- { + if (option) { + setValue(`offers.${index}.companyId`, option.value); + setValue(`offers.${index}.companyName`, option.label); + } + }} + /> + { + if (option) { + setValue(`offers.${index}.cityId`, option.value); + setValue(`offers.${index}.cityName`, option.label); + } else { + setValue(`offers.${index}.cityId`, ''); + setValue(`offers.${index}.cityName`, ''); + } + }} />
@@ -305,6 +316,12 @@ function InternshipOfferDetailsForm({ const watchCompanyName = useWatch({ name: `offers.${index}.companyName`, }); + const watchCityId = useWatch({ + name: `offers.${index}.cityId`, + }); + const watchCityName = useWatch({ + name: `offers.${index}.cityName`, + }); return (
@@ -342,16 +359,23 @@ function InternshipOfferDetailsForm({ }} />
- { + if (option) { + setValue(`offers.${index}.cityId`, option.value); + setValue(`offers.${index}.cityName`, option.label); + } else { + setValue(`offers.${index}.cityId`, ''); + setValue(`offers.${index}.cityName`, ''); + } + }} />
diff --git a/apps/portal/src/components/offers/types.ts b/apps/portal/src/components/offers/types.ts index 1ee07a15..0e963a17 100644 --- a/apps/portal/src/components/offers/types.ts +++ b/apps/portal/src/components/offers/types.ts @@ -46,13 +46,14 @@ export type BackgroundPostData = { }; type ExperiencePostData = { + cityId?: string | null; + cityName?: string | null; companyId?: string | null; companyName?: string | null; durationInMonths?: number | null; id?: string; jobType?: string | null; level?: string | null; - location?: Location | null; monthlySalary?: Money | null; title?: string | null; totalCompensation?: Money | null; @@ -77,12 +78,13 @@ type SpecificYoePostData = { type SpecificYoe = SpecificYoePostData; export type OfferPostData = { + cityId: string; + cityName?: string; comments: string; companyId: string; companyName?: string; id?: string; jobType: JobType; - location: string; monthYearReceived: Date; negotiationStrategy: string; offersFullTime?: OfferFullTimePostData | null; diff --git a/apps/portal/src/pages/offers/profile/edit/[offerProfileId].tsx b/apps/portal/src/pages/offers/profile/edit/[offerProfileId].tsx index 05e47b7c..829acb28 100644 --- a/apps/portal/src/pages/offers/profile/edit/[offerProfileId].tsx +++ b/apps/portal/src/pages/offers/profile/edit/[offerProfileId].tsx @@ -36,13 +36,14 @@ export default function OffersEditPage() { experiences.length === 0 ? [{ jobType: JobType.FULLTIME }] : experiences.map((exp) => ({ + cityId: exp.location?.cityId, + cityName: exp.location?.cityName, companyId: exp.company?.id, companyName: exp.company?.name, durationInMonths: exp.durationInMonths, id: exp.id, jobType: exp.jobType, level: exp.level, - location: exp.location, monthlySalary: exp.monthlySalary, title: exp.title, totalCompensation: exp.totalCompensation, @@ -53,12 +54,13 @@ export default function OffersEditPage() { }, id: data.id, offers: data.offers.map((offer) => ({ + cityId: offer.location.cityId, + cityName: offer.location.cityName, comments: offer.comments, companyId: offer.company.id, companyName: offer.company.name, id: offer.id, jobType: offer.jobType, - location: offer.location, monthYearReceived: convertToMonthYear(offer.monthYearReceived), negotiationStrategy: offer.negotiationStrategy, offersFullTime: offer.offersFullTime,