@paro.io/expert-shared-components 1.7.1 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/components/ClientReferencesSection/DeleteButton.js +11 -11
  2. package/lib/components/ClientReferencesSection/ParoError.js +10 -10
  3. package/lib/components/ClientReferencesSection/TagsSection.js +2 -2
  4. package/lib/components/ClientReferencesSection/styles/BrandedTypography.js +2 -2
  5. package/lib/components/ClientReferencesSection/styles/Buttons.js +15 -15
  6. package/lib/components/ClientReferencesSection/styles/Name.js +5 -5
  7. package/lib/components/ClientReferencesSection/styles/NullContentConditionalColor.js +4 -4
  8. package/lib/components/ClientReferencesSection/styles/SectionBody.js +11 -11
  9. package/lib/components/ClientReferencesSection/styles/SectionTitle.js +6 -6
  10. package/lib/components/ClientReferencesSection/styles/Tags.js +2 -2
  11. package/lib/components/DocumentCenter/DocumentCenter.js +4 -3
  12. package/lib/components/DocumentCenter/DocumentTable.d.ts +15 -15
  13. package/lib/components/DocumentCenter/DocumentTable.js +350 -350
  14. package/lib/components/DocumentCenter/UploadFilesButton.d.ts +6 -6
  15. package/lib/components/DocumentCenter/UploadFilesButton.js +29 -29
  16. package/lib/components/ExpertProfileHeader/ActionButtonSection.d.ts +3 -1
  17. package/lib/components/ExpertProfileHeader/ActionButtonSection.js +13 -7
  18. package/lib/components/ExpertProfileHeader/ExpertProfileHeader.d.ts +3 -1
  19. package/lib/components/ExpertProfileHeader/ExpertProfileHeader.js +2 -2
  20. package/lib/components/ExpertProfileHeader/NetworkSection.js +2 -2
  21. package/lib/components/ExpertProfileHeader/ProfileSection.js +7 -7
  22. package/lib/components/HeaderNavBar/index.d.ts +1 -1
  23. package/lib/components/HeaderNavBar/index.js +6 -1
  24. package/lib/components/OrganizationChart/OrganizationChart.js +7 -7
  25. package/lib/components/Reviews/Pagination.js +6 -6
  26. package/lib/components/ReviewsTab/RatingHeader.js +6 -6
  27. package/lib/components/ReviewsTab/expert-shared-components.code-workspace +20 -20
  28. package/lib/components/ReviewsTab/reviewRequestModal.js +5 -5
  29. package/lib/components/ServiceLinesTemplate/index.d.ts +21 -0
  30. package/lib/components/ServiceLinesTemplate/index.js +231 -0
  31. package/lib/components/shared/Error.d.ts +6 -6
  32. package/lib/components/shared/Error.js +40 -40
  33. package/lib/components/shared/Image.js +13 -13
  34. package/lib/components/shared/ProfileTextField.d.ts +18 -18
  35. package/lib/components/shared/ProfileTextField.js +16 -16
  36. package/lib/components/shared/StyledActionButtons.d.ts +7 -7
  37. package/lib/components/shared/StyledActionButtons.js +15 -15
  38. package/lib/components/shared/ToastNotification.d.ts +10 -10
  39. package/lib/components/shared/ToastNotification.js +63 -63
  40. package/lib/components/shared/utils.d.ts +8 -2
  41. package/lib/components/shared/utils.js +73 -1
  42. package/lib/index.d.ts +2 -0
  43. package/lib/index.js +5 -1
  44. package/package.json +59 -59
