From 1c26a5fb2f924bcc9f18eb1d500adf6999ec0df9 Mon Sep 17 00:00:00 2001 From: PaulEntourage Date: Wed, 26 Jul 2023 12:14:25 +0200 Subject: [PATCH 1/2] [EN-6274] feat(cv): integration page CV --- .lintstagedrc.js | 2 +- package.json | 1 + src/api/api.ts | 2 +- src/api/types.ts | 5 +++ .../{CVPageContent.js => CVPageContent.tsx} | 43 ++++++++++++------- ...EditCareerPath.js => CVEditCareerPath.tsx} | 25 ++++++++++- src/components/cv/CVFiche.tsx | 17 +++++--- .../{CVFicheEdition.js => CVFicheEdition.tsx} | 34 ++++++--------- .../HeaderConnectedContent/ImgProfile.tsx | 12 +----- .../CarouselSwiper/swiper-augmentation.d.ts | 14 ++++++ tsconfig.json | 2 +- yarn.lock | 5 +++ 12 files changed, 105 insertions(+), 57 deletions(-) rename src/components/backoffice/cv/{CVPageContent.js => CVPageContent.tsx} (93%) rename src/components/cv/{CVEditCareerPath.js => CVEditCareerPath.tsx} (91%) rename src/components/cv/{CVFicheEdition.js => CVFicheEdition.tsx} (91%) create mode 100644 src/components/utils/CarouselSwiper/swiper-augmentation.d.ts diff --git a/.lintstagedrc.js b/.lintstagedrc.js index 09284031b..b10c16341 100644 --- a/.lintstagedrc.js +++ b/.lintstagedrc.js @@ -1,4 +1,4 @@ module.exports = { - '*.ts?(x)': 'yarn lint:fix', + '*.ts?(x)': ['yarn tsc-files', 'yarn lint:fix'], '*.js?(x)': 'yarn lint:fix', }; diff --git a/package.json b/package.json index 664822938..af03b0765 100755 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "lint": "npx eslint src --ext js,jsx,ts,tsx", "lint:fix": "npx eslint src --ext js,jsx,ts,tsx --fix", "ts-check": "tsc -p tsconfig.json --noEmit", + "ts-check:hook": "tsc tsconfig.json --noEmit", "format": "prettier --write './**/*.{js,jsx,md,json,ts,tsx}' --config .prettierrc.json", "build": "next build", "uikit-install": "cd ./node_modules/uikit && yarn", diff --git a/src/api/api.ts b/src/api/api.ts index 15a462bf9..e21587bb0 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -190,7 +190,7 @@ export class APIHandler { // put - putUser(userId: string, params: UserDto): Promise { + putUser(userId: string, params: Partial): Promise { return this.put(`/user/${userId}`, params); } diff --git a/src/api/types.ts b/src/api/types.ts index eef5119ac..9e00bb2d1 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -83,6 +83,10 @@ export type User = { }; export interface CV { + id?: string; + version: string; + profileImage: string; + profileImageObjectUrl: string; user: { candidat: { firstName: string; @@ -136,6 +140,7 @@ export interface CV { }[]; experiences: { description: string; + order: number; skills: { id: string; name: string; diff --git a/src/components/backoffice/cv/CVPageContent.js b/src/components/backoffice/cv/CVPageContent.tsx similarity index 93% rename from src/components/backoffice/cv/CVPageContent.js rename to src/components/backoffice/cv/CVPageContent.tsx index f150dc48d..f7674a18d 100644 --- a/src/components/backoffice/cv/CVPageContent.js +++ b/src/components/backoffice/cv/CVPageContent.tsx @@ -5,6 +5,7 @@ import React, { useCallback, useContext, useEffect, useState } from 'react'; import UIkit from 'uikit'; import { Api } from 'src/api'; +import { CV, User } from 'src/api/types'; import { ButtonDownload } from 'src/components/backoffice/cv/ButtonDownload'; import { ButtonPost } from 'src/components/backoffice/cv/ButtonPost'; import { NoCV } from 'src/components/backoffice/cv/NoCV'; @@ -29,7 +30,12 @@ const pusher = new Pusher(process.env.PUSHER_API_KEY, { forceTLS: true, }); -const ModalPreview = ({ imageUrl, cv }) => { +interface ModalPreviewProps { + imageUrl: string; + cv: CV; +} + +const ModalPreview = ({ imageUrl, cv }: ModalPreviewProps) => { const { onClose } = useModalContext(); return ( @@ -49,18 +55,23 @@ const ModalPreview = ({ imageUrl, cv }) => { ); }; -ModalPreview.propTypes = { - cv: CVShape.isRequired, - imageUrl: PropTypes.string.isRequired, -}; - -export const CVPageContent = ({ candidateId, cv, setCV }) => { - const [cvVersion, setCvVersion] = useState(undefined); - const [imageUrl, setImageUrl] = useState(undefined); +interface CVPageContentProps { + cv: CV; + candidateId: string; + setCV: (arg1: any) => void; +} + +export const CVPageContent = ({ + candidateId, + cv, + setCV, +}: CVPageContentProps) => { + const [cvVersion, setCvVersion] = useState(); + const [imageUrl, setImageUrl] = useState(); const [previewGenerating, setPreviewGenerating] = useState(false); const [pdfGenerating, setPdfGenerating] = useState(false); - const { user } = useContext(UserContext); + const { user } = useContext<{ user: User }>(UserContext); const prevCV = usePrevious(cv); @@ -155,25 +166,25 @@ export const CVPageContent = ({ candidateId, cv, setCV }) => { }; Api.putUser(candidateId, userData) - .then(({ newUserData }) => { - res(newUserData); + .then((data) => { + res(data); }) .catch((err) => { rej(err); }); } else { - res(); + res(null); } }); }; const checkIfLastVersion = useCallback( - async (callback, isAutoSave) => { + async (callback, isAutoSave = false) => { const { data: { lastCvVersion }, } = await Api.getCVLastVersion(candidateId); - if (lastCvVersion > cvVersion) { + if (cvVersion && lastCvVersion > cvVersion) { if (!isAutoSave) { openModal( { }; delete obj.id; formData.append('cv', JSON.stringify(obj)); - formData.append('autoSave', true); + formData.append('autoSave', ''); // post return saveUserData(obj) .then(() => { diff --git a/src/components/cv/CVEditCareerPath.js b/src/components/cv/CVEditCareerPath.tsx similarity index 91% rename from src/components/cv/CVEditCareerPath.js rename to src/components/cv/CVEditCareerPath.tsx index db9a70fad..72b36ed59 100644 --- a/src/components/cv/CVEditCareerPath.js +++ b/src/components/cv/CVEditCareerPath.tsx @@ -5,10 +5,31 @@ import { formEditCareerPath } from 'src/components/forms/schema/formEditCareerPa import { openModal } from 'src/components/modals/Modal'; import { ModalEdit } from 'src/components/modals/Modal/ModalGeneric/ModalEdit'; import { ButtonIcon, Grid } from 'src/components/utils'; -import { AMBITIONS_PREFIXES, BUSINESS_LINES } from 'src/constants'; +import { + AMBITIONS_PREFIXES, + AmbitionsPrefixesType, + BUSINESS_LINES, +} from 'src/constants'; import { findConstantFromValue, sortByOrder } from 'src/utils'; -export const CVEditCareerPath = ({ ambitions, businessLines, onChange }) => { +interface CVEditCareerPath { + ambitions: { + order: number; + name: string; + prefix: AmbitionsPrefixesType; + }[]; + businessLines: { + order: number; + name: string; + }[]; + onChange: (arg1: any) => void; +} + +export const CVEditCareerPath = ({ + ambitions, + businessLines, + onChange, +}: CVEditCareerPath) => { const sortedAmbitions = ambitions && ambitions.length > 0 ? sortByOrder(ambitions) : null; diff --git a/src/components/cv/CVFiche.tsx b/src/components/cv/CVFiche.tsx index baf03e7b8..03dd65245 100644 --- a/src/components/cv/CVFiche.tsx +++ b/src/components/cv/CVFiche.tsx @@ -1,7 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { v4 as uuid } from 'uuid'; +import { CV } from 'src/api/types'; import { CVCareerPathSentence } from 'src/components/cv/CVCareerPathSentence'; -import { CVCallToActions } from 'src/components/partials/CV/CVCallToActions'; import { Grid, Img, SimpleLink, Icon } from 'src/components/utils'; import { CONTRACTS } from 'src/constants'; import { DEPARTMENTS_FILTERS } from 'src/constants/departements'; @@ -14,12 +15,18 @@ import { } from 'src/utils'; import { CVShape } from './CV.shape'; +const uuidValue = uuid(); + /** * Le cv en public et en preview */ -export const CVFiche = ({ cv, actionDisabled }) => { - const updateSharesCount = useUpdateSharesCount(); +interface CVFicheProps { + cv: CV; + actionDisabled?: boolean; +} + +export const CVFiche = ({ cv, actionDisabled }: CVFicheProps) => { const experiences = cv.experiences && cv.experiences.length > 0 ? sortByOrder(cv.experiences) @@ -285,7 +292,7 @@ export const CVFiche = ({ cv, actionDisabled }) => {
    {cv.skills.map(({ name }, i) => { return ( -
  • +
  • {name}
  • ); @@ -300,7 +307,7 @@ export const CVFiche = ({ cv, actionDisabled }) => {
      {cv.passions.map(({ name }, i) => { return ( -
    • +
    • {name}
    • ); diff --git a/src/components/cv/CVFicheEdition.js b/src/components/cv/CVFicheEdition.tsx similarity index 91% rename from src/components/cv/CVFicheEdition.js rename to src/components/cv/CVFicheEdition.tsx index 0719047ba..e2590997e 100644 --- a/src/components/cv/CVFicheEdition.js +++ b/src/components/cv/CVFicheEdition.tsx @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React, { useCallback, useEffect, useState } from 'react'; +import { CV } from 'src/api/types'; import { ExperiencesProfileCard, InfoProfileCard, @@ -15,7 +16,17 @@ import { Grid, Img } from 'src/components/utils'; import { CV_STATUS } from 'src/constants'; import { useMount, usePrevious } from 'src/hooks/utils'; -import { CVShape } from './CV.shape'; + +interface VFicheEditionProps { + cv: CV; + onChange?: (arg1: any) => void; + disablePicture?: boolean; + email: string; + phone?: string; + previewGenerating: boolean; + address: string; + userZone: string; +} export const CVFicheEdition = ({ cv, @@ -26,7 +37,7 @@ export const CVFicheEdition = ({ phone, address, userZone, -}) => { +}: VFicheEditionProps) => { const [previewUrl, setPreviewUrl] = useState(undefined); const [imageUrl, setImageUrl] = useState(undefined); @@ -151,22 +162,3 @@ export const CVFicheEdition = ({ ); }; - -CVFicheEdition.propTypes = { - cv: CVShape.isRequired, - onChange: PropTypes.func, - disablePicture: PropTypes.bool, - email: PropTypes.string.isRequired, - phone: PropTypes.string, - address: PropTypes.string, - previewGenerating: PropTypes.bool.isRequired, - userZone: PropTypes.string, -}; - -CVFicheEdition.defaultProps = { - onChange: () => {}, - disablePicture: false, - phone: undefined, - address: undefined, - userZone: undefined, -}; diff --git a/src/components/headers/HeaderConnected/HeaderConnectedContent/ImgProfile.tsx b/src/components/headers/HeaderConnected/HeaderConnectedContent/ImgProfile.tsx index c919e6c76..6beeefbe5 100644 --- a/src/components/headers/HeaderConnected/HeaderConnectedContent/ImgProfile.tsx +++ b/src/components/headers/HeaderConnected/HeaderConnectedContent/ImgProfile.tsx @@ -1,20 +1,12 @@ import React, { useContext, useEffect, useState } from 'react'; +import { UserWithUserCandidate } from 'src/api/types'; import { Img } from 'src/components/utils'; import { CANDIDATE_USER_ROLES } from 'src/constants/users'; import { UserContext } from 'src/store/UserProvider'; import { isRoleIncluded } from 'src/utils/Finding'; interface ImgProfileProps { - user?: { - id: string; - firstName: string; - candidat?: { - cvs?: { - version: number; - urlImg: string; - }[]; - }; - }; + user?: UserWithUserCandidate; size?: number; } diff --git a/src/components/utils/CarouselSwiper/swiper-augmentation.d.ts b/src/components/utils/CarouselSwiper/swiper-augmentation.d.ts new file mode 100644 index 000000000..bb81cd9cb --- /dev/null +++ b/src/components/utils/CarouselSwiper/swiper-augmentation.d.ts @@ -0,0 +1,14 @@ +/* eslint import/no-unresolved: "off" */ +import { Pagination, Autoplay, Navigation } from 'swiper/modules'; + +declare module 'swiper/react' { + interface SwiperProps { + modules?: any[]; + threshold?: number; + navigation: boolean; + autoplay: boolean; + pagination: { + clickable: boolean; + }; + } +} diff --git a/tsconfig.json b/tsconfig.json index 1ab7c1f1f..4292e7bd4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,6 @@ "jsx": "preserve", "baseUrl": "./" }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "src/components/utils/CarouselSwiper/swiper-augmentation.d.ts"], "exclude": ["node_modules"] } diff --git a/yarn.lock b/yarn.lock index 0e74d9191..7f9a54b20 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14031,6 +14031,11 @@ ts-pnp@^1.1.6: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== +tsc-files@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/tsc-files/-/tsc-files-1.1.4.tgz#e0b2042a9494500f528769f52a0d0105a48457dd" + integrity sha512-RePsRsOLru3BPpnf237y1Xe1oCGta8rmSYzM76kYo5tLGsv5R2r3s64yapYorGTPuuLyfS9NVbh9ydzmvNie2w== + tsconfig-paths-webpack-plugin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.1.tgz#a24651d0f69668a1abad38d3c2489855c257460d" From 0067677ce18c2042a57ffe4f1e2716288eace8af Mon Sep 17 00:00:00 2001 From: PaulEntourage Date: Wed, 26 Jul 2023 15:02:06 +0200 Subject: [PATCH 2/2] [EN-6274] feat(cv): integration page CV --- .lintstagedrc.js | 2 +- package.json | 1 - src/components/cv/CVEditCareerPath.tsx | 4 ++-- src/components/cv/CVFicheEdition.tsx | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.lintstagedrc.js b/.lintstagedrc.js index b10c16341..347502e5f 100644 --- a/.lintstagedrc.js +++ b/.lintstagedrc.js @@ -1,4 +1,4 @@ module.exports = { - '*.ts?(x)': ['yarn tsc-files', 'yarn lint:fix'], + '*.ts?(x)': [() => 'yarn ts-check', 'yarn lint:fix'], '*.js?(x)': 'yarn lint:fix', }; diff --git a/package.json b/package.json index af03b0765..664822938 100755 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "lint": "npx eslint src --ext js,jsx,ts,tsx", "lint:fix": "npx eslint src --ext js,jsx,ts,tsx --fix", "ts-check": "tsc -p tsconfig.json --noEmit", - "ts-check:hook": "tsc tsconfig.json --noEmit", "format": "prettier --write './**/*.{js,jsx,md,json,ts,tsx}' --config .prettierrc.json", "build": "next build", "uikit-install": "cd ./node_modules/uikit && yarn", diff --git a/src/components/cv/CVEditCareerPath.tsx b/src/components/cv/CVEditCareerPath.tsx index 72b36ed59..a1ad4025f 100644 --- a/src/components/cv/CVEditCareerPath.tsx +++ b/src/components/cv/CVEditCareerPath.tsx @@ -12,7 +12,7 @@ import { } from 'src/constants'; import { findConstantFromValue, sortByOrder } from 'src/utils'; -interface CVEditCareerPath { +interface CVEditCareerPathProps { ambitions: { order: number; name: string; @@ -29,7 +29,7 @@ export const CVEditCareerPath = ({ ambitions, businessLines, onChange, -}: CVEditCareerPath) => { +}: CVEditCareerPathProps) => { const sortedAmbitions = ambitions && ambitions.length > 0 ? sortByOrder(ambitions) : null; diff --git a/src/components/cv/CVFicheEdition.tsx b/src/components/cv/CVFicheEdition.tsx index e2590997e..5d8103a06 100644 --- a/src/components/cv/CVFicheEdition.tsx +++ b/src/components/cv/CVFicheEdition.tsx @@ -17,7 +17,7 @@ import { Grid, Img } from 'src/components/utils'; import { CV_STATUS } from 'src/constants'; import { useMount, usePrevious } from 'src/hooks/utils'; -interface VFicheEditionProps { +interface CVFicheEditionProps { cv: CV; onChange?: (arg1: any) => void; disablePicture?: boolean; @@ -37,7 +37,7 @@ export const CVFicheEdition = ({ phone, address, userZone, -}: VFicheEditionProps) => { +}: CVFicheEditionProps) => { const [previewUrl, setPreviewUrl] = useState(undefined); const [imageUrl, setImageUrl] = useState(undefined);