[offers][refactor] add types for interfaces (#390)
* [offers][chore] Create types for API responses * [offers][fix] fix get comments bug * [offers][fix] make offers api open to unauthenticated users * [offers][chore] add return types to comment api * [offers][chore] add types to get comments api * [offers][chore] Refactor profile and analysis APIs to return defined types * [offers][chore] Add typed response for get offers API * [offers][chore] Changed delete offer API response * [offers][fix] Fix type definitions for OffersCompany in types/offers * [offers][fix] fix list some offer frontend Co-authored-by: BryannYeap <e0543723@u.nus.edu> Co-authored-by: Stuart Long Chay Boon <chayboon@gmail.com>pull/391/head
parent
612bef14ad
commit
bc424bee33
@ -0,0 +1,574 @@
|
|||||||
|
import type {
|
||||||
|
Company,
|
||||||
|
OffersAnalysis,
|
||||||
|
OffersBackground,
|
||||||
|
OffersCurrency,
|
||||||
|
OffersEducation,
|
||||||
|
OffersExperience,
|
||||||
|
OffersFullTime,
|
||||||
|
OffersIntern,
|
||||||
|
OffersOffer,
|
||||||
|
OffersProfile,
|
||||||
|
OffersReply,
|
||||||
|
OffersSpecificYoe,
|
||||||
|
User,
|
||||||
|
} from '@prisma/client';
|
||||||
|
import { JobType } from '@prisma/client';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
AddToProfileResponse,
|
||||||
|
Analysis,
|
||||||
|
AnalysisHighestOffer,
|
||||||
|
AnalysisOffer,
|
||||||
|
Background,
|
||||||
|
CreateOfferProfileResponse,
|
||||||
|
DashboardOffer,
|
||||||
|
Education,
|
||||||
|
Experience,
|
||||||
|
GetOffersResponse,
|
||||||
|
OffersCompany,
|
||||||
|
Paging,
|
||||||
|
Profile,
|
||||||
|
ProfileAnalysis,
|
||||||
|
ProfileOffer,
|
||||||
|
SpecificYoe,
|
||||||
|
Valuation,
|
||||||
|
} from '~/types/offers';
|
||||||
|
|
||||||
|
const analysisOfferDtoMapper = (
|
||||||
|
offer: OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & { background: OffersBackground | null };
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
const { background, profileName } = offer.profile;
|
||||||
|
const analysisOfferDto: AnalysisOffer = {
|
||||||
|
company: offersCompanyDtoMapper(offer.company),
|
||||||
|
id: offer.id,
|
||||||
|
income: -1,
|
||||||
|
jobType: offer.jobType,
|
||||||
|
level: offer.OffersFullTime?.level ?? '',
|
||||||
|
location: offer.location,
|
||||||
|
monthYearReceived: offer.monthYearReceived,
|
||||||
|
negotiationStrategy: offer.negotiationStrategy,
|
||||||
|
previousCompanies: [],
|
||||||
|
profileName,
|
||||||
|
specialization:
|
||||||
|
offer.jobType === JobType.FULLTIME
|
||||||
|
? offer.OffersFullTime?.specialization ?? ''
|
||||||
|
: offer.OffersIntern?.specialization ?? '',
|
||||||
|
title:
|
||||||
|
offer.jobType === JobType.FULLTIME
|
||||||
|
? offer.OffersFullTime?.title ?? ''
|
||||||
|
: offer.OffersIntern?.title ?? '',
|
||||||
|
totalYoe: background?.totalYoe ?? -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (offer.OffersFullTime?.totalCompensation) {
|
||||||
|
analysisOfferDto.income = offer.OffersFullTime.totalCompensation.value;
|
||||||
|
} else if (offer.OffersIntern?.monthlySalary) {
|
||||||
|
analysisOfferDto.income = offer.OffersIntern.monthlySalary.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return analysisOfferDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
const analysisDtoMapper = (
|
||||||
|
noOfOffers: number,
|
||||||
|
percentile: number,
|
||||||
|
topPercentileOffers: Array<
|
||||||
|
OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & { background: OffersBackground | null };
|
||||||
|
}
|
||||||
|
>,
|
||||||
|
) => {
|
||||||
|
const analysisDto: Analysis = {
|
||||||
|
noOfOffers,
|
||||||
|
percentile,
|
||||||
|
topPercentileOffers: topPercentileOffers.map((offer) =>
|
||||||
|
analysisOfferDtoMapper(offer),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
return analysisDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
const analysisHighestOfferDtoMapper = (
|
||||||
|
offer: OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & { background: OffersBackground | null };
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
const analysisHighestOfferDto: AnalysisHighestOffer = {
|
||||||
|
company: offersCompanyDtoMapper(offer.company),
|
||||||
|
id: offer.id,
|
||||||
|
level: offer.OffersFullTime?.level ?? '',
|
||||||
|
location: offer.location,
|
||||||
|
specialization:
|
||||||
|
offer.jobType === JobType.FULLTIME
|
||||||
|
? offer.OffersFullTime?.specialization ?? ''
|
||||||
|
: offer.OffersIntern?.specialization ?? '',
|
||||||
|
totalYoe: offer.profile.background?.totalYoe ?? -1,
|
||||||
|
};
|
||||||
|
return analysisHighestOfferDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const profileAnalysisDtoMapper = (
|
||||||
|
analysis:
|
||||||
|
| (OffersAnalysis & {
|
||||||
|
overallHighestOffer: OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern:
|
||||||
|
| (OffersIntern & { monthlySalary: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & { background: OffersBackground | null };
|
||||||
|
};
|
||||||
|
topCompanyOffers: Array<
|
||||||
|
OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern:
|
||||||
|
| (OffersIntern & { monthlySalary: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & {
|
||||||
|
background:
|
||||||
|
| (OffersBackground & {
|
||||||
|
experiences: Array<
|
||||||
|
OffersExperience & { company: Company | null }
|
||||||
|
>;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
topOverallOffers: Array<
|
||||||
|
OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern:
|
||||||
|
| (OffersIntern & { monthlySalary: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & {
|
||||||
|
background:
|
||||||
|
| (OffersBackground & {
|
||||||
|
experiences: Array<
|
||||||
|
OffersExperience & { company: Company | null }
|
||||||
|
>;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
})
|
||||||
|
| null,
|
||||||
|
) => {
|
||||||
|
if (!analysis) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const profileAnalysisDto: ProfileAnalysis = {
|
||||||
|
companyAnalysis: [
|
||||||
|
analysisDtoMapper(
|
||||||
|
analysis.noOfSimilarCompanyOffers,
|
||||||
|
analysis.companyPercentile,
|
||||||
|
analysis.topCompanyOffers,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
id: analysis.id,
|
||||||
|
overallAnalysis: analysisDtoMapper(
|
||||||
|
analysis.noOfSimilarOffers,
|
||||||
|
analysis.overallPercentile,
|
||||||
|
analysis.topOverallOffers,
|
||||||
|
),
|
||||||
|
overallHighestOffer: analysisHighestOfferDtoMapper(
|
||||||
|
analysis.overallHighestOffer,
|
||||||
|
),
|
||||||
|
profileId: analysis.profileId,
|
||||||
|
};
|
||||||
|
return profileAnalysisDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const valuationDtoMapper = (currency: {
|
||||||
|
currency: string;
|
||||||
|
id?: string;
|
||||||
|
value: number;
|
||||||
|
}) => {
|
||||||
|
const valuationDto: Valuation = {
|
||||||
|
currency: currency.currency,
|
||||||
|
value: currency.value,
|
||||||
|
};
|
||||||
|
return valuationDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const offersCompanyDtoMapper = (company: Company) => {
|
||||||
|
const companyDto: OffersCompany = {
|
||||||
|
createdAt: company.createdAt,
|
||||||
|
description: company?.description ?? '',
|
||||||
|
id: company.id,
|
||||||
|
logoUrl: company.logoUrl ?? '',
|
||||||
|
name: company.name,
|
||||||
|
slug: company.slug,
|
||||||
|
updatedAt: company.updatedAt,
|
||||||
|
};
|
||||||
|
return companyDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const educationDtoMapper = (education: {
|
||||||
|
backgroundId?: string;
|
||||||
|
endDate: Date | null;
|
||||||
|
field: string | null;
|
||||||
|
id: string;
|
||||||
|
school: string | null;
|
||||||
|
startDate: Date | null;
|
||||||
|
type: string | null;
|
||||||
|
}) => {
|
||||||
|
const educationDto: Education = {
|
||||||
|
endDate: education.endDate,
|
||||||
|
field: education.field,
|
||||||
|
id: education.id,
|
||||||
|
school: education.school,
|
||||||
|
startDate: education.startDate,
|
||||||
|
type: education.type,
|
||||||
|
};
|
||||||
|
return educationDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const experienceDtoMapper = (
|
||||||
|
experience: OffersExperience & {
|
||||||
|
company: Company | null;
|
||||||
|
monthlySalary: OffersCurrency | null;
|
||||||
|
totalCompensation: OffersCurrency | null;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
const experienceDto: Experience = {
|
||||||
|
company: experience.company
|
||||||
|
? offersCompanyDtoMapper(experience.company)
|
||||||
|
: null,
|
||||||
|
durationInMonths: experience.durationInMonths,
|
||||||
|
id: experience.id,
|
||||||
|
jobType: experience.jobType,
|
||||||
|
level: experience.level,
|
||||||
|
monthlySalary: experience.monthlySalary
|
||||||
|
? valuationDtoMapper(experience.monthlySalary)
|
||||||
|
: experience.monthlySalary,
|
||||||
|
specialization: experience.specialization,
|
||||||
|
title: experience.title,
|
||||||
|
totalCompensation: experience.totalCompensation
|
||||||
|
? valuationDtoMapper(experience.totalCompensation)
|
||||||
|
: experience.totalCompensation,
|
||||||
|
};
|
||||||
|
return experienceDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const specificYoeDtoMapper = (specificYoe: {
|
||||||
|
backgroundId?: string;
|
||||||
|
domain: string;
|
||||||
|
id: string;
|
||||||
|
yoe: number;
|
||||||
|
}) => {
|
||||||
|
const specificYoeDto: SpecificYoe = {
|
||||||
|
domain: specificYoe.domain,
|
||||||
|
id: specificYoe.id,
|
||||||
|
yoe: specificYoe.yoe,
|
||||||
|
};
|
||||||
|
return specificYoeDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const backgroundDtoMapper = (
|
||||||
|
background:
|
||||||
|
| (OffersBackground & {
|
||||||
|
educations: Array<OffersEducation>;
|
||||||
|
experiences: Array<
|
||||||
|
OffersExperience & {
|
||||||
|
company: Company | null;
|
||||||
|
monthlySalary: OffersCurrency | null;
|
||||||
|
totalCompensation: OffersCurrency | null;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
specificYoes: Array<OffersSpecificYoe>;
|
||||||
|
})
|
||||||
|
| null,
|
||||||
|
) => {
|
||||||
|
if (!background) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const educations = background.educations.map((education) =>
|
||||||
|
educationDtoMapper(education),
|
||||||
|
);
|
||||||
|
|
||||||
|
const experiences = background.experiences.map((experience) =>
|
||||||
|
experienceDtoMapper(experience),
|
||||||
|
);
|
||||||
|
|
||||||
|
const specificYoes = background.specificYoes.map((specificYoe) =>
|
||||||
|
specificYoeDtoMapper(specificYoe),
|
||||||
|
);
|
||||||
|
|
||||||
|
const backgroundDto: Background = {
|
||||||
|
educations,
|
||||||
|
experiences,
|
||||||
|
id: background.id,
|
||||||
|
specificYoes,
|
||||||
|
totalYoe: background.totalYoe,
|
||||||
|
};
|
||||||
|
|
||||||
|
return backgroundDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const profileOfferDtoMapper = (
|
||||||
|
offer: OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & {
|
||||||
|
baseSalary: OffersCurrency;
|
||||||
|
bonus: OffersCurrency;
|
||||||
|
stocks: OffersCurrency;
|
||||||
|
totalCompensation: OffersCurrency;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
OffersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null;
|
||||||
|
company: Company;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
const profileOfferDto: ProfileOffer = {
|
||||||
|
comments: offer.comments,
|
||||||
|
company: offersCompanyDtoMapper(offer.company),
|
||||||
|
id: offer.id,
|
||||||
|
jobType: offer.jobType,
|
||||||
|
location: offer.location,
|
||||||
|
monthYearReceived: offer.monthYearReceived,
|
||||||
|
negotiationStrategy: offer.negotiationStrategy,
|
||||||
|
offersFullTime: offer.OffersFullTime,
|
||||||
|
offersIntern: offer.OffersIntern,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (offer.OffersFullTime) {
|
||||||
|
profileOfferDto.offersFullTime = {
|
||||||
|
baseSalary: valuationDtoMapper(offer.OffersFullTime.baseSalary),
|
||||||
|
bonus: valuationDtoMapper(offer.OffersFullTime.bonus),
|
||||||
|
id: offer.OffersFullTime.id,
|
||||||
|
level: offer.OffersFullTime.level,
|
||||||
|
specialization: offer.OffersFullTime.specialization,
|
||||||
|
stocks: valuationDtoMapper(offer.OffersFullTime.stocks),
|
||||||
|
title: offer.OffersFullTime.title,
|
||||||
|
totalCompensation: valuationDtoMapper(
|
||||||
|
offer.OffersFullTime.totalCompensation,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
} else if (offer.OffersIntern) {
|
||||||
|
profileOfferDto.offersIntern = {
|
||||||
|
id: offer.OffersIntern.id,
|
||||||
|
internshipCycle: offer.OffersIntern.internshipCycle,
|
||||||
|
monthlySalary: valuationDtoMapper(offer.OffersIntern.monthlySalary),
|
||||||
|
specialization: offer.OffersIntern.specialization,
|
||||||
|
startYear: offer.OffersIntern.startYear,
|
||||||
|
title: offer.OffersIntern.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return profileOfferDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const profileDtoMapper = (
|
||||||
|
profile: OffersProfile & {
|
||||||
|
analysis:
|
||||||
|
| (OffersAnalysis & {
|
||||||
|
overallHighestOffer: OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern:
|
||||||
|
| (OffersIntern & { monthlySalary: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & { background: OffersBackground | null };
|
||||||
|
};
|
||||||
|
topCompanyOffers: Array<
|
||||||
|
OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern:
|
||||||
|
| (OffersIntern & { monthlySalary: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & {
|
||||||
|
background:
|
||||||
|
| (OffersBackground & {
|
||||||
|
experiences: Array<
|
||||||
|
OffersExperience & { company: Company | null }
|
||||||
|
>;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
topOverallOffers: Array<
|
||||||
|
OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & { totalCompensation: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
OffersIntern:
|
||||||
|
| (OffersIntern & { monthlySalary: OffersCurrency })
|
||||||
|
| null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & {
|
||||||
|
background:
|
||||||
|
| (OffersBackground & {
|
||||||
|
experiences: Array<
|
||||||
|
OffersExperience & { company: Company | null }
|
||||||
|
>;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
background:
|
||||||
|
| (OffersBackground & {
|
||||||
|
educations: Array<OffersEducation>;
|
||||||
|
experiences: Array<
|
||||||
|
OffersExperience & {
|
||||||
|
company: Company | null;
|
||||||
|
monthlySalary: OffersCurrency | null;
|
||||||
|
totalCompensation: OffersCurrency | null;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
specificYoes: Array<OffersSpecificYoe>;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
discussion: Array<
|
||||||
|
OffersReply & {
|
||||||
|
replies: Array<OffersReply>;
|
||||||
|
replyingTo: OffersReply | null;
|
||||||
|
user: User | null;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
offers: Array<
|
||||||
|
OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & {
|
||||||
|
baseSalary: OffersCurrency;
|
||||||
|
bonus: OffersCurrency;
|
||||||
|
stocks: OffersCurrency;
|
||||||
|
totalCompensation: OffersCurrency;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
OffersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null;
|
||||||
|
company: Company;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
},
|
||||||
|
inputToken: string | undefined,
|
||||||
|
) => {
|
||||||
|
const profileDto: Profile = {
|
||||||
|
analysis: profileAnalysisDtoMapper(profile.analysis),
|
||||||
|
background: backgroundDtoMapper(profile.background),
|
||||||
|
editToken: null,
|
||||||
|
id: profile.id,
|
||||||
|
isEditable: false,
|
||||||
|
offers: profile.offers.map((offer) => profileOfferDtoMapper(offer)),
|
||||||
|
profileName: profile.profileName,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (inputToken === profile.editToken) {
|
||||||
|
profileDto.editToken = profile.editToken;
|
||||||
|
profileDto.isEditable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return profileDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createOfferProfileResponseMapper = (
|
||||||
|
profile: { id: string },
|
||||||
|
token: string,
|
||||||
|
) => {
|
||||||
|
const res: CreateOfferProfileResponse = {
|
||||||
|
id: profile.id,
|
||||||
|
token,
|
||||||
|
};
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addToProfileResponseMapper = (updatedProfile: {
|
||||||
|
id: string;
|
||||||
|
profileName: string;
|
||||||
|
userId?: string | null;
|
||||||
|
}) => {
|
||||||
|
const addToProfileResponse: AddToProfileResponse = {
|
||||||
|
id: updatedProfile.id,
|
||||||
|
profileName: updatedProfile.profileName,
|
||||||
|
userId: updatedProfile.userId ?? '',
|
||||||
|
};
|
||||||
|
|
||||||
|
return addToProfileResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const dashboardOfferDtoMapper = (
|
||||||
|
offer: OffersOffer & {
|
||||||
|
OffersFullTime:
|
||||||
|
| (OffersFullTime & {
|
||||||
|
baseSalary: OffersCurrency;
|
||||||
|
bonus: OffersCurrency;
|
||||||
|
stocks: OffersCurrency;
|
||||||
|
totalCompensation: OffersCurrency;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
OffersIntern: (OffersIntern & { monthlySalary: OffersCurrency }) | null;
|
||||||
|
company: Company;
|
||||||
|
profile: OffersProfile & { background: OffersBackground | null };
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
const dashboardOfferDto: DashboardOffer = {
|
||||||
|
company: offersCompanyDtoMapper(offer.company),
|
||||||
|
id: offer.id,
|
||||||
|
income: valuationDtoMapper({ currency: '', value: -1 }),
|
||||||
|
monthYearReceived: offer.monthYearReceived,
|
||||||
|
profileId: offer.profileId,
|
||||||
|
title: offer.OffersFullTime?.title ?? '',
|
||||||
|
totalYoe: offer.profile.background?.totalYoe ?? -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (offer.OffersFullTime) {
|
||||||
|
dashboardOfferDto.income = valuationDtoMapper(
|
||||||
|
offer.OffersFullTime.totalCompensation,
|
||||||
|
);
|
||||||
|
} else if (offer.OffersIntern) {
|
||||||
|
dashboardOfferDto.income = valuationDtoMapper(
|
||||||
|
offer.OffersIntern.monthlySalary,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dashboardOfferDto;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOffersResponseMapper = (
|
||||||
|
data: Array<DashboardOffer>,
|
||||||
|
paging: Paging,
|
||||||
|
) => {
|
||||||
|
const getOffersResponse: GetOffersResponse = {
|
||||||
|
data,
|
||||||
|
paging,
|
||||||
|
};
|
||||||
|
return getOffersResponse;
|
||||||
|
};
|
@ -1,264 +1,329 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import * as trpc from '@trpc/server';
|
import * as trpc from '@trpc/server';
|
||||||
|
|
||||||
import { createProtectedRouter } from '../context';
|
import { createRouter } from '../context';
|
||||||
|
|
||||||
import type { Reply } from '~/types/offers-profile';
|
import type { OffersDiscussion, Reply } from '~/types/offers';
|
||||||
|
|
||||||
|
export const offersCommentsRouter = createRouter()
|
||||||
|
.query('getComments', {
|
||||||
|
input: z.object({
|
||||||
|
profileId: z.string(),
|
||||||
|
}),
|
||||||
|
async resolve({ ctx, input }) {
|
||||||
|
const profile = await ctx.prisma.offersProfile.findFirst({
|
||||||
|
where: {
|
||||||
|
id: input.profileId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const offersCommentsRouter = createProtectedRouter()
|
const result = await ctx.prisma.offersProfile.findFirst({
|
||||||
.query('getComments', {
|
include: {
|
||||||
input: z.object({
|
discussion: {
|
||||||
profileId: z.string()
|
include: {
|
||||||
}),
|
replies: {
|
||||||
async resolve({ ctx, input }) {
|
include: {
|
||||||
|
user: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
replyingTo: true,
|
||||||
|
user: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: input.profileId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const profile = await ctx.prisma.offersProfile.findFirst({
|
const discussions: OffersDiscussion = {
|
||||||
where: {
|
data: result?.discussion
|
||||||
id: input.profileId
|
.filter((x) => {
|
||||||
}
|
return x.replyingToId === null
|
||||||
})
|
})
|
||||||
|
.map((x) => {
|
||||||
|
if (x.user == null) {
|
||||||
|
x.user = {
|
||||||
|
email: '',
|
||||||
|
emailVerified: null,
|
||||||
|
id: '',
|
||||||
|
image: '',
|
||||||
|
name: profile?.profileName ?? '<missing name>',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const result = await ctx.prisma.offersProfile.findFirst({
|
x.replies?.map((y) => {
|
||||||
include: {
|
if (y.user == null) {
|
||||||
discussion: {
|
y.user = {
|
||||||
include: {
|
email: '',
|
||||||
replies: {
|
emailVerified: null,
|
||||||
include: {
|
id: '',
|
||||||
user: true
|
image: '',
|
||||||
}
|
name: profile?.profileName ?? '<missing name>',
|
||||||
},
|
};
|
||||||
replyingTo: true,
|
|
||||||
user: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
id: input.profileId
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
if (result) {
|
const replyType: Reply = {
|
||||||
return result.discussion
|
createdAt: x.createdAt,
|
||||||
.filter((x: Reply) => x.replyingToId === null)
|
id: x.id,
|
||||||
.map((x: Reply) => {
|
message: x.message,
|
||||||
if (x.user == null) {
|
replies: x.replies.map((reply) => {
|
||||||
x.user = {
|
return {
|
||||||
email: "",
|
createdAt: reply.createdAt,
|
||||||
emailVerified: null,
|
id: reply.id,
|
||||||
id: "",
|
message: reply.message,
|
||||||
image: "",
|
replies: [],
|
||||||
name: profile?.profileName ?? "<missing name>"
|
replyingToId: reply.replyingToId,
|
||||||
}
|
user: reply.user
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
replyingToId: x.replyingToId,
|
||||||
|
user: x.user
|
||||||
|
}
|
||||||
|
|
||||||
x.replies?.map((y) => {
|
return replyType
|
||||||
if (y.user == null) {
|
}) ?? []
|
||||||
y.user = {
|
}
|
||||||
email: "",
|
|
||||||
emailVerified: null,
|
|
||||||
id: "",
|
|
||||||
image: "",
|
|
||||||
name: profile?.profileName ?? "<missing name>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return x;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
return discussions
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.mutation("create", {
|
.mutation('create', {
|
||||||
input: z.object({
|
input: z.object({
|
||||||
message: z.string(),
|
message: z.string(),
|
||||||
profileId: z.string(),
|
profileId: z.string(),
|
||||||
replyingToId: z.string().optional(),
|
replyingToId: z.string().optional(),
|
||||||
userId: z.string().optional()
|
token: z.string().optional(),
|
||||||
}),
|
userId: z.string().optional()
|
||||||
async resolve({ ctx, input }) {
|
}),
|
||||||
const createdReply = await ctx.prisma.offersReply.create({
|
async resolve({ ctx, input }) {
|
||||||
data: {
|
const profile = await ctx.prisma.offersProfile.findFirst({
|
||||||
message: input.message,
|
where: {
|
||||||
profile: {
|
id: input.profileId,
|
||||||
connect: {
|
},
|
||||||
id: input.profileId
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (input.replyingToId) {
|
const profileEditToken = profile?.editToken;
|
||||||
await ctx.prisma.offersReply.update({
|
|
||||||
data: {
|
|
||||||
replyingTo: {
|
|
||||||
connect: {
|
|
||||||
id: input.replyingToId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
id: createdReply.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.userId) {
|
if (input.token === profileEditToken || input.userId) {
|
||||||
await ctx.prisma.offersReply.update({
|
const createdReply = await ctx.prisma.offersReply.create({
|
||||||
data: {
|
data: {
|
||||||
user: {
|
message: input.message,
|
||||||
connect: {
|
profile: {
|
||||||
id: input.userId
|
connect: {
|
||||||
}
|
id: input.profileId,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
where: {
|
},
|
||||||
id: createdReply.id
|
});
|
||||||
}
|
|
||||||
})
|
if (input.replyingToId) {
|
||||||
}
|
await ctx.prisma.offersReply.update({
|
||||||
// Get replies
|
data: {
|
||||||
const result = await ctx.prisma.offersProfile.findFirst({
|
replyingTo: {
|
||||||
include: {
|
connect: {
|
||||||
discussion: {
|
id: input.replyingToId,
|
||||||
include: {
|
|
||||||
replies: true,
|
|
||||||
replyingTo: true,
|
|
||||||
user: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
where: {
|
},
|
||||||
id: input.profileId
|
},
|
||||||
}
|
where: {
|
||||||
})
|
id: createdReply.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (result) {
|
if (input.userId) {
|
||||||
return result.discussion.filter((x) => x.replyingToId === null)
|
await ctx.prisma.offersReply.update({
|
||||||
}
|
data: {
|
||||||
|
user: {
|
||||||
|
connect: {
|
||||||
|
id: input.userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: createdReply.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const created = await ctx.prisma.offersReply.findFirst({
|
||||||
|
include: {
|
||||||
|
user: true
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: createdReply.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return result
|
const result: Reply = {
|
||||||
|
createdAt: created!.createdAt,
|
||||||
|
id: created!.id,
|
||||||
|
message: created!.message,
|
||||||
|
replies: [], // New message should have no replies
|
||||||
|
replyingToId: created!.replyingToId,
|
||||||
|
user: created!.user ?? {
|
||||||
|
email: '',
|
||||||
|
emailVerified: null,
|
||||||
|
id: '',
|
||||||
|
image: '',
|
||||||
|
name: profile?.profileName ?? '<missing name>',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.mutation("update", {
|
|
||||||
input: z.object({
|
|
||||||
id: z.string(),
|
|
||||||
message: z.string(),
|
|
||||||
profileId: z.string(),
|
|
||||||
// Have to pass in either userID or token for validation
|
|
||||||
token: z.string().optional(),
|
|
||||||
userId: z.string().optional(),
|
|
||||||
}),
|
|
||||||
async resolve({ ctx, input }) {
|
|
||||||
const messageToUpdate = await ctx.prisma.offersReply.findFirst({
|
|
||||||
where: {
|
|
||||||
id: input.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const profile = await ctx.prisma.offersProfile.findFirst({
|
|
||||||
where: {
|
|
||||||
id: input.profileId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const profileEditToken = profile?.editToken;
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// To validate user editing, OP or correct user
|
throw new trpc.TRPCError({
|
||||||
// TODO: improve validation process
|
code: 'UNAUTHORIZED',
|
||||||
if (profileEditToken === input.token || messageToUpdate?.userId === input.userId) {
|
message: 'Missing userId or wrong token.',
|
||||||
await ctx.prisma.offersReply.update({
|
});
|
||||||
data: {
|
},
|
||||||
message: input.message
|
})
|
||||||
},
|
.mutation('update', {
|
||||||
where: {
|
input: z.object({
|
||||||
id: input.id
|
id: z.string(),
|
||||||
}
|
message: z.string(),
|
||||||
})
|
profileId: z.string(),
|
||||||
|
// Have to pass in either userID or token for validation
|
||||||
|
token: z.string().optional(),
|
||||||
|
userId: z.string().optional(),
|
||||||
|
}),
|
||||||
|
async resolve({ ctx, input }) {
|
||||||
|
const messageToUpdate = await ctx.prisma.offersReply.findFirst({
|
||||||
|
where: {
|
||||||
|
id: input.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const profile = await ctx.prisma.offersProfile.findFirst({
|
||||||
|
where: {
|
||||||
|
id: input.profileId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const result = await ctx.prisma.offersProfile.findFirst({
|
const profileEditToken = profile?.editToken;
|
||||||
include: {
|
|
||||||
discussion: {
|
|
||||||
include: {
|
|
||||||
replies: true,
|
|
||||||
replyingTo: true,
|
|
||||||
user: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
id: input.profileId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (result) {
|
// To validate user editing, OP or correct user
|
||||||
return result.discussion.filter((x) => x.replyingToId === null)
|
// TODO: improve validation process
|
||||||
}
|
if (
|
||||||
|
profileEditToken === input.token ||
|
||||||
|
messageToUpdate?.userId === input.userId
|
||||||
|
) {
|
||||||
|
const updated = await ctx.prisma.offersReply.update({
|
||||||
|
data: {
|
||||||
|
message: input.message,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
replies: {
|
||||||
|
include: {
|
||||||
|
user: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
user: true
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: input.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return result
|
const result: Reply = {
|
||||||
|
createdAt: updated!.createdAt,
|
||||||
|
id: updated!.id,
|
||||||
|
message: updated!.message,
|
||||||
|
replies: updated!.replies.map((x) => {
|
||||||
|
return {
|
||||||
|
createdAt: x.createdAt,
|
||||||
|
id: x.id,
|
||||||
|
message: x.message,
|
||||||
|
replies: [],
|
||||||
|
replyingToId: x.replyingToId,
|
||||||
|
user: x.user ?? {
|
||||||
|
email: '',
|
||||||
|
emailVerified: null,
|
||||||
|
id: '',
|
||||||
|
image: '',
|
||||||
|
name: profile?.profileName ?? '<missing name>',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
throw new trpc.TRPCError({
|
replyingToId: updated!.replyingToId,
|
||||||
code: 'UNAUTHORIZED',
|
user: updated!.user ?? {
|
||||||
message: 'Wrong userId or token.'
|
email: '',
|
||||||
})
|
emailVerified: null,
|
||||||
|
id: '',
|
||||||
|
image: '',
|
||||||
|
name: profile?.profileName ?? '<missing name>',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.mutation("delete", {
|
|
||||||
input: z.object({
|
|
||||||
id: z.string(),
|
|
||||||
profileId: z.string(),
|
|
||||||
// Have to pass in either userID or token for validation
|
|
||||||
token: z.string().optional(),
|
|
||||||
userId: z.string().optional(),
|
|
||||||
}),
|
|
||||||
async resolve({ ctx, input }) {
|
|
||||||
const messageToDelete = await ctx.prisma.offersReply.findFirst({
|
|
||||||
where: {
|
|
||||||
id: input.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const profile = await ctx.prisma.offersProfile.findFirst({
|
|
||||||
where: {
|
|
||||||
id: input.profileId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const profileEditToken = profile?.editToken;
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// To validate user editing, OP or correct user
|
throw new trpc.TRPCError({
|
||||||
// TODO: improve validation process
|
code: 'UNAUTHORIZED',
|
||||||
if (profileEditToken === input.token || messageToDelete?.userId === input.userId) {
|
message: 'Wrong userId or token.',
|
||||||
await ctx.prisma.offersReply.delete({
|
});
|
||||||
where: {
|
},
|
||||||
id: input.id
|
})
|
||||||
}
|
.mutation('delete', {
|
||||||
})
|
input: z.object({
|
||||||
const result = await ctx.prisma.offersProfile.findFirst({
|
id: z.string(),
|
||||||
include: {
|
profileId: z.string(),
|
||||||
discussion: {
|
// Have to pass in either userID or token for validation
|
||||||
include: {
|
token: z.string().optional(),
|
||||||
replies: true,
|
userId: z.string().optional(),
|
||||||
replyingTo: true,
|
}),
|
||||||
user: true
|
async resolve({ ctx, input }) {
|
||||||
}
|
const messageToDelete = await ctx.prisma.offersReply.findFirst({
|
||||||
}
|
where: {
|
||||||
},
|
id: input.id,
|
||||||
where: {
|
},
|
||||||
id: input.profileId
|
});
|
||||||
}
|
const profile = await ctx.prisma.offersProfile.findFirst({
|
||||||
})
|
where: {
|
||||||
|
id: input.profileId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (result) {
|
const profileEditToken = profile?.editToken;
|
||||||
return result.discussion.filter((x) => x.replyingToId === null)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
// To validate user editing, OP or correct user
|
||||||
}
|
// TODO: improve validation process
|
||||||
|
if (
|
||||||
|
profileEditToken === input.token ||
|
||||||
|
messageToDelete?.userId === input.userId
|
||||||
|
) {
|
||||||
|
await ctx.prisma.offersReply.delete({
|
||||||
|
where: {
|
||||||
|
id: input.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await ctx.prisma.offersProfile.findFirst({
|
||||||
|
include: {
|
||||||
|
discussion: {
|
||||||
|
include: {
|
||||||
|
replies: true,
|
||||||
|
replyingTo: true,
|
||||||
|
user: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: input.profileId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
throw new trpc.TRPCError({
|
// If (result) {
|
||||||
code: 'UNAUTHORIZED',
|
// return result.discussion.filter((x) => x.replyingToId === null);
|
||||||
message: 'Wrong userId or token.'
|
// }
|
||||||
})
|
|
||||||
}
|
// return result;
|
||||||
})
|
}
|
||||||
|
|
||||||
|
throw new trpc.TRPCError({
|
||||||
|
code: 'UNAUTHORIZED',
|
||||||
|
message: 'Wrong userId or token.',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
export type OffersProfile = {
|
|
||||||
background?: Background | null;
|
|
||||||
createdAt: Date;
|
|
||||||
// Discussions: Array<discussion>;
|
|
||||||
editToken: string;
|
|
||||||
id: string;
|
|
||||||
offers: Array<Offer>;
|
|
||||||
profileName: string;
|
|
||||||
userId?: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Background = {
|
|
||||||
educations: Array<Education>;
|
|
||||||
experiences: Array<Experience>;
|
|
||||||
id: string;
|
|
||||||
offersProfileId: string;
|
|
||||||
specificYoes: Array<SpecificYoe>;
|
|
||||||
totalYoe?: number | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Experience = {
|
|
||||||
backgroundId: string;
|
|
||||||
company?: Company | null;
|
|
||||||
companyId?: string | null;
|
|
||||||
durationInMonths?: number | null;
|
|
||||||
id: string;
|
|
||||||
jobType?: string | null;
|
|
||||||
level?: string | null;
|
|
||||||
monthlySalary?: Valuation | null;
|
|
||||||
monthlySalaryId?: string | null;
|
|
||||||
specialization?: string | null;
|
|
||||||
title?: string | null;
|
|
||||||
totalCompensation?: Valuation | null;
|
|
||||||
totalCompensationId?: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Company = {
|
|
||||||
createdAt: Date;
|
|
||||||
description: string | null;
|
|
||||||
id: string;
|
|
||||||
logoUrl: string | null;
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
updatedAt: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Valuation = {
|
|
||||||
currency: string;
|
|
||||||
id: string;
|
|
||||||
value: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Education = {
|
|
||||||
backgroundId: string;
|
|
||||||
endDate?: Date | null;
|
|
||||||
field?: string | null;
|
|
||||||
id: string;
|
|
||||||
school?: string | null;
|
|
||||||
startDate?: Date | null;
|
|
||||||
type?: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SpecificYoe = {
|
|
||||||
backgroundId: string;
|
|
||||||
domain: string;
|
|
||||||
id: string;
|
|
||||||
yoe: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Offer = {
|
|
||||||
OfferFullTime?: OfferFullTime | null;
|
|
||||||
OfferIntern?: OfferIntern | null;
|
|
||||||
comments?: string | null;
|
|
||||||
company: Company;
|
|
||||||
companyId: string;
|
|
||||||
id: string;
|
|
||||||
jobType: string;
|
|
||||||
location: string;
|
|
||||||
monthYearReceived: Date;
|
|
||||||
negotiationStrategy?: string | null;
|
|
||||||
offersFullTimeId?: string | null;
|
|
||||||
offersInternId?: string | null;
|
|
||||||
profileId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OfferFullTime = {
|
|
||||||
baseSalary: Valuation;
|
|
||||||
baseSalaryId: string;
|
|
||||||
bonus: Valuation;
|
|
||||||
bonusId: string;
|
|
||||||
id: string;
|
|
||||||
level: string;
|
|
||||||
specialization: string;
|
|
||||||
stocks: Valuation;
|
|
||||||
stocksId: string;
|
|
||||||
title?: string;
|
|
||||||
totalCompensation: Valuation;
|
|
||||||
totalCompensationId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OfferIntern = {
|
|
||||||
id: string;
|
|
||||||
internshipCycle: string;
|
|
||||||
monthlySalary: Valuation;
|
|
||||||
monthlySalaryId: string;
|
|
||||||
specialization: string;
|
|
||||||
startYear: number;
|
|
||||||
title?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Reply = {
|
|
||||||
createdAt: Date;
|
|
||||||
id: string;
|
|
||||||
message: string;
|
|
||||||
// Profile: OffersProfile | null;
|
|
||||||
profileId: string;
|
|
||||||
replies: Array<Discussion>?;
|
|
||||||
replyingTo: Discussion?;
|
|
||||||
replyingToId: string | null;
|
|
||||||
user: User?;
|
|
||||||
userId: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type User = {
|
|
||||||
email: string?;
|
|
||||||
emailVerified: Date?;
|
|
||||||
id: string;
|
|
||||||
image: string?;
|
|
||||||
name: string?;
|
|
||||||
}
|
|
@ -0,0 +1,186 @@
|
|||||||
|
import type { JobType } from '@prisma/client';
|
||||||
|
|
||||||
|
export type Profile = {
|
||||||
|
analysis: ProfileAnalysis?;
|
||||||
|
background: Background?;
|
||||||
|
editToken: string?;
|
||||||
|
id: string;
|
||||||
|
isEditable: boolean;
|
||||||
|
offers: Array<ProfileOffer>;
|
||||||
|
profileName: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Background = {
|
||||||
|
educations: Array<Education>;
|
||||||
|
experiences: Array<Experience>;
|
||||||
|
id: string;
|
||||||
|
specificYoes: Array<SpecificYoe>;
|
||||||
|
totalYoe: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Experience = {
|
||||||
|
company: OffersCompany?;
|
||||||
|
durationInMonths: number?;
|
||||||
|
id: string;
|
||||||
|
jobType: JobType?;
|
||||||
|
level: string?;
|
||||||
|
monthlySalary: Valuation?;
|
||||||
|
specialization: string?;
|
||||||
|
title: string?;
|
||||||
|
totalCompensation: Valuation?;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OffersCompany = {
|
||||||
|
createdAt: Date;
|
||||||
|
description: string;
|
||||||
|
id: string;
|
||||||
|
logoUrl: string;
|
||||||
|
name: string;
|
||||||
|
slug: string;
|
||||||
|
updatedAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Valuation = {
|
||||||
|
currency: string;
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Education = {
|
||||||
|
endDate: Date?;
|
||||||
|
field: string?;
|
||||||
|
id: string;
|
||||||
|
school: string?;
|
||||||
|
startDate: Date?;
|
||||||
|
type: string?;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SpecificYoe = {
|
||||||
|
domain: string;
|
||||||
|
id: string;
|
||||||
|
yoe: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DashboardOffer = {
|
||||||
|
company: OffersCompany;
|
||||||
|
id: string;
|
||||||
|
income: Valuation;
|
||||||
|
monthYearReceived: Date;
|
||||||
|
profileId: string;
|
||||||
|
title: string;
|
||||||
|
totalYoe: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ProfileOffer = {
|
||||||
|
comments: string;
|
||||||
|
company: OffersCompany;
|
||||||
|
id: string;
|
||||||
|
jobType: JobType;
|
||||||
|
location: string;
|
||||||
|
monthYearReceived: Date;
|
||||||
|
negotiationStrategy: string;
|
||||||
|
offersFullTime: FullTime?;
|
||||||
|
offersIntern: Intern?;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FullTime = {
|
||||||
|
baseSalary: Valuation;
|
||||||
|
bonus: Valuation;
|
||||||
|
id: string;
|
||||||
|
level: string;
|
||||||
|
specialization: string;
|
||||||
|
stocks: Valuation;
|
||||||
|
title: string;
|
||||||
|
totalCompensation: Valuation;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Intern = {
|
||||||
|
id: string;
|
||||||
|
internshipCycle: string;
|
||||||
|
monthlySalary: Valuation;
|
||||||
|
specialization: string;
|
||||||
|
startYear: number;
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Reply = {
|
||||||
|
createdAt: Date;
|
||||||
|
id: string;
|
||||||
|
message: string;
|
||||||
|
replies: Array<Reply>?;
|
||||||
|
replyingToId: string?;
|
||||||
|
user: User?;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type User = {
|
||||||
|
email: string?;
|
||||||
|
emailVerified: Date?;
|
||||||
|
id: string;
|
||||||
|
image: string?;
|
||||||
|
name: string?;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetOffersResponse = {
|
||||||
|
data: Array<DashboardOffer>;
|
||||||
|
paging: Paging;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Paging = {
|
||||||
|
currentPage: number;
|
||||||
|
numOfItems: number;
|
||||||
|
numOfPages: number;
|
||||||
|
totalItems: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateOfferProfileResponse = {
|
||||||
|
id: string;
|
||||||
|
token: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OffersDiscussion = {
|
||||||
|
data: Array<Reply>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ProfileAnalysis = {
|
||||||
|
companyAnalysis: Array<Analysis>;
|
||||||
|
id: string;
|
||||||
|
overallAnalysis: Analysis;
|
||||||
|
overallHighestOffer: AnalysisHighestOffer;
|
||||||
|
profileId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Analysis = {
|
||||||
|
noOfOffers: number;
|
||||||
|
percentile: number;
|
||||||
|
topPercentileOffers: Array<AnalysisOffer>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AnalysisHighestOffer = {
|
||||||
|
company: OffersCompany;
|
||||||
|
id: string;
|
||||||
|
level: string;
|
||||||
|
location: string;
|
||||||
|
specialization: string;
|
||||||
|
totalYoe: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AnalysisOffer = {
|
||||||
|
company: OffersCompany;
|
||||||
|
id: string;
|
||||||
|
income: number;
|
||||||
|
jobType: JobType;
|
||||||
|
level: string;
|
||||||
|
location: string;
|
||||||
|
monthYearReceived: Date;
|
||||||
|
negotiationStrategy: string;
|
||||||
|
previousCompanies: Array<string>;
|
||||||
|
profileName: string;
|
||||||
|
specialization: string;
|
||||||
|
title: string;
|
||||||
|
totalYoe: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddToProfileResponse = {
|
||||||
|
id: string;
|
||||||
|
profileName: string;
|
||||||
|
userId: string;
|
||||||
|
};
|
Loading…
Reference in new issue