@@ -1,6 +1,6 @@
1
- interface UploadFilesButtonProps {
2
- onFileSelect: (file: File) => void;
3
- isLoading?: boolean;
4
- }
5
- export declare const UploadFilesButton: ({ onFileSelect, isLoading, }: UploadFilesButtonProps) => JSX.Element;
6
- export {};
1
+ interface UploadFilesButtonProps {
2
+ onFileSelect: (file: File) => void;
3
+ isLoading?: boolean;
4
+ }
5
+ export declare const UploadFilesButton: ({ onFileSelect, isLoading, }: UploadFilesButtonProps) => JSX.Element;
6
+ export {};
@@ -1,29 +1,29 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.UploadFilesButton = void 0;
7
- const react_1 = __importDefault(require("react"));
8
- const base_ui_1 = require("@paro.io/base-ui");
9
- const react_2 = require("react");
10
- const UploadFilesButton = ({ onFileSelect, isLoading, }) => {
11
- const fileInputRef = (0, react_2.useRef)(null);
12
- const handleClick = () => {
13
- var _a;
14
- (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
15
- };
16
- const handleFileChange = (event) => {
17
- var _a;
18
- const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
19
- if (file) {
20
- onFileSelect(file);
21
- }
22
- // Reset input value to allow uploading the same file again
23
- event.target.value = '';
24
- };
25
- return (react_1.default.createElement("div", null,
26
- react_1.default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileChange, className: "hidden", accept: ".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx" }),
27
- react_1.default.createElement(base_ui_1.Button, { onClick: handleClick, disabled: isLoading })));
28
- };
29
- exports.UploadFilesButton = UploadFilesButton;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UploadFilesButton = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const base_ui_1 = require("@paro.io/base-ui");
9
+ const react_2 = require("react");
10
+ const UploadFilesButton = ({ onFileSelect, isLoading, }) => {
11
+ const fileInputRef = (0, react_2.useRef)(null);
12
+ const handleClick = () => {
13
+ var _a;
14
+ (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
15
+ };
16
+ const handleFileChange = (event) => {
17
+ var _a;
18
+ const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
19
+ if (file) {
20
+ onFileSelect(file);
21
+ }
22
+ // Reset input value to allow uploading the same file again
23
+ event.target.value = '';
24
+ };
25
+ return (react_1.default.createElement("div", null,
26
+ react_1.default.createElement("input", { type: "file", ref: fileInputRef, onChange: handleFileChange, className: "hidden", accept: ".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx" }),
27
+ react_1.default.createElement(base_ui_1.Button, { onClick: handleClick, disabled: isLoading })));
28
+ };
29
+ exports.UploadFilesButton = UploadFilesButton;
@@ -5,6 +5,8 @@ interface ActionButtonSectionProps {
5
5
  setOpenAssessmentModal: (openAssessmentModal: boolean) => void;
6
6
  createExpertPublicProfileTrackingRecord: () => void;
7
7
  lifetimeFSV: number;
8
+ openServiceLinesTemplate?: boolean;
9
+ setOpenServiceLinesTemplate: (openServiceLinesTemplate: boolean) => void;
8
10
  }
9
- declare const ActionButtonsSection: ({ isWhiteLabel, applicationStatus, publicProfileLink, setOpenAssessmentModal, createExpertPublicProfileTrackingRecord, lifetimeFSV }: ActionButtonSectionProps) => JSX.Element;
11
+ declare const ActionButtonsSection: ({ isWhiteLabel, applicationStatus, publicProfileLink, setOpenAssessmentModal, setOpenServiceLinesTemplate, createExpertPublicProfileTrackingRecord, lifetimeFSV, openServiceLinesTemplate }: ActionButtonSectionProps) => JSX.Element;
10
12
  export default ActionButtonsSection;
@@ -10,19 +10,25 @@ const react_1 = __importDefault(require("react"));
10
10
  const CopyToClipboardAlert_1 = __importDefault(require("../shared/CopyToClipboardAlert"));
11
11
  const colors_1 = __importDefault(require("../ClientReferencesSection/constants/colors"));
12
12
  const Banner_1 = __importDefault(require("./Banner"));
13
- const StyledButton = (0, styled_components_1.default)(core_1.Button) `
14
- margin: 0px !important;
15
- padding: 26px 0 18px 0 !important;
16
- span {
17
- color: ${colors_1.default.buttonText} !important
18
- }
13
+ const base_icons_1 = require("@paro.io/base-icons");
14
+ const StyledButton = (0, styled_components_1.default)(core_1.Button) `
15
+ margin: 0px !important;
16
+ padding: 26px 0 18px 0 !important;
17
+ span {
18
+ color: ${colors_1.default.buttonText} !important
19
+ }
19
20
  `;
20
21
  const ActionButton = ({ title, ariaLabel, onClick, icon: Icon }) => (react_1.default.createElement(core_1.Tooltip, { arrow: true, placement: "top", interactive: true, className: "whitespace-nowrap", title: title },
21
22
  react_1.default.createElement(core_1.IconButton, { "aria-label": ariaLabel, onClick: onClick },
22
23
  react_1.default.createElement(Icon, null))));
23
- const ActionButtonsSection = ({ isWhiteLabel, applicationStatus, publicProfileLink, setOpenAssessmentModal, createExpertPublicProfileTrackingRecord, lifetimeFSV }) => {
24
+ const ActionButtonsSection = ({ isWhiteLabel, applicationStatus, publicProfileLink, setOpenAssessmentModal, setOpenServiceLinesTemplate, createExpertPublicProfileTrackingRecord, lifetimeFSV, openServiceLinesTemplate }) => {
24
25
  return (react_1.default.createElement(core_1.Box, { style: { display: 'flex', justifyContent: 'flex-end', marginTop: '10px', alignItems: 'center' } },
25
26
  (lifetimeFSV && lifetimeFSV >= 85000) ? react_1.default.createElement(Banner_1.default, { lifetimeFSV: lifetimeFSV }) : '',
27
+ react_1.default.createElement(core_1.Tooltip, { arrow: true, placement: "top", interactive: true, className: "whitespace-nowrap", title: "Service Lines" },
28
+ react_1.default.createElement(core_1.IconButton, { onClick: () => setOpenServiceLinesTemplate(true) },
29
+ " ",
30
+ react_1.default.createElement(base_icons_1.IconBriefcase, { size: "md" }),
31
+ " ")),
26
32
  isWhiteLabel && applicationStatus === 'ACTIVE' && (react_1.default.createElement(ActionButton, { title: "Send Assessment", ariaLabel: "send assessment", onClick: () => setOpenAssessmentModal(true), icon: icons_1.Send })),
27
33
  react_1.default.createElement(CopyToClipboardAlert_1.default, { alertMessage: "Public profile copied to clipboard", title: "Copy public profile link", button: StyledButton, buttonContent: "", copyContent: publicProfileLink, icon: true, mutationToInvoke: createExpertPublicProfileTrackingRecord, iconButton: true })));
28
34
  };
@@ -14,6 +14,8 @@ type SectionContents = {
14
14
  paroAppUrl: string;
15
15
  isExpertOps?: boolean;
16
16
  internalUserId?: number;
17
+ openServiceLinesTemplate?: boolean;
18
+ setOpenServiceLinesTemplate: (openServiceLinesTemplate: boolean) => void;
17
19
  };
18
20
  type QueryAndMutationProps = {
19
21
  getExpertByLegacyFreelancerIdDocument?: any;
@@ -71,5 +73,5 @@ type ProfileCompletedPercentageProps = {
71
73
  detailsSectionCompleted: boolean;
72
74
  handleScrollToBottom?: () => void;
73
75
  };
74
- export declare const ExpertProfileHeader: ({ expertId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, }: SectionContents & PersonalInformationType & ProfileCompletedPercentageProps & QueryAndMutationProps & ChangeEmailPasswordProps) => JSX.Element;
76
+ export declare const ExpertProfileHeader: ({ expertId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, openServiceLinesTemplate, setOpenServiceLinesTemplate, }: SectionContents & PersonalInformationType & ProfileCompletedPercentageProps & QueryAndMutationProps & ChangeEmailPasswordProps) => JSX.Element;
75
77
  export {};
@@ -75,7 +75,7 @@ const convertRegionToStateAbbreviation = (region) => {
75
75
  const personalInformationReducer = (state, updatedState) => {
76
76
  return Object.assign(Object.assign({}, state), updatedState);
77
77
  };
78
- const ExpertProfileHeader = ({ expertId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, }) => {
78
+ const ExpertProfileHeader = ({ expertId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, openServiceLinesTemplate, setOpenServiceLinesTemplate, }) => {
79
79
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
80
80
  const [leftSideStatus, setLeftSideStatus] = react_1.default.useState("");
81
81
  const [rightSideStatus, setRightSideStatus] = react_1.default.useState("");
@@ -210,7 +210,7 @@ const ExpertProfileHeader = ({ expertId, address: addressForReducer, companyName
210
210
  react_1.default.createElement(core_1.Typography, { variant: 'h5' },
211
211
  react_1.default.createElement("b", null, "Personal Information"))),
212
212
  isInternal && react_1.default.createElement(core_1.Grid, { item: true },
213
- react_1.default.createElement(ActionButtonSection_1.default, { isWhiteLabel: isWhiteLabel, applicationStatus: applicationStatus, publicProfileLink: publicProfileLink, setOpenAssessmentModal: setOpenAssessmentModal, createExpertPublicProfileTrackingRecord: createExpertPublicProfileTrackingRecord, lifetimeFSV: lifetimeFSV !== null && lifetimeFSV !== void 0 ? lifetimeFSV : 0 }))),
213
+ react_1.default.createElement(ActionButtonSection_1.default, { isWhiteLabel: isWhiteLabel, applicationStatus: applicationStatus, publicProfileLink: publicProfileLink, setOpenAssessmentModal: setOpenAssessmentModal, createExpertPublicProfileTrackingRecord: createExpertPublicProfileTrackingRecord, lifetimeFSV: lifetimeFSV !== null && lifetimeFSV !== void 0 ? lifetimeFSV : 0, openServiceLinesTemplate: openServiceLinesTemplate, setOpenServiceLinesTemplate: setOpenServiceLinesTemplate }))),
214
214
  react_1.default.createElement(CustomPaper, { style: { minHeight: 'min-content', maxHeight: '60vh', overflow: 'auto', borderBottom: '1px solid #c1c1c1' }, className: 'personalInfo' },
215
215
  react_1.default.createElement(core_1.Divider, null),
216
216
  react_1.default.createElement(core_1.Grid, { container: true, spacing: 2, style: { display: 'flex', flexWrap: isSmallScreen ? 'wrap' : 'nowrap' } },
@@ -25,10 +25,10 @@ const StatusItem = ({ label, status, successText, warningText }) => {
25
25
  react_1.default.createElement("b", { className: status ? classes.textSuccess : classes.textWarning }, status ? successText : warningText)));
26
26
  };
27
27
  const NetworkSection = ({ handleScrollToBottom, preferenceTasks, isWhiteLabel, detailsSectionCompleted, infoColor, leftSideStatus, rightSideStatus, isInternal }) => {
28
- return (react_1.default.createElement(core_1.Grid, { item: true, style: { width: '100%', padding: '6px 0px 6px 0px' } },
28
+ return (react_1.default.createElement(core_1.Grid, { item: true, style: { width: '100%', padding: '6px 0px 6px 0px', zIndex: 1 } },
29
29
  react_1.default.createElement(core_1.Grid, { style: { paddingLeft: '10px' } },
30
30
  react_1.default.createElement("b", null, "Profile"),
31
- react_1.default.createElement("div", { style: { display: 'flex', justifyContent: 'flex-start', cursor: 'pointer', width: 'full', marginBottom: '6px' }, onClick: handleScrollToBottom },
31
+ react_1.default.createElement("div", { style: { display: 'flex', justifyContent: 'flex-start', cursor: 'pointer', width: 'full', marginBottom: '6px', zIndex: 1 }, onClick: handleScrollToBottom },
32
32
  react_1.default.createElement(ProfileCompletedPercentange_1.ProfileCompletedPercentage, { preferenceTasks: preferenceTasks, isWhiteLabel: isWhiteLabel, detailsSectionCompleted: detailsSectionCompleted }))),
33
33
  react_1.default.createElement(core_1.Box, { mt: 4, mb: 2, mr: 2 },
34
34
  react_1.default.createElement(core_1.Divider, null)),
@@ -53,13 +53,13 @@ const formatPhoneNumber = (phone) => {
53
53
  return `(${numericPhone.slice(0, 3)}) ${numericPhone.slice(3, 6)} - ${numericPhone.slice(6)}`;
54
54
  };
55
55
  exports.formatPhoneNumber = formatPhoneNumber;
56
- exports.ProfilePhotoPreview = styled_components_1.default.img `
57
- height: 86px;
58
- width: 86px;
59
- border: 1px solid ${colors_1.default.lightGray};
60
- border-radius: 50%;
61
- object-fit: cover;
62
- object-position: top;
56
+ exports.ProfilePhotoPreview = styled_components_1.default.img `
57
+ height: 86px;
58
+ width: 86px;
59
+ border: 1px solid ${colors_1.default.lightGray};
60
+ border-radius: 50%;
61
+ object-fit: cover;
62
+ object-position: top;
63
63
  `;
64
64
  const ProfileSection = ({ legacyFreelancerId, imageUrl, shouldAllowEditProfile, firstName, lastName, primaryServiceLine, editServiceLine, city, stateAbbreviation, email, phone, paroTenure, hourlyRate, setOpen, paroProjectsData, getUserDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, isInternal, getUserByEmail, updateUserEmail, updateUserMutation, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, }) => {
65
65
  var _a;
@@ -1,2 +1,2 @@
1
1
  import React from "react";
2
- export declare const HeaderNavBar: ({ setOpenDocumentModal }: any) => React.JSX.Element;
2
+ export declare const HeaderNavBar: ({ setOpenDocumentModal, setOpenServiceLinesTemplate }: any) => React.JSX.Element;
@@ -7,9 +7,14 @@ exports.HeaderNavBar = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const core_1 = require("@material-ui/core");
9
9
  const base_icons_1 = require("@paro.io/base-icons");
10
- const HeaderNavBar = ({ setOpenDocumentModal }) => {
10
+ const HeaderNavBar = ({ setOpenDocumentModal, setOpenServiceLinesTemplate }) => {
11
11
  return (react_1.default.createElement("div", { className: "flex w-full bg-white p-1 shadow-sm justify-end" },
12
12
  react_1.default.createElement("div", { style: { display: 'flex', justifyContent: 'flex-end' } },
13
+ react_1.default.createElement(core_1.Tooltip, { arrow: true, placement: "top", interactive: true, className: "whitespace-nowrap", title: "Service Lines" },
14
+ react_1.default.createElement(core_1.IconButton, { onClick: () => setOpenServiceLinesTemplate(true) },
15
+ " ",
16
+ react_1.default.createElement(base_icons_1.IconBriefcase, { size: "md" }),
17
+ " ")),
13
18
  react_1.default.createElement(core_1.Tooltip, { arrow: true, placement: "top", interactive: true, className: "whitespace-nowrap", title: "Document Center" },
14
19
  react_1.default.createElement(core_1.IconButton, { id: "document_center_button", "data-tut": "document_center_button", onClick: () => setOpenDocumentModal(true) },
15
20
  " ",
@@ -34,13 +34,13 @@ const Close_1 = __importDefault(require("@material-ui/icons/Close"));
34
34
  const cdn_1 = require("../shared/constants/cdn");
35
35
  const styled_components_1 = __importDefault(require("styled-components"));
36
36
  const defaultAvatar = cdn_1.CDN_URL + 'defaultAvatar.png';
37
- const ProfilePhotoPreview = styled_components_1.default.img `
38
- height: 86px;
39
- width: 86px;
40
- border: 1px solid #e4e5e4;
41
- border-radius: 50%;
42
- object-fit: cover;
43
- object-position: top;
37
+ const ProfilePhotoPreview = styled_components_1.default.img `
38
+ height: 86px;
39
+ width: 86px;
40
+ border: 1px solid #e4e5e4;
41
+ border-radius: 50%;
42
+ object-fit: cover;
43
+ object-position: top;
44
44
  `;
45
45
  const CustomDialog = (0, core_1.styled)(Dialog_1.default)(({ theme }) => ({
46
46
  '& .MuiDialog-paper': {
@@ -51,12 +51,12 @@ const Pagination = ({ total, currentPage = 1, setCurrentPage, perPageItems = 10,
51
51
  };
52
52
  const numberOfPages = Math.ceil(total / perPageItems);
53
53
  return (react_1.default.createElement("div", { className: "bg-white px-4 py-3 border-t border-gray-200 sm:px-6 flex flex-col md:flex-row md:items-center md:justify-between" },
54
- react_1.default.createElement("div", { className: "pb-2 md:pb-0" }, `Showing
55
- ${perPageItems * (currentPage - 1) + 1}
56
- to
57
- ${Math.min(total, perPageItems * currentPage)}
58
- of
59
- ${total}
54
+ react_1.default.createElement("div", { className: "pb-2 md:pb-0" }, `Showing
55
+ ${perPageItems * (currentPage - 1) + 1}
56
+ to
57
+ ${Math.min(total, perPageItems * currentPage)}
58
+ of
59
+ ${total}
60
60
  ${displayText}`),
61
61
  react_1.default.createElement("div", { className: "flex items-center justify-between" },
62
62
  react_1.default.createElement("div", { className: "flex-1 flex justify-between sm:hidden" },
@@ -51,12 +51,12 @@ const isRatingExists = (rating) => {
51
51
  return false;
52
52
  };
53
53
  exports.isRatingExists = isRatingExists;
54
- const StyledButton = (0, styled_components_1.default)(core_2.Button) `
55
- margin: 0px !important;
56
- padding: 26px 0 18px 0 !important;
57
- span {
58
- color: #248384 !important
59
- }
54
+ const StyledButton = (0, styled_components_1.default)(core_2.Button) `
55
+ margin: 0px !important;
56
+ padding: 26px 0 18px 0 !important;
57
+ span {
58
+ color: #248384 !important
59
+ }
60
60
  `;
61
61
  const RatingHeader = ({ ratings, project, index, highlightedRatings, requestStatus, handleRatingRequest, loadingSubmitId, handleAddToProfile, ratingReviewButtonlabel, setOpenClientReviewModal, setShowReviewModelWithRecentlyRatedProjects, enableReviewModal, disableReviewModal, isClientPortal, isInternal, createOrUpdateRating, getParoProjectsDocument, projectIdToShow, }) => {
62
62
  var _a, _b, _c, _d;
@@ -1,20 +1,20 @@
1
- {
2
- "folders": [
3
- {
4
- "path": "../../.."
5
- },
6
- {
7
- "path": "../../../../internal-profile-app"
8
- },
9
- {
10
- "path": "../../../../availability-gantt-chart"
11
- },
12
- {
13
- "path": "../../../../client-portal"
14
- },
15
- {
16
- "path": "../../../../expert-portal"
17
- }
18
- ],
19
- "settings": {}
20
- }
1
+ {
2
+ "folders": [
3
+ {
4
+ "path": "../../.."
5
+ },
6
+ {
7
+ "path": "../../../../internal-profile-app"
8
+ },
9
+ {
10
+ "path": "../../../../availability-gantt-chart"
11
+ },
12
+ {
13
+ "path": "../../../../client-portal"
14
+ },
15
+ {
16
+ "path": "../../../../expert-portal"
17
+ }
18
+ ],
19
+ "settings": {}
20
+ }
@@ -34,11 +34,11 @@ const react_hot_toast_1 = __importDefault(require("react-hot-toast"));
34
34
  const ReviewRequestModal = ({ project, requestModal, setRequestModal, expertName, freelancerId, setRequestStatus, selectedProject, setSelectedProject, clientId, refetchParoProjects, setHighlightedRatings, createOrUpdateRatingRequestMutation, getParoProjectsDocument, }) => {
35
35
  var _a;
36
36
  const [showError, setShowError] = (0, react_1.useState)(false);
37
- const [textareaValue, setTextareaValue] = (0, react_1.useState)(`Hi ${(_a = project === null || project === void 0 ? void 0 : project.client) === null || _a === void 0 ? void 0 : _a.name},
38
- I hope you are satisfied with the work I provided on ${project === null || project === void 0 ? void 0 : project.name}. Your feedback is very important to me and helps me improve my services and build my reputation on Paro. Could you please take a moment to leave a review of you experience? Your input is greatly appreciated!
39
-
40
- Thank you in advance for your time and feedback.
41
- Best regards,
37
+ const [textareaValue, setTextareaValue] = (0, react_1.useState)(`Hi ${(_a = project === null || project === void 0 ? void 0 : project.client) === null || _a === void 0 ? void 0 : _a.name},
38
+ I hope you are satisfied with the work I provided on ${project === null || project === void 0 ? void 0 : project.name}. Your feedback is very important to me and helps me improve my services and build my reputation on Paro. Could you please take a moment to leave a review of you experience? Your input is greatly appreciated!
39
+
40
+ Thank you in advance for your time and feedback.
41
+ Best regards,
42
42
  ${expertName}`);
43
43
  const handleTextArea = (e) => {
44
44
  setTextareaValue(e.target.value);
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ type ServiceLinesTemplateProps = {
3
+ getFreelancerDataResult?: any;
4
+ createOrUpdateRates?: any;
5
+ updateExpert?: any;
6
+ openServiceLinesTemplate?: boolean;
7
+ setOpenServiceLinesTemplate?: any;
8
+ getRatesByExpertId?: any;
9
+ setView?: any;
10
+ getServiceLines?: any;
11
+ legacyFreelancerId?: any;
12
+ expertId?: any;
13
+ isFirmProfile?: boolean;
14
+ serviceLineData?: any;
15
+ selectedServicesList?: any;
16
+ servicePricesList?: any;
17
+ isInternalProfile?: boolean;
18
+ updateFreelancerPreferences?: any;
19
+ };
20
+ export declare const ServiceLinesTemplate: ({ getFreelancerDataResult, createOrUpdateRates, getRatesByExpertId, updateExpert, openServiceLinesTemplate, setOpenServiceLinesTemplate, getServiceLines, legacyFreelancerId, expertId, isFirmProfile, serviceLineData, selectedServicesList, isInternalProfile, updateFreelancerPreferences, }: ServiceLinesTemplateProps) => false | React.JSX.Element | undefined;
21
+ export {};
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.ServiceLinesTemplate = void 0;
36
+ const react_1 = __importStar(require("react"));
37
+ const core_1 = require("@material-ui/core");
38
+ const icons_1 = require("@material-ui/icons");
39
+ const ReviewsTab_1 = require("../ReviewsTab/ReviewsTab");
40
+ const base_ui_1 = require("@paro.io/base-ui");
41
+ const utils_1 = require("../shared/utils");
42
+ const ServiceLinesTemplate = ({ getFreelancerDataResult, createOrUpdateRates, getRatesByExpertId, updateExpert, openServiceLinesTemplate, setOpenServiceLinesTemplate, getServiceLines, legacyFreelancerId, expertId, isFirmProfile, serviceLineData, selectedServicesList = [], isInternalProfile = false, updateFreelancerPreferences, }) => {
43
+ const [selectedServices, dispatch] = (0, react_1.useReducer)(utils_1.selectedServicesReducer, selectedServicesList);
44
+ const [updateClicked, setUpdateClicked] = (0, react_1.useState)(false);
45
+ const [loading, setLoading] = (0, react_1.useState)(false);
46
+ const [serviceLines, setServiceLines] = (0, react_1.useState)(serviceLineData);
47
+ const [currentServiveRate, setCurrentServiceRate] = (0, react_1.useState)(null);
48
+ const fetchServiceLineData = () => __awaiter(void 0, void 0, void 0, function* () {
49
+ var _a, _b, _c, _d, _e, _f, _g, _h;
50
+ try {
51
+ setLoading(true);
52
+ const [freelancerResponse, serviceLinesResponse, ratesResponse] = yield Promise.all([
53
+ getFreelancerDataResult({ variables: { legacyFreelancerId: legacyFreelancerId }, skip: !legacyFreelancerId, fetchPolicy: 'network-only' }),
54
+ getServiceLines({ fetchPolicy: 'network-only', }),
55
+ getRatesByExpertId({ variables: { expertId }, skip: !expertId, fetchPolicy: 'network-only' }),
56
+ ]);
57
+ setServiceLines(((_a = serviceLinesResponse === null || serviceLinesResponse === void 0 ? void 0 : serviceLinesResponse.data) === null || _a === void 0 ? void 0 : _a.getServiceLines) || serviceLineData);
58
+ const currentService = (_d = (_c = (_b = freelancerResponse === null || freelancerResponse === void 0 ? void 0 : freelancerResponse.data) === null || _b === void 0 ? void 0 : _b.getExpertByLegacyFreelancerId) === null || _c === void 0 ? void 0 : _c.legacyMetadata) === null || _d === void 0 ? void 0 : _d.primaryServiceLine;
59
+ const currentRate = (_g = (_f = (_e = freelancerResponse === null || freelancerResponse === void 0 ? void 0 : freelancerResponse.data) === null || _e === void 0 ? void 0 : _e.getExpertByLegacyFreelancerId) === null || _f === void 0 ? void 0 : _f.legacyMetadata) === null || _g === void 0 ? void 0 : _g.defaultHourlyRate;
60
+ const expertRates = (_h = ratesResponse === null || ratesResponse === void 0 ? void 0 : ratesResponse.data) === null || _h === void 0 ? void 0 : _h.getRatesByExpertId;
61
+ setCurrentServiceRate(currentRate);
62
+ dispatch({
63
+ currentService,
64
+ currentRate,
65
+ expertRates,
66
+ type: 'populate'
67
+ });
68
+ }
69
+ catch (error) {
70
+ console.error("Error fetching service line data:", error);
71
+ }
72
+ finally {
73
+ setLoading(false);
74
+ }
75
+ });
76
+ (0, react_1.useEffect)(() => {
77
+ if (openServiceLinesTemplate && !isInternalProfile) {
78
+ fetchServiceLineData();
79
+ }
80
+ }, [openServiceLinesTemplate]);
81
+ const handlePriceChange = (serviceTitle, newPrice, currentService) => {
82
+ dispatch({
83
+ serviceTitle,
84
+ newPrice,
85
+ currentService,
86
+ type: 'price-change'
87
+ });
88
+ };
89
+ const services = serviceLines === null || serviceLines === void 0 ? void 0 : serviceLines.map((title) => {
90
+ return {
91
+ title: utils_1.titleMappings[title] || title,
92
+ description: utils_1.serviceDescriptions[utils_1.titleMappings[title]] || '',
93
+ };
94
+ });
95
+ const updateFreelancerPreferencesFn = (rate) => {
96
+ updateFreelancerPreferences({
97
+ variables: {
98
+ freelancerId: legacyFreelancerId,
99
+ input: {
100
+ freelancerRate: rate,
101
+ clientRate: rate * 2,
102
+ },
103
+ },
104
+ });
105
+ };
106
+ const handleUpdateProfile = () => __awaiter(void 0, void 0, void 0, function* () {
107
+ try {
108
+ setUpdateClicked(true);
109
+ const ratesInput = {
110
+ rates: selectedServices.map((service) => ({
111
+ serviceLine: service.service,
112
+ rate: Number(service.rate),
113
+ })),
114
+ };
115
+ const isCurrentRateUpdated = selectedServices.filter((service) => service.currentService === true);
116
+ if (isCurrentRateUpdated.length > 0 && isCurrentRateUpdated[0].rate !== currentServiveRate) {
117
+ yield updateFreelancerPreferencesFn(Number(isCurrentRateUpdated[0].rate));
118
+ }
119
+ yield createOrUpdateRates({
120
+ variables: {
121
+ expertId: expertId,
122
+ isFirmProfile: isFirmProfile === true,
123
+ input: ratesInput,
124
+ },
125
+ });
126
+ updateFeatureStatus();
127
+ fetchServiceLineData();
128
+ }
129
+ catch (error) {
130
+ console.log('DB Updation failed: ', error.message);
131
+ }
132
+ finally {
133
+ setOpenServiceLinesTemplate && setOpenServiceLinesTemplate(false);
134
+ }
135
+ ;
136
+ });
137
+ const updateFeatureStatus = () => {
138
+ updateExpert({
139
+ variables: {
140
+ expertId: expertId,
141
+ input: {
142
+ featureStatus: { "serviceLines": true }
143
+ }
144
+ },
145
+ }).then(() => {
146
+ (0, ReviewsTab_1.toastNotification)({
147
+ position: 'top-center',
148
+ color: 'success',
149
+ message: 'Updated successfully!',
150
+ icon: 'success',
151
+ });
152
+ }).catch((error) => {
153
+ (0, ReviewsTab_1.toastNotification)({
154
+ position: 'top-center',
155
+ color: 'warning',
156
+ message: 'Update failed!',
157
+ icon: 'warning'
158
+ });
159
+ console.log('DB Updation failed : ', error.message);
160
+ }).finally(() => {
161
+ setOpenServiceLinesTemplate && setOpenServiceLinesTemplate(false);
162
+ });
163
+ };
164
+ const handleNotInterestedClick = () => __awaiter(void 0, void 0, void 0, function* () {
165
+ yield updateFeatureStatus();
166
+ });
167
+ const isUpdateButtonDisabled = () => {
168
+ if ((selectedServices === null || selectedServices === void 0 ? void 0 : selectedServices.length) === 0)
169
+ return true;
170
+ return selectedServices.some((service) => !service.service || service.rate === 0);
171
+ };
172
+ const CustomCheckbox = (0, core_1.withStyles)({
173
+ root: {
174
+ color: "#378284",
175
+ "&$checked": {
176
+ color: "#378284",
177
+ },
178
+ "&.Mui-disabled.Mui-checked": {
179
+ color: "#9e9e9e", // Grey color when both disabled and checked
180
+ },
181
+ },
182
+ checked: {},
183
+ })((props) => react_1.default.createElement(core_1.Checkbox, Object.assign({ color: "default" }, props)));
184
+ const handleServiceToggle = (service) => {
185
+ dispatch({
186
+ service,
187
+ type: 'update'
188
+ });
189
+ };
190
+ return (openServiceLinesTemplate && (react_1.default.createElement(core_1.Grid, { style: { backgroundColor: '#fff' } }, loading ? (react_1.default.createElement(core_1.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px" },
191
+ react_1.default.createElement(core_1.CircularProgress, null))) : (react_1.default.createElement(react_1.default.Fragment, null,
192
+ react_1.default.createElement(core_1.Grid, { style: { backgroundColor: '#132f4a', padding: 12 }, className: "service-lines-header" },
193
+ react_1.default.createElement(core_1.Typography, { className: "headerTop", variant: "h5", style: { color: '#ffffff', fontWeight: 500, padding: 12, justifyContent: 'space-between', display: 'flex', alignItems: 'center' } },
194
+ "Expand Your Expertise: Add More Services to Your Profile",
195
+ react_1.default.createElement("img", { src: 'https://expert-files-dev.s3.us-east-1.amazonaws.com/ParoGroupLogo.png', alt: "Paro Group Logo", style: { width: 24, height: 24, marginLeft: 8 } })),
196
+ react_1.default.createElement(core_1.Typography, { className: "headerMiddle", style: { color: '#ffffff', fontWeight: 200, fontStyle: 'italic', paddingLeft: 12 } }, "Why Add More Services?"),
197
+ react_1.default.createElement(core_1.Grid, { container: true, spacing: 3, style: { padding: 12, color: '#ffffff' }, direction: "row", justifyContent: "flex-start", alignItems: "center" }, utils_1.features.map((feature, index) => (react_1.default.createElement(core_1.Box, { key: index, display: "flex", alignItems: "center", m: 2 },
198
+ react_1.default.createElement(icons_1.AdjustRounded, { style: {
199
+ marginRight: 8,
200
+ color: '#2A9D8F',
201
+ fontSize: 20
202
+ }, className: "headerCircle" }),
203
+ react_1.default.createElement(core_1.Typography, { className: "headerFeature", variant: "body2", style: { color: '#ffffff' } }, feature)))))),
204
+ react_1.default.createElement(core_1.Grid, { container: true, style: { padding: 4 } },
205
+ react_1.default.createElement(core_1.Typography, { variant: "h6", style: { marginLeft: 20, fontWeight: 500 } }, "Select from the following service lines:"),
206
+ react_1.default.createElement(core_1.Grid, { container: true, direction: "row", justifyContent: "space-evenly", alignItems: "center" }, services === null || services === void 0 ? void 0 :
207
+ services.map((service, index) => {
208
+ const serviceExistsInArray = selectedServices.find((svc) => svc.service === service.title);
209
+ return (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, md: 5, key: index, style: { margin: 12 } },
210
+ react_1.default.createElement(core_1.Box, { sx: { display: "flex" } },
211
+ react_1.default.createElement(core_1.Box, { display: 'flex', alignItems: 'center' },
212
+ react_1.default.createElement(CustomCheckbox, { checked: serviceExistsInArray, disabled: serviceExistsInArray === null || serviceExistsInArray === void 0 ? void 0 : serviceExistsInArray.currentService, onChange: () => handleServiceToggle(service.title) })),
213
+ react_1.default.createElement(core_1.Box, { sx: { flex: 1 } },
214
+ react_1.default.createElement(core_1.Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2 } },
215
+ react_1.default.createElement(core_1.Box, null,
216
+ react_1.default.createElement(core_1.Typography, { component: "div", style: { fontWeight: 300, fontSize: 16 } },
217
+ service.title,
218
+ (serviceExistsInArray === null || serviceExistsInArray === void 0 ? void 0 : serviceExistsInArray.currentService) && (react_1.default.createElement(core_1.Typography, { variant: "caption", style: { fontWeight: 400, fontSize: 16 } }, "\u00A0(current service line)"))),
219
+ react_1.default.createElement(core_1.Typography, { variant: "body2", style: { fontWeight: 50, fontSize: 14 } }, service.description)),
220
+ react_1.default.createElement(core_1.Box, { display: 'flex', alignItems: 'center', ml: 4 },
221
+ react_1.default.createElement(core_1.TextField, { size: "small", variant: "outlined", value: (serviceExistsInArray === null || serviceExistsInArray === void 0 ? void 0 : serviceExistsInArray.rate) || '', onChange: (e) => handlePriceChange(service.title, e.target.value ? parseInt(e.target.value) : 0, serviceExistsInArray === null || serviceExistsInArray === void 0 ? void 0 : serviceExistsInArray.currentService), InputProps: {
222
+ startAdornment: react_1.default.createElement(core_1.Typography, null, "$\u00A0"),
223
+ endAdornment: react_1.default.createElement(core_1.Typography, null, "\u00A0/hr"),
224
+ }, style: { width: 100 }, required: serviceExistsInArray, error: serviceExistsInArray && !serviceExistsInArray.rate, label: "Rate", className: "serviceLineRateInput" })))))));
225
+ }),
226
+ react_1.default.createElement(core_1.Grid, { item: true, xs: 12, md: 5, style: { margin: 5 } },
227
+ react_1.default.createElement(core_1.Box, { sx: { display: "flex", justifyContent: "space-evenly", mt: 4 } },
228
+ react_1.default.createElement(base_ui_1.Button, { label: "UPDATE PROFILE", onClick: handleUpdateProfile, type: "button", disabled: isUpdateButtonDisabled(), color: "primary" }),
229
+ react_1.default.createElement(base_ui_1.Button, { label: "NOT INTERESTED", onClick: handleNotInterestedClick, type: "button", disabled: updateClicked }))))))))));
230
+ };
231
+ exports.ServiceLinesTemplate = ServiceLinesTemplate;
@@ -1,6 +1,6 @@
1
- type SectionContents = {
2
- handleClose?: (...args: any) => void;
3
- formError?: boolean;
4
- };
5
- declare const Error: ({ handleClose }: SectionContents) => JSX.Element;
6
- export default Error;
1
+ type SectionContents = {
2
+ handleClose?: (...args: any) => void;
3
+ formError?: boolean;
4
+ };
5
+ declare const Error: ({ handleClose }: SectionContents) => JSX.Element;
6
+ export default Error;