@paro.io/expert-shared-components 1.14.14 → 1.14.16
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.
- package/LICENSE +21 -21
- package/README.md +2 -2
- package/lib/components/ClientReferencesSection/DeleteButton.js +11 -11
- package/lib/components/ClientReferencesSection/ParoError.js +10 -10
- package/lib/components/ClientReferencesSection/TagsSection.js +2 -2
- package/lib/components/ClientReferencesSection/styles/BrandedTypography.js +2 -2
- package/lib/components/ClientReferencesSection/styles/Buttons.js +15 -15
- package/lib/components/ClientReferencesSection/styles/Name.js +5 -5
- package/lib/components/ClientReferencesSection/styles/NullContentConditionalColor.js +4 -4
- package/lib/components/ClientReferencesSection/styles/SectionBody.js +11 -11
- package/lib/components/ClientReferencesSection/styles/SectionTitle.js +6 -6
- package/lib/components/ClientReferencesSection/styles/Tags.js +2 -2
- package/lib/components/DiscussionThread/chat.d.ts +22 -22
- package/lib/components/DiscussionThread/chat.js +106 -106
- package/lib/components/DocumentCenter/DocumentTable.d.ts +15 -15
- package/lib/components/DocumentCenter/DocumentTable.js +350 -350
- package/lib/components/DocumentCenter/UploadFilesButton.d.ts +6 -6
- package/lib/components/DocumentCenter/UploadFilesButton.js +29 -29
- package/lib/components/EarningsTracker/ActiveProjectCard.d.ts +52 -52
- package/lib/components/EarningsTracker/ActiveProjectCard.js +161 -161
- package/lib/components/EarningsTracker/CenterCardUI.d.ts +13 -13
- package/lib/components/EarningsTracker/CenterCardUI.js +134 -134
- package/lib/components/EarningsTracker/EarningsTracker.d.ts +52 -52
- package/lib/components/EarningsTracker/EarningsTracker.js +508 -508
- package/lib/components/EarningsTracker/EditDateModal.d.ts +22 -22
- package/lib/components/EarningsTracker/EditDateModal.js +149 -149
- package/lib/components/EarningsTracker/EmailModal.d.ts +14 -14
- package/lib/components/EarningsTracker/EmailModal.js +79 -79
- package/lib/components/EarningsTracker/EndProjectModal.d.ts +56 -56
- package/lib/components/EarningsTracker/EndProjectModal.js +221 -221
- package/lib/components/EarningsTracker/LeftCardUI.d.ts +18 -18
- package/lib/components/EarningsTracker/LeftCardUI.js +189 -189
- package/lib/components/EarningsTracker/LogTimeModalAuthenticated.d.ts +52 -52
- package/lib/components/EarningsTracker/LogTimeModalAuthenticated.js +358 -358
- package/lib/components/EarningsTracker/ProgressBar.d.ts +4 -4
- package/lib/components/EarningsTracker/ProgressBar.js +66 -66
- package/lib/components/EarningsTracker/ReviewRequestModal.d.ts +17 -17
- package/lib/components/EarningsTracker/ReviewRequestModal.js +135 -135
- package/lib/components/EarningsTracker/RightCardUI.d.ts +46 -46
- package/lib/components/EarningsTracker/RightCardUI.js +231 -231
- package/lib/components/EarningsTracker/index.d.ts +1 -1
- package/lib/components/EarningsTracker/index.js +5 -5
- package/lib/components/Escalations/CustomTag.d.ts +3 -3
- package/lib/components/Escalations/CustomTag.js +25 -25
- package/lib/components/Escalations/ViewReponseModal.d.ts +8 -8
- package/lib/components/Escalations/ViewReponseModal.js +27 -27
- package/lib/components/ExpertProfileHeader/ActionButtonSection.js +6 -6
- package/lib/components/ExpertProfileHeader/ProfileSection.js +7 -7
- package/lib/components/ExpertProfileHeader/TeamsSection.js +1 -1
- package/lib/components/HeaderNavBar/index.d.ts +1 -1
- package/lib/components/HeaderNavBar/index.js +25 -18
- package/lib/components/Invoices/TestDecisionSection.d.ts +1 -1
- package/lib/components/Invoices/TestDecisionSection.js +126 -126
- package/lib/components/OrganizationChart/OrgChart.d.ts +15 -1
- package/lib/components/OrganizationChart/OrgChart.js +33 -30
- package/lib/components/OrganizationChart/OrganizationChart.d.ts +15 -15
- package/lib/components/OrganizationChart/OrganizationChart.js +312 -312
- package/lib/components/OrganizationChart/PersonCard.js +5 -5
- package/lib/components/OrganizationChart/utils.d.ts +1 -1
- package/lib/components/OrganizationChart/utils.js +80 -80
- package/lib/components/ProjectCard/ProgressBar.js +4 -4
- package/lib/components/ProjectCard/ReviewRequestModal.js +5 -5
- package/lib/components/ProjectIntelligence/MissingInformation/index.js +1 -1
- package/lib/components/Reviews/Pagination.js +6 -6
- package/lib/components/ReviewsTab/RatingHeader.js +6 -6
- package/lib/components/ReviewsTab/expert-shared-components.code-workspace +20 -20
- package/lib/components/ReviewsTab/reviewRequestModal.js +5 -5
- package/lib/components/shared/Image.js +13 -13
- package/lib/components/shared/ProfileTextField.d.ts +18 -18
- package/lib/components/shared/ProfileTextField.js +16 -16
- package/lib/components/shared/StyledActionButtons.d.ts +7 -7
- package/lib/components/shared/StyledActionButtons.js +15 -15
- package/lib/components/shared/ToastNotification.d.ts +10 -10
- package/lib/components/shared/ToastNotification.js +63 -63
- package/package.json +67 -67
|
@@ -1,508 +1,508 @@
|
|
|
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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
-
};
|
|
37
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.EarningsTracker = void 0;
|
|
39
|
-
const react_1 = __importStar(require("react"));
|
|
40
|
-
const core_1 = require("@material-ui/core");
|
|
41
|
-
const base_icons_1 = require("@paro.io/base-icons");
|
|
42
|
-
const base_ui_1 = require("@paro.io/base-ui");
|
|
43
|
-
const ActiveProjectCard_1 = require("./ActiveProjectCard");
|
|
44
|
-
const TabContext_1 = __importDefault(require("@material-ui/lab/TabContext"));
|
|
45
|
-
const TabPanel_1 = __importDefault(require("@material-ui/lab/TabPanel"));
|
|
46
|
-
const ProgressBar_1 = require("./ProgressBar");
|
|
47
|
-
const ActiveProjectCard_2 = require("./ActiveProjectCard");
|
|
48
|
-
const styled_components_1 = __importDefault(require("styled-components"));
|
|
49
|
-
const Pagination_1 = __importDefault(require("../Reviews/Pagination"));
|
|
50
|
-
const icons_1 = require("@material-ui/icons");
|
|
51
|
-
const moment_1 = __importDefault(require("moment"));
|
|
52
|
-
const Loader_1 = __importDefault(require("../shared/Loader"));
|
|
53
|
-
const Error_1 = __importDefault(require("../shared/Error"));
|
|
54
|
-
const DEFAULT_SORT_OPTIONS = [
|
|
55
|
-
{
|
|
56
|
-
label: 'Client Name',
|
|
57
|
-
value: 'Client Name',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
label: 'Unrealized Earnings',
|
|
61
|
-
value: 'Unrealized Earnings',
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
label: 'Fixed Projects',
|
|
65
|
-
value: 'Fixed Projects',
|
|
66
|
-
},
|
|
67
|
-
];
|
|
68
|
-
const StyledTabPanel = (0, styled_components_1.default)(TabPanel_1.default) `
|
|
69
|
-
padding: 0px;
|
|
70
|
-
padding-top: 18px;
|
|
71
|
-
margin: -6px;
|
|
72
|
-
`;
|
|
73
|
-
const EarningsTracker = ({ freelancerId, isAuthenticated, freelancerProjectDataUnauth, getPendingProjectTagReviews, getAllIrPrDetailsQuery, getFreelancerEarningData, updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation, GetParoProjectsDocument, updateProjectTagReviewStatusMutation, updateProjectStatus, updateProjectTags, sendParoSupportEmail, getSowLazyQuery, createChangeRequestMutation, createChangeRequest, createOrUpdateRatingRequestMutation, updateProjectTaskMutation, updateProjectTask, submitProjectHoursMutation, getAuth0Roles, submitProjectHoursLambda, user, router, }) => {
|
|
74
|
-
var _a, _b, _c, _d;
|
|
75
|
-
const theme = (0, core_1.useTheme)();
|
|
76
|
-
const params = new URLSearchParams(router.query);
|
|
77
|
-
const renewalsTabIndex = Number((_a = params.get('tab')) !== null && _a !== void 0 ? _a : 0);
|
|
78
|
-
const classes = (0, ActiveProjectCard_2.useStyles)();
|
|
79
|
-
const mobileScreen = (0, core_1.useMediaQuery)(theme.breakpoints.down('sm'));
|
|
80
|
-
const [selectedTab, setSelectedTab] = (0, react_1.useState)(renewalsTabIndex);
|
|
81
|
-
const sortOptions = selectedTab === 1 ? DEFAULT_SORT_OPTIONS : [{ label: 'Project Health Grade', value: 'Project Health Grade' }, ...DEFAULT_SORT_OPTIONS];
|
|
82
|
-
const [faqModal, setFaqModal] = react_1.default.useState(false);
|
|
83
|
-
const [earnings, setEarnings] = (0, react_1.useState)(0);
|
|
84
|
-
const [lifetimeIRToPR, setLifeTimeIRToPR] = (0, react_1.useState)(0);
|
|
85
|
-
const [currentPage, setCurrentPage] = (0, react_1.useState)(1);
|
|
86
|
-
const [perPageItems, setPerPageItems] = (0, react_1.useState)(10);
|
|
87
|
-
const [sortDirection, setSortDirection] = (0, react_1.useState)('asc');
|
|
88
|
-
const [sortBy, setSortBy] = (0, react_1.useState)(sortOptions[0].value);
|
|
89
|
-
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
90
|
-
const [pendingProjectTagReviewsData, setPendingProjectTagReviewsData] = (0, react_1.useState)([]);
|
|
91
|
-
const [freelancerProjectData, setFreelancerProjectData] = (0, react_1.useState)([]);
|
|
92
|
-
const [getProjectsError, setGetProjectsError] = (0, react_1.useState)(false);
|
|
93
|
-
const firstItem = (currentPage - 1) * perPageItems;
|
|
94
|
-
const lastItem = (currentPage - 1) * perPageItems + perPageItems;
|
|
95
|
-
const fetchQueries = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
|
-
var _a, _b;
|
|
97
|
-
try {
|
|
98
|
-
setLoading(true);
|
|
99
|
-
let pendingProjects;
|
|
100
|
-
let projectDetails;
|
|
101
|
-
const [pendingProjectTagResponse, projectDetailsResponse] = yield Promise.all([
|
|
102
|
-
getPendingProjectTagReviews && getPendingProjectTagReviews({
|
|
103
|
-
variables: {
|
|
104
|
-
freelancerId
|
|
105
|
-
},
|
|
106
|
-
skip: !freelancerId || [2, 3, 4].includes(selectedTab)
|
|
107
|
-
}),
|
|
108
|
-
getAllIrPrDetailsQuery && getAllIrPrDetailsQuery({
|
|
109
|
-
variables: {
|
|
110
|
-
freelancerId: freelancerId,
|
|
111
|
-
projectType: 3, //get hourly & fixed projects
|
|
112
|
-
activeTabId: 0, selectedTab,
|
|
113
|
-
isInternal: false
|
|
114
|
-
},
|
|
115
|
-
fetchPolicy: 'network-only',
|
|
116
|
-
})
|
|
117
|
-
]);
|
|
118
|
-
pendingProjects = ((_a = pendingProjectTagResponse === null || pendingProjectTagResponse === void 0 ? void 0 : pendingProjectTagResponse.data) === null || _a === void 0 ? void 0 : _a.getPendingProjectTagReviews) || [];
|
|
119
|
-
projectDetails = ((_b = projectDetailsResponse === null || projectDetailsResponse === void 0 ? void 0 : projectDetailsResponse.data) === null || _b === void 0 ? void 0 : _b.getAllProjectIRPRDetailsForFreelancer) || {};
|
|
120
|
-
setPendingProjectTagReviewsData(pendingProjects);
|
|
121
|
-
setFreelancerProjectData(projectDetails);
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
console.error("Error fetching queries:", error);
|
|
125
|
-
setGetProjectsError(true);
|
|
126
|
-
}
|
|
127
|
-
finally {
|
|
128
|
-
setLoading(false);
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
(0, react_1.useEffect)(() => {
|
|
132
|
-
if (isAuthenticated) {
|
|
133
|
-
fetchQueries();
|
|
134
|
-
}
|
|
135
|
-
}, [selectedTab, isAuthenticated]);
|
|
136
|
-
const tagReviewProjects = (pendingProjectTagReviewsData === null || pendingProjectTagReviewsData === void 0 ? void 0 : pendingProjectTagReviewsData.getPendingProjectTagReviews) || [];
|
|
137
|
-
const projectTagsMap = tagReviewProjects.reduce((acc, project) => {
|
|
138
|
-
var _a, _b;
|
|
139
|
-
return Object.assign(Object.assign({}, acc), { [project.id]: {
|
|
140
|
-
softwareTags: ((_a = project === null || project === void 0 ? void 0 : project.tags) === null || _a === void 0 ? void 0 : _a.reduce((acc, tag) => (tag === null || tag === void 0 ? void 0 : tag.field) === 'softwares' ? [...acc, tag.value] : acc, [])) || [],
|
|
141
|
-
skillTags: ((_b = project === null || project === void 0 ? void 0 : project.tags) === null || _b === void 0 ? void 0 : _b.reduce((acc, tag) => (tag === null || tag === void 0 ? void 0 : tag.field) === 'skills' ? [...acc, tag.value] : acc, [])) || [],
|
|
142
|
-
project
|
|
143
|
-
} });
|
|
144
|
-
}, {});
|
|
145
|
-
(0, react_1.useEffect)(() => {
|
|
146
|
-
if (!freelancerId)
|
|
147
|
-
return;
|
|
148
|
-
getFreelancerEarningData(freelancerId).then((data) => {
|
|
149
|
-
var _a;
|
|
150
|
-
if (data) {
|
|
151
|
-
const actualEarnings = ((_a = data === null || data === void 0 ? void 0 : data.results) === null || _a === void 0 ? void 0 : _a.length) > 0 && (data === null || data === void 0 ? void 0 : data.results.filter((earning) => earning.earnings_type === 'actual').reduce((acc, curr) => acc + curr.earnings, 0));
|
|
152
|
-
setEarnings(actualEarnings);
|
|
153
|
-
setLifeTimeIRToPR(data === null || data === void 0 ? void 0 : data.lifetime_ir_pr);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
}, [freelancerId]);
|
|
157
|
-
(0, react_1.useEffect)(() => {
|
|
158
|
-
if (selectedTab === 1 || selectedTab === 2) {
|
|
159
|
-
setSortBy('Start Date');
|
|
160
|
-
}
|
|
161
|
-
else if (selectedTab === 4) {
|
|
162
|
-
setSortBy('End Date');
|
|
163
|
-
}
|
|
164
|
-
else if (selectedTab === 3) {
|
|
165
|
-
setSortBy('Nearest');
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
setSortBy(sortOptions[0].value);
|
|
169
|
-
}
|
|
170
|
-
}, [selectedTab]);
|
|
171
|
-
if (selectedTab === 0 && isAuthenticated && (loading || !freelancerProjectData)) {
|
|
172
|
-
return react_1.default.createElement(Loader_1.default, null);
|
|
173
|
-
}
|
|
174
|
-
if (getProjectsError) {
|
|
175
|
-
return (react_1.default.createElement("div", { className: "mt-20" },
|
|
176
|
-
react_1.default.createElement(Error_1.default, { message: 'Error fetching your project data. Please refresh the page and try again.' })));
|
|
177
|
-
}
|
|
178
|
-
//@ts-ignore
|
|
179
|
-
const data = isAuthenticated ? freelancerProjectData !== null && freelancerProjectData !== void 0 ? freelancerProjectData : {} : freelancerProjectDataUnauth;
|
|
180
|
-
let averageInvoicedRevenue;
|
|
181
|
-
if (earnings > 0 && (data === null || data === void 0 ? void 0 : data.paroTenure) > 0) {
|
|
182
|
-
const invoicedRevenueData = earnings / (data === null || data === void 0 ? void 0 : data.paroTenure);
|
|
183
|
-
averageInvoicedRevenue = (invoicedRevenueData === null || invoicedRevenueData === void 0 ? void 0 : invoicedRevenueData.toFixed(2)) || 0;
|
|
184
|
-
}
|
|
185
|
-
const projectsArray = (_b = data === null || data === void 0 ? void 0 : data.projects) !== null && _b !== void 0 ? _b : [];
|
|
186
|
-
const projectsData = (_c = data === null || data === void 0 ? void 0 : data.projectsData) !== null && _c !== void 0 ? _c : [];
|
|
187
|
-
let projectDataContainer = new Map();
|
|
188
|
-
projectsArray.forEach((el) => projectDataContainer.set(el.id, el));
|
|
189
|
-
let sortedData = [];
|
|
190
|
-
projectsData === null || projectsData === void 0 ? void 0 : projectsData.forEach((el) => {
|
|
191
|
-
if (projectDataContainer.has(el.id)) {
|
|
192
|
-
sortedData === null || sortedData === void 0 ? void 0 : sortedData.push(Object.assign(Object.assign({}, el), projectDataContainer === null || projectDataContainer === void 0 ? void 0 : projectDataContainer.get(el.id)));
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
const healthOrder = { "!": 0, "D": 1, "C": 2, "B": 3, "A": 4 };
|
|
196
|
-
let sortedProjects = [];
|
|
197
|
-
const getSortKey = (project) => {
|
|
198
|
-
const health = project === null || project === void 0 ? void 0 : project.healthGrade;
|
|
199
|
-
const startDate = (project === null || project === void 0 ? void 0 : project.startDate) || null;
|
|
200
|
-
const endDate = (project === null || project === void 0 ? void 0 : project.endDate) || null;
|
|
201
|
-
//@ts-ignore
|
|
202
|
-
const healthKey = healthOrder[health] !== undefined ? healthOrder[health] : Infinity;
|
|
203
|
-
const startDateObj = startDate ? new Date(startDate) : null;
|
|
204
|
-
const endDateObj = endDate ? new Date(endDate) : null;
|
|
205
|
-
const projectName = project === null || project === void 0 ? void 0 : project.name;
|
|
206
|
-
return [healthKey, startDateObj, projectName, endDateObj];
|
|
207
|
-
};
|
|
208
|
-
if (sortBy) {
|
|
209
|
-
if (sortBy === "Project Health Grade") {
|
|
210
|
-
sortedProjects = sortedData.sort((a, b) => {
|
|
211
|
-
var _a, _b;
|
|
212
|
-
const orderA = healthOrder[a === null || a === void 0 ? void 0 : a.healthGrade];
|
|
213
|
-
const orderB = healthOrder[b === null || b === void 0 ? void 0 : b.healthGrade];
|
|
214
|
-
// for fixed projects
|
|
215
|
-
const rateTypeA = (_a = a === null || a === void 0 ? void 0 : a.projectScope) === null || _a === void 0 ? void 0 : _a.freelanceRateTypeId;
|
|
216
|
-
const rateTypeB = (_b = b === null || b === void 0 ? void 0 : b.projectScope) === null || _b === void 0 ? void 0 : _b.freelanceRateTypeId;
|
|
217
|
-
if (rateTypeA === 2 && rateTypeB === 2) {
|
|
218
|
-
return 0;
|
|
219
|
-
}
|
|
220
|
-
else if (rateTypeA === 2) {
|
|
221
|
-
return 1;
|
|
222
|
-
}
|
|
223
|
-
else if (rateTypeB === 2) {
|
|
224
|
-
return -1;
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
if (sortDirection === "asc") {
|
|
228
|
-
return orderA - orderB;
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
return orderB - orderA;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
else if (sortBy === "Client Name") {
|
|
237
|
-
sortedProjects = sortedData.sort((a, b) => {
|
|
238
|
-
var _a, _b;
|
|
239
|
-
const clientA = (_a = a === null || a === void 0 ? void 0 : a.client) === null || _a === void 0 ? void 0 : _a.name;
|
|
240
|
-
const clientB = (_b = b === null || b === void 0 ? void 0 : b.client) === null || _b === void 0 ? void 0 : _b.name;
|
|
241
|
-
if (sortDirection === "asc") {
|
|
242
|
-
return String(clientA).localeCompare(clientB);
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
return String(clientB).localeCompare(clientA);
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
else if (sortBy === "Unrealized Earnings") {
|
|
250
|
-
sortedProjects = sortedData.sort((a, b) => {
|
|
251
|
-
const unrealizedEarningsKey1 = (a === null || a === void 0 ? void 0 : a.maxHours) * (a === null || a === void 0 ? void 0 : a.expertRate);
|
|
252
|
-
const unrealizedEarningsKey2 = (b === null || b === void 0 ? void 0 : b.maxHours) * (b === null || b === void 0 ? void 0 : b.expertRate);
|
|
253
|
-
if (sortDirection === "asc") {
|
|
254
|
-
return unrealizedEarningsKey1 - unrealizedEarningsKey2;
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
return unrealizedEarningsKey2 - unrealizedEarningsKey1;
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
else if (sortBy === "Fixed Projects") {
|
|
262
|
-
sortedProjects = sortedData.sort((a, b) => {
|
|
263
|
-
var _a, _b;
|
|
264
|
-
const rateTypeA = (_a = a === null || a === void 0 ? void 0 : a.projectScope) === null || _a === void 0 ? void 0 : _a.freelanceRateTypeId;
|
|
265
|
-
const rateTypeB = (_b = b === null || b === void 0 ? void 0 : b.projectScope) === null || _b === void 0 ? void 0 : _b.freelanceRateTypeId;
|
|
266
|
-
if (rateTypeA === 2 && rateTypeB === 2) {
|
|
267
|
-
return sortDirection === "asc" ? +(0, moment_1.default)(a.startDate) - +(0, moment_1.default)(b.startDate) : +(0, moment_1.default)(b.startDate) - +(0, moment_1.default)(a.startDate);
|
|
268
|
-
}
|
|
269
|
-
else if (rateTypeA === 2) {
|
|
270
|
-
return -1;
|
|
271
|
-
}
|
|
272
|
-
else if (rateTypeB === 2) {
|
|
273
|
-
return 1;
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
return 0;
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
else if (sortBy === "Start Date") {
|
|
281
|
-
sortedProjects = sortedData === null || sortedData === void 0 ? void 0 : sortedData.slice().sort((a, b) => {
|
|
282
|
-
const keyA = getSortKey(a);
|
|
283
|
-
const keyB = getSortKey(b);
|
|
284
|
-
return keyA[1] - keyB[1];
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
else if (sortBy === "End Date") {
|
|
288
|
-
sortedProjects = sortedData === null || sortedData === void 0 ? void 0 : sortedData.slice().sort((a, b) => {
|
|
289
|
-
const keyA = getSortKey(a);
|
|
290
|
-
const keyB = getSortKey(b);
|
|
291
|
-
return keyB[3] - keyA[3];
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
else if (sortBy === "Nearest") {
|
|
295
|
-
sortedProjects = sortedData === null || sortedData === void 0 ? void 0 : sortedData.sort((a, b) => {
|
|
296
|
-
if (a.endDate === null && b.endDate === null) {
|
|
297
|
-
return 0;
|
|
298
|
-
}
|
|
299
|
-
else if (a.endDate === null) {
|
|
300
|
-
return 1;
|
|
301
|
-
}
|
|
302
|
-
else if (b.endDate === null) {
|
|
303
|
-
return -1;
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
const diffA = Math.abs((0, moment_1.default)(a.endDate).diff((0, moment_1.default)(), 'days'));
|
|
307
|
-
const diffB = Math.abs((0, moment_1.default)(b.endDate).diff((0, moment_1.default)(), 'days'));
|
|
308
|
-
return diffA - diffB;
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
const handleChangeValue = (event, newValue) => {
|
|
314
|
-
setSortBy(sortOptions[0].value);
|
|
315
|
-
setSortDirection('asc');
|
|
316
|
-
setSelectedTab(newValue);
|
|
317
|
-
};
|
|
318
|
-
const today = new Date();
|
|
319
|
-
const currMonth = today.toLocaleDateString('en-US', { month: 'long' });
|
|
320
|
-
const tabPanelProps = mobileScreen ? { component: StyledTabPanel } : { component: TabPanel_1.default };
|
|
321
|
-
const handleSort = (e) => {
|
|
322
|
-
setSortBy(e.currentTarget.value);
|
|
323
|
-
};
|
|
324
|
-
const handleSortDirectionChange = () => {
|
|
325
|
-
setSortDirection(sortDirection === "asc" ? "desc" : "asc");
|
|
326
|
-
let isKeyExist = sortOptions.find(i => i.value === sortBy);
|
|
327
|
-
if (!isKeyExist) {
|
|
328
|
-
setSortBy(sortOptions[0].value);
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
let unrealizedEarnings = 0;
|
|
332
|
-
const calculateTotalUnrealizedEarnings = (projectData) => {
|
|
333
|
-
var _a, _b, _c;
|
|
334
|
-
const payRate = (_a = projectData === null || projectData === void 0 ? void 0 : projectData.expertRate) !== null && _a !== void 0 ? _a : 0;
|
|
335
|
-
const loggedHours = (_b = projectData === null || projectData === void 0 ? void 0 : projectData.hoursInvoiced) !== null && _b !== void 0 ? _b : 0;
|
|
336
|
-
const maxHours = (_c = projectData === null || projectData === void 0 ? void 0 : projectData.maxHours) !== null && _c !== void 0 ? _c : 0;
|
|
337
|
-
const invoicedAmount = payRate * loggedHours;
|
|
338
|
-
const maxProjectEarnings = maxHours * payRate;
|
|
339
|
-
return maxProjectEarnings - invoicedAmount > 0 ? maxProjectEarnings - invoicedAmount : 0;
|
|
340
|
-
};
|
|
341
|
-
if (sortedData.length > 0) {
|
|
342
|
-
unrealizedEarnings = sortedData.reduce((acc, project) => {
|
|
343
|
-
return acc + calculateTotalUnrealizedEarnings(project);
|
|
344
|
-
}, 0);
|
|
345
|
-
}
|
|
346
|
-
const getTitle = () => {
|
|
347
|
-
switch (selectedTab) {
|
|
348
|
-
case 0:
|
|
349
|
-
return "Active";
|
|
350
|
-
case 1:
|
|
351
|
-
return "Ad Hoc";
|
|
352
|
-
case 2:
|
|
353
|
-
return "Upcoming";
|
|
354
|
-
case 3:
|
|
355
|
-
return "Inactive";
|
|
356
|
-
case 4:
|
|
357
|
-
return "Completed";
|
|
358
|
-
case 5:
|
|
359
|
-
return "Paused";
|
|
360
|
-
default:
|
|
361
|
-
return "Active";
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
return (react_1.default.createElement("div", { className: "flex flex-col w-full" },
|
|
365
|
-
react_1.default.createElement("h1", { className: "font-bold text-3xl ml-4", "data-tut": 'reactour__projectmanagement' }, "Earnings Tracker"),
|
|
366
|
-
loading && isAuthenticated ? react_1.default.createElement("div", { className: "m-8" },
|
|
367
|
-
react_1.default.createElement(Loader_1.default, null)) :
|
|
368
|
-
react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(base_ui_1.Card, { className: "w-full bg-white flex flex-col sm:flex-row justify-space-between p-8 m-4" },
|
|
369
|
-
selectedTab !== 1 && (react_1.default.createElement("div", { className: "flex flex-col w-full mb-4 md:mb-0" },
|
|
370
|
-
react_1.default.createElement("h1", { className: "font-bold text-xl ml-4" },
|
|
371
|
-
"Avg. Project Grading for ",
|
|
372
|
-
getTitle(),
|
|
373
|
-
" Projects"),
|
|
374
|
-
react_1.default.createElement("div", { className: "flex flex-row" },
|
|
375
|
-
react_1.default.createElement("div", { className: "flex flex-col items-center rounded-md bg-[#FDD8A5] p-4 m-4" },
|
|
376
|
-
react_1.default.createElement("p", null, "Hourly Projects"),
|
|
377
|
-
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "The average health card grade is based on all your active projects shown below.", placement: "top", arrow: true },
|
|
378
|
-
react_1.default.createElement("div", { className: "h-12 w-16 rounded-md flex place-content-center items-center m-1" }, ((_d = data === null || data === void 0 ? void 0 : data.overallProjectHealth) === null || _d === void 0 ? void 0 : _d.trim()) !== '' ? react_1.default.createElement("h1", { className: "font-bold text-2xl self-center" }, data === null || data === void 0 ? void 0 : data.overallProjectHealth) : react_1.default.createElement("h1", { className: "text-xl text-red-500" }, "N/A"))),
|
|
379
|
-
react_1.default.createElement("div", { className: 'flex items-center' },
|
|
380
|
-
react_1.default.createElement("p", null, "Why this score?"),
|
|
381
|
-
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "This grade does not have an impact on your standing with Paro but if you see a low grade or action required, please reach out to the Customer Success Team to help make sure you are staying up to date with your projects.", placement: "top", arrow: true },
|
|
382
|
-
react_1.default.createElement("div", null,
|
|
383
|
-
react_1.default.createElement(base_icons_1.IconInfoCircle, { size: "sm" }))))),
|
|
384
|
-
react_1.default.createElement("div", { className: "flex flex-col gap-y-4" },
|
|
385
|
-
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "The Minimum Floor Hours shows how many active projects you have currently completed the minimum floor hours requirement for and how many active projects that require minimum floor hours to be completed", placement: "top", arrow: true },
|
|
386
|
-
react_1.default.createElement("div", { className: "flex flex-row justify-content-start mt-4 bg-[#F1F5F9] p-1 rounded-md" },
|
|
387
|
-
react_1.default.createElement(ActiveProjectCard_1.CheckItem, { checked: ((data === null || data === void 0 ? void 0 : data.minFloorHoursCountNumerator) > 0 && (data === null || data === void 0 ? void 0 : data.minFloorHoursCountDenominator) > 0), text: "Avg. Min Floor Hours Completed" }),
|
|
388
|
-
react_1.default.createElement("div", { className: "p-2 w-1/5 border-2 border-solid border-[#F1F5F9] rounded-md flex place-content-center items-start" }, ((data === null || data === void 0 ? void 0 : data.minFloorHoursCountNumerator) >= 0 && (data === null || data === void 0 ? void 0 : data.minFloorHoursCountDenominator) >= 0) ? react_1.default.createElement("p", null, data === null || data === void 0 ? void 0 :
|
|
389
|
-
data.minFloorHoursCountNumerator,
|
|
390
|
-
"/", data === null || data === void 0 ? void 0 :
|
|
391
|
-
data.minFloorHoursCountDenominator) : react_1.default.createElement("p", { className: "text-xl text-red-500" }, "N/A")))),
|
|
392
|
-
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "The Weekly Minimum Hours shows if you have submitted hours for a given week for an active project. If so, a check mark will appear next to it on the project card below. This does not impact your project grade but is a reminder to log hours consistently.", placement: "top", arrow: true },
|
|
393
|
-
react_1.default.createElement("div", { className: "flex flex-row justify-content-start mb-4 bg-[#F1F5F9] p-1 rounded-md" },
|
|
394
|
-
react_1.default.createElement(ActiveProjectCard_1.CheckItem, { checked: ((data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountNumerator) > 0 && (data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountDenominator) > 0), text: "Avg. Weekly Min Hours Logged" }),
|
|
395
|
-
react_1.default.createElement("div", { className: "p-2 w-1/5 border-2 border-solid border-[#F1F5F9] rounded-md flex place-content-center items-start" }, ((data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountNumerator) >= 0 && (data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountDenominator) >= 0) ? react_1.default.createElement("p", null, data === null || data === void 0 ? void 0 :
|
|
396
|
-
data.weeklyMinHoursLoggedCountNumerator,
|
|
397
|
-
"/", data === null || data === void 0 ? void 0 :
|
|
398
|
-
data.weeklyMinHoursLoggedCountDenominator) : react_1.default.createElement("p", { className: "text-xl text-red-500" }, "N/A")))))))),
|
|
399
|
-
react_1.default.createElement("div", { className: "flex flex-col w-full mb-4 md:mb-0" },
|
|
400
|
-
react_1.default.createElement("h1", { className: "font-bold text-xl ml-4" }, "Monthly Earnings"),
|
|
401
|
-
react_1.default.createElement("div", { className: "flex flex-row justify-items-stretch gap-x-4 p-4" },
|
|
402
|
-
react_1.default.createElement("div", { className: "flex flex-col bg-[#F1F5F9] p-4 text-md rounded-md w-1/2", "data-tut": 'reactour__monthlyearnings' },
|
|
403
|
-
react_1.default.createElement("p", null, currMonth),
|
|
404
|
-
(data === null || data === void 0 ? void 0 : data.monthlyEarnings) > 0 ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
405
|
-
"$ ",
|
|
406
|
-
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.monthlyEarnings)) : react_1.default.createElement("h1", { className: "text-xl font-bold" }, "$ 0"),
|
|
407
|
-
(data === null || data === void 0 ? void 0 : data.expertCurrMonthGoal) >= 0 ? react_1.default.createElement("p", { className: "text-sm" },
|
|
408
|
-
"Goal: $ ",
|
|
409
|
-
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.expertCurrMonthGoal)) : react_1.default.createElement("p", { className: "text-sm" },
|
|
410
|
-
react_1.default.createElement("small", null, "Goal: No Goal set for current month"),
|
|
411
|
-
" ")),
|
|
412
|
-
react_1.default.createElement("div", { className: "flex flex-col bg-[#F1F5F9] p-4 text-md rounded-md w-1/2" },
|
|
413
|
-
react_1.default.createElement("p", null, "Avg./Month"),
|
|
414
|
-
averageInvoicedRevenue ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
415
|
-
"$ ",
|
|
416
|
-
(0, ProgressBar_1.formatNumberingSystem)(averageInvoicedRevenue)) : react_1.default.createElement("h1", { className: "text-xl font-bold" }, "$ 0"),
|
|
417
|
-
(data === null || data === void 0 ? void 0 : data.freelancerGoal) >= 0 ? react_1.default.createElement("p", { className: "text-sm" },
|
|
418
|
-
"Avg Goal: $ ",
|
|
419
|
-
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.freelancerGoal)) : react_1.default.createElement("p", { className: "text-sm" },
|
|
420
|
-
react_1.default.createElement("small", null, "Avg Goal: No Monthly Goal Set"),
|
|
421
|
-
" ")))),
|
|
422
|
-
react_1.default.createElement("div", { className: "flex flex-col w-full" },
|
|
423
|
-
react_1.default.createElement("h1", { className: "font-bold text-xl ml-4" }, "Lifetime Earnings Health"),
|
|
424
|
-
react_1.default.createElement("div", { className: "flex flex-col justify-between p-4 gap-y-4" },
|
|
425
|
-
react_1.default.createElement("div", { className: "flex flex-row justify-between bg-[#F1F5F9] p-2 px-4 text-md rounded-md" },
|
|
426
|
-
react_1.default.createElement("p", null, "Invoiced to Projected:"),
|
|
427
|
-
lifetimeIRToPR > 0 ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
428
|
-
(0, ProgressBar_1.formatNumberingSystem)(lifetimeIRToPR),
|
|
429
|
-
"%") : react_1.default.createElement("h1", { className: "text-xl font-bold" }, "--")),
|
|
430
|
-
react_1.default.createElement("div", { className: "flex flex-row justify-between bg-[#F1F5F9] p-2 px-4 text-md rounded-md" },
|
|
431
|
-
react_1.default.createElement("p", null, "Avg Contract Value:"),
|
|
432
|
-
(data === null || data === void 0 ? void 0 : data.averageContractValue) > 0 ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
433
|
-
"$",
|
|
434
|
-
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.averageContractValue)) : react_1.default.createElement("h1", { className: "text-sm text-red-500 w-36" }, "Data will appear once you have won your first project")),
|
|
435
|
-
react_1.default.createElement("div", { className: "flex flex-row justify-between bg-[#F1F5F9] p-2 px-4 text-md rounded-md" },
|
|
436
|
-
react_1.default.createElement("p", null,
|
|
437
|
-
"Total Unrealized Earnings for ",
|
|
438
|
-
getTitle(),
|
|
439
|
-
" Projects:"),
|
|
440
|
-
react_1.default.createElement("h1", { className: "text-xl font-bold", "data-tut": 'reactour__totalunrealizedearnings' },
|
|
441
|
-
"$",
|
|
442
|
-
(0, ProgressBar_1.formatNumberingSystem)(unrealizedEarnings))))))),
|
|
443
|
-
!isAuthenticated && react_1.default.createElement("div", { className: 'border ml-4 w-full text-white rounded-md bg-[#1878bd]' },
|
|
444
|
-
react_1.default.createElement("ul", { className: "list-disc px-8 py-3" },
|
|
445
|
-
react_1.default.createElement("li", null, "The projects shown below are only your active projects."),
|
|
446
|
-
react_1.default.createElement("li", null,
|
|
447
|
-
"Please ",
|
|
448
|
-
react_1.default.createElement("a", { className: 'underline font-bold', href: "/earnings-tracker", target: "_blank" }, "log in"),
|
|
449
|
-
" here to view all your projects that are Upcoming, Ad Hoc, Completed, or Inactive."),
|
|
450
|
-
react_1.default.createElement("li", null, "Active projects will show up 7 days before they start for you to make changes and keep track of reporting."))),
|
|
451
|
-
react_1.default.createElement("div", { className: "m-4 w-full" },
|
|
452
|
-
react_1.default.createElement(TabContext_1.default, { value: selectedTab + '' },
|
|
453
|
-
react_1.default.createElement(core_1.Tabs, { TabIndicatorProps: { style: { background: '#248384' } }, value: selectedTab, onChange: handleChangeValue, variant: "scrollable", scrollButtons: "off" },
|
|
454
|
-
react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Active") }),
|
|
455
|
-
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Ad Hoc") })),
|
|
456
|
-
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center", "data-tut": 'reacttour__upcomingsubheader' }, "\u00A0Upcoming") })),
|
|
457
|
-
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Inactive") })),
|
|
458
|
-
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Completed") })),
|
|
459
|
-
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Paused") }))),
|
|
460
|
-
((sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) > 0 || (isAuthenticated && !loading)) && selectedTab !== 5 &&
|
|
461
|
-
react_1.default.createElement("div", { className: 'flex items-end gap-2 w-full justify-end mt-4', "data-tut": 'reacttour__sortby' },
|
|
462
|
-
react_1.default.createElement(base_ui_1.Select, { label: "Sort by", required: false, value: sortBy, onChange: e => handleSort(e), options: sortOptions, className: 'max-w-fit' }),
|
|
463
|
-
react_1.default.createElement(core_1.IconButton, { onClick: handleSortDirectionChange, title: sortDirection }, sortDirection === "asc" ? react_1.default.createElement(icons_1.ArrowUpwardRounded, null) : react_1.default.createElement(icons_1.ArrowDownwardRounded, null))),
|
|
464
|
-
react_1.default.createElement(tabPanelProps.component, { value: 0 + '' }, loading && isAuthenticated ? react_1.default.createElement(Loader_1.default, null) :
|
|
465
|
-
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
466
|
-
react_1.default.createElement("p", null,
|
|
467
|
-
"You currently have no active hourly projects. ",
|
|
468
|
-
react_1.default.createElement("a", { className: "underline cursor-pointer", onClick: () => { setFaqModal(true); } }, "Learn more"),
|
|
469
|
-
" about winning projects here or visit the ",
|
|
470
|
-
react_1.default.createElement("a", { className: "underline cursor-pointer", href: "/opportunities", target: "_blank" }, "opportunity board"),
|
|
471
|
-
".")) :
|
|
472
|
-
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
473
|
-
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: true, selectedTab: selectedTab, projectTagsMap: projectTagsMap, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
474
|
-
})))),
|
|
475
|
-
react_1.default.createElement(tabPanelProps.component, { value: 1 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
476
|
-
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
477
|
-
react_1.default.createElement("p", null, "You have no Ad Hoc projects at this time.")) :
|
|
478
|
-
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
479
|
-
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: true, adhocProject: true, selectedTab: selectedTab, projectTagsMap: projectTagsMap, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
480
|
-
})))),
|
|
481
|
-
react_1.default.createElement(tabPanelProps.component, { value: 2 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
482
|
-
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
483
|
-
react_1.default.createElement("p", null, "You have no upcoming projects at this time.")) :
|
|
484
|
-
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
485
|
-
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: false, upcomingProject: true, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
486
|
-
})))),
|
|
487
|
-
react_1.default.createElement(tabPanelProps.component, { value: 3 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
488
|
-
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
489
|
-
react_1.default.createElement("p", null, "You have no Inactive projects at this time.")) :
|
|
490
|
-
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
491
|
-
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: false, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
492
|
-
})))),
|
|
493
|
-
react_1.default.createElement(tabPanelProps.component, { value: 4 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
494
|
-
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
495
|
-
react_1.default.createElement("p", null, "You currently have no completed projects.")) :
|
|
496
|
-
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
497
|
-
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: false, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
498
|
-
})))),
|
|
499
|
-
react_1.default.createElement(tabPanelProps.component, { value: 5 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
500
|
-
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
501
|
-
react_1.default.createElement("p", null, "You currently have no paused projects.")) :
|
|
502
|
-
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
503
|
-
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: true, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
504
|
-
})))),
|
|
505
|
-
(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) > 10 && (react_1.default.createElement("div", { className: `${!mobileScreen && "mx-7"}` },
|
|
506
|
-
react_1.default.createElement(Pagination_1.default, { total: sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length, currentPage: currentPage, setCurrentPage: setCurrentPage, perPageItems: perPageItems, setPerPageItems: setPerPageItems, displayText: "projects" })))))));
|
|
507
|
-
};
|
|
508
|
-
exports.EarningsTracker = EarningsTracker;
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.EarningsTracker = void 0;
|
|
39
|
+
const react_1 = __importStar(require("react"));
|
|
40
|
+
const core_1 = require("@material-ui/core");
|
|
41
|
+
const base_icons_1 = require("@paro.io/base-icons");
|
|
42
|
+
const base_ui_1 = require("@paro.io/base-ui");
|
|
43
|
+
const ActiveProjectCard_1 = require("./ActiveProjectCard");
|
|
44
|
+
const TabContext_1 = __importDefault(require("@material-ui/lab/TabContext"));
|
|
45
|
+
const TabPanel_1 = __importDefault(require("@material-ui/lab/TabPanel"));
|
|
46
|
+
const ProgressBar_1 = require("./ProgressBar");
|
|
47
|
+
const ActiveProjectCard_2 = require("./ActiveProjectCard");
|
|
48
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
49
|
+
const Pagination_1 = __importDefault(require("../Reviews/Pagination"));
|
|
50
|
+
const icons_1 = require("@material-ui/icons");
|
|
51
|
+
const moment_1 = __importDefault(require("moment"));
|
|
52
|
+
const Loader_1 = __importDefault(require("../shared/Loader"));
|
|
53
|
+
const Error_1 = __importDefault(require("../shared/Error"));
|
|
54
|
+
const DEFAULT_SORT_OPTIONS = [
|
|
55
|
+
{
|
|
56
|
+
label: 'Client Name',
|
|
57
|
+
value: 'Client Name',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
label: 'Unrealized Earnings',
|
|
61
|
+
value: 'Unrealized Earnings',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
label: 'Fixed Projects',
|
|
65
|
+
value: 'Fixed Projects',
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
const StyledTabPanel = (0, styled_components_1.default)(TabPanel_1.default) `
|
|
69
|
+
padding: 0px;
|
|
70
|
+
padding-top: 18px;
|
|
71
|
+
margin: -6px;
|
|
72
|
+
`;
|
|
73
|
+
const EarningsTracker = ({ freelancerId, isAuthenticated, freelancerProjectDataUnauth, getPendingProjectTagReviews, getAllIrPrDetailsQuery, getFreelancerEarningData, updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation, GetParoProjectsDocument, updateProjectTagReviewStatusMutation, updateProjectStatus, updateProjectTags, sendParoSupportEmail, getSowLazyQuery, createChangeRequestMutation, createChangeRequest, createOrUpdateRatingRequestMutation, updateProjectTaskMutation, updateProjectTask, submitProjectHoursMutation, getAuth0Roles, submitProjectHoursLambda, user, router, }) => {
|
|
74
|
+
var _a, _b, _c, _d;
|
|
75
|
+
const theme = (0, core_1.useTheme)();
|
|
76
|
+
const params = new URLSearchParams(router.query);
|
|
77
|
+
const renewalsTabIndex = Number((_a = params.get('tab')) !== null && _a !== void 0 ? _a : 0);
|
|
78
|
+
const classes = (0, ActiveProjectCard_2.useStyles)();
|
|
79
|
+
const mobileScreen = (0, core_1.useMediaQuery)(theme.breakpoints.down('sm'));
|
|
80
|
+
const [selectedTab, setSelectedTab] = (0, react_1.useState)(renewalsTabIndex);
|
|
81
|
+
const sortOptions = selectedTab === 1 ? DEFAULT_SORT_OPTIONS : [{ label: 'Project Health Grade', value: 'Project Health Grade' }, ...DEFAULT_SORT_OPTIONS];
|
|
82
|
+
const [faqModal, setFaqModal] = react_1.default.useState(false);
|
|
83
|
+
const [earnings, setEarnings] = (0, react_1.useState)(0);
|
|
84
|
+
const [lifetimeIRToPR, setLifeTimeIRToPR] = (0, react_1.useState)(0);
|
|
85
|
+
const [currentPage, setCurrentPage] = (0, react_1.useState)(1);
|
|
86
|
+
const [perPageItems, setPerPageItems] = (0, react_1.useState)(10);
|
|
87
|
+
const [sortDirection, setSortDirection] = (0, react_1.useState)('asc');
|
|
88
|
+
const [sortBy, setSortBy] = (0, react_1.useState)(sortOptions[0].value);
|
|
89
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
90
|
+
const [pendingProjectTagReviewsData, setPendingProjectTagReviewsData] = (0, react_1.useState)([]);
|
|
91
|
+
const [freelancerProjectData, setFreelancerProjectData] = (0, react_1.useState)([]);
|
|
92
|
+
const [getProjectsError, setGetProjectsError] = (0, react_1.useState)(false);
|
|
93
|
+
const firstItem = (currentPage - 1) * perPageItems;
|
|
94
|
+
const lastItem = (currentPage - 1) * perPageItems + perPageItems;
|
|
95
|
+
const fetchQueries = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
|
+
var _a, _b;
|
|
97
|
+
try {
|
|
98
|
+
setLoading(true);
|
|
99
|
+
let pendingProjects;
|
|
100
|
+
let projectDetails;
|
|
101
|
+
const [pendingProjectTagResponse, projectDetailsResponse] = yield Promise.all([
|
|
102
|
+
getPendingProjectTagReviews && getPendingProjectTagReviews({
|
|
103
|
+
variables: {
|
|
104
|
+
freelancerId
|
|
105
|
+
},
|
|
106
|
+
skip: !freelancerId || [2, 3, 4].includes(selectedTab)
|
|
107
|
+
}),
|
|
108
|
+
getAllIrPrDetailsQuery && getAllIrPrDetailsQuery({
|
|
109
|
+
variables: {
|
|
110
|
+
freelancerId: freelancerId,
|
|
111
|
+
projectType: 3, //get hourly & fixed projects
|
|
112
|
+
activeTabId: 0, selectedTab,
|
|
113
|
+
isInternal: false
|
|
114
|
+
},
|
|
115
|
+
fetchPolicy: 'network-only',
|
|
116
|
+
})
|
|
117
|
+
]);
|
|
118
|
+
pendingProjects = ((_a = pendingProjectTagResponse === null || pendingProjectTagResponse === void 0 ? void 0 : pendingProjectTagResponse.data) === null || _a === void 0 ? void 0 : _a.getPendingProjectTagReviews) || [];
|
|
119
|
+
projectDetails = ((_b = projectDetailsResponse === null || projectDetailsResponse === void 0 ? void 0 : projectDetailsResponse.data) === null || _b === void 0 ? void 0 : _b.getAllProjectIRPRDetailsForFreelancer) || {};
|
|
120
|
+
setPendingProjectTagReviewsData(pendingProjects);
|
|
121
|
+
setFreelancerProjectData(projectDetails);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error("Error fetching queries:", error);
|
|
125
|
+
setGetProjectsError(true);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
setLoading(false);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
(0, react_1.useEffect)(() => {
|
|
132
|
+
if (isAuthenticated) {
|
|
133
|
+
fetchQueries();
|
|
134
|
+
}
|
|
135
|
+
}, [selectedTab, isAuthenticated]);
|
|
136
|
+
const tagReviewProjects = (pendingProjectTagReviewsData === null || pendingProjectTagReviewsData === void 0 ? void 0 : pendingProjectTagReviewsData.getPendingProjectTagReviews) || [];
|
|
137
|
+
const projectTagsMap = tagReviewProjects.reduce((acc, project) => {
|
|
138
|
+
var _a, _b;
|
|
139
|
+
return Object.assign(Object.assign({}, acc), { [project.id]: {
|
|
140
|
+
softwareTags: ((_a = project === null || project === void 0 ? void 0 : project.tags) === null || _a === void 0 ? void 0 : _a.reduce((acc, tag) => (tag === null || tag === void 0 ? void 0 : tag.field) === 'softwares' ? [...acc, tag.value] : acc, [])) || [],
|
|
141
|
+
skillTags: ((_b = project === null || project === void 0 ? void 0 : project.tags) === null || _b === void 0 ? void 0 : _b.reduce((acc, tag) => (tag === null || tag === void 0 ? void 0 : tag.field) === 'skills' ? [...acc, tag.value] : acc, [])) || [],
|
|
142
|
+
project
|
|
143
|
+
} });
|
|
144
|
+
}, {});
|
|
145
|
+
(0, react_1.useEffect)(() => {
|
|
146
|
+
if (!freelancerId)
|
|
147
|
+
return;
|
|
148
|
+
getFreelancerEarningData(freelancerId).then((data) => {
|
|
149
|
+
var _a;
|
|
150
|
+
if (data) {
|
|
151
|
+
const actualEarnings = ((_a = data === null || data === void 0 ? void 0 : data.results) === null || _a === void 0 ? void 0 : _a.length) > 0 && (data === null || data === void 0 ? void 0 : data.results.filter((earning) => earning.earnings_type === 'actual').reduce((acc, curr) => acc + curr.earnings, 0));
|
|
152
|
+
setEarnings(actualEarnings);
|
|
153
|
+
setLifeTimeIRToPR(data === null || data === void 0 ? void 0 : data.lifetime_ir_pr);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}, [freelancerId]);
|
|
157
|
+
(0, react_1.useEffect)(() => {
|
|
158
|
+
if (selectedTab === 1 || selectedTab === 2) {
|
|
159
|
+
setSortBy('Start Date');
|
|
160
|
+
}
|
|
161
|
+
else if (selectedTab === 4) {
|
|
162
|
+
setSortBy('End Date');
|
|
163
|
+
}
|
|
164
|
+
else if (selectedTab === 3) {
|
|
165
|
+
setSortBy('Nearest');
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
setSortBy(sortOptions[0].value);
|
|
169
|
+
}
|
|
170
|
+
}, [selectedTab]);
|
|
171
|
+
if (selectedTab === 0 && isAuthenticated && (loading || !freelancerProjectData)) {
|
|
172
|
+
return react_1.default.createElement(Loader_1.default, null);
|
|
173
|
+
}
|
|
174
|
+
if (getProjectsError) {
|
|
175
|
+
return (react_1.default.createElement("div", { className: "mt-20" },
|
|
176
|
+
react_1.default.createElement(Error_1.default, { message: 'Error fetching your project data. Please refresh the page and try again.' })));
|
|
177
|
+
}
|
|
178
|
+
//@ts-ignore
|
|
179
|
+
const data = isAuthenticated ? freelancerProjectData !== null && freelancerProjectData !== void 0 ? freelancerProjectData : {} : freelancerProjectDataUnauth;
|
|
180
|
+
let averageInvoicedRevenue;
|
|
181
|
+
if (earnings > 0 && (data === null || data === void 0 ? void 0 : data.paroTenure) > 0) {
|
|
182
|
+
const invoicedRevenueData = earnings / (data === null || data === void 0 ? void 0 : data.paroTenure);
|
|
183
|
+
averageInvoicedRevenue = (invoicedRevenueData === null || invoicedRevenueData === void 0 ? void 0 : invoicedRevenueData.toFixed(2)) || 0;
|
|
184
|
+
}
|
|
185
|
+
const projectsArray = (_b = data === null || data === void 0 ? void 0 : data.projects) !== null && _b !== void 0 ? _b : [];
|
|
186
|
+
const projectsData = (_c = data === null || data === void 0 ? void 0 : data.projectsData) !== null && _c !== void 0 ? _c : [];
|
|
187
|
+
let projectDataContainer = new Map();
|
|
188
|
+
projectsArray.forEach((el) => projectDataContainer.set(el.id, el));
|
|
189
|
+
let sortedData = [];
|
|
190
|
+
projectsData === null || projectsData === void 0 ? void 0 : projectsData.forEach((el) => {
|
|
191
|
+
if (projectDataContainer.has(el.id)) {
|
|
192
|
+
sortedData === null || sortedData === void 0 ? void 0 : sortedData.push(Object.assign(Object.assign({}, el), projectDataContainer === null || projectDataContainer === void 0 ? void 0 : projectDataContainer.get(el.id)));
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
const healthOrder = { "!": 0, "D": 1, "C": 2, "B": 3, "A": 4 };
|
|
196
|
+
let sortedProjects = [];
|
|
197
|
+
const getSortKey = (project) => {
|
|
198
|
+
const health = project === null || project === void 0 ? void 0 : project.healthGrade;
|
|
199
|
+
const startDate = (project === null || project === void 0 ? void 0 : project.startDate) || null;
|
|
200
|
+
const endDate = (project === null || project === void 0 ? void 0 : project.endDate) || null;
|
|
201
|
+
//@ts-ignore
|
|
202
|
+
const healthKey = healthOrder[health] !== undefined ? healthOrder[health] : Infinity;
|
|
203
|
+
const startDateObj = startDate ? new Date(startDate) : null;
|
|
204
|
+
const endDateObj = endDate ? new Date(endDate) : null;
|
|
205
|
+
const projectName = project === null || project === void 0 ? void 0 : project.name;
|
|
206
|
+
return [healthKey, startDateObj, projectName, endDateObj];
|
|
207
|
+
};
|
|
208
|
+
if (sortBy) {
|
|
209
|
+
if (sortBy === "Project Health Grade") {
|
|
210
|
+
sortedProjects = sortedData.sort((a, b) => {
|
|
211
|
+
var _a, _b;
|
|
212
|
+
const orderA = healthOrder[a === null || a === void 0 ? void 0 : a.healthGrade];
|
|
213
|
+
const orderB = healthOrder[b === null || b === void 0 ? void 0 : b.healthGrade];
|
|
214
|
+
// for fixed projects
|
|
215
|
+
const rateTypeA = (_a = a === null || a === void 0 ? void 0 : a.projectScope) === null || _a === void 0 ? void 0 : _a.freelanceRateTypeId;
|
|
216
|
+
const rateTypeB = (_b = b === null || b === void 0 ? void 0 : b.projectScope) === null || _b === void 0 ? void 0 : _b.freelanceRateTypeId;
|
|
217
|
+
if (rateTypeA === 2 && rateTypeB === 2) {
|
|
218
|
+
return 0;
|
|
219
|
+
}
|
|
220
|
+
else if (rateTypeA === 2) {
|
|
221
|
+
return 1;
|
|
222
|
+
}
|
|
223
|
+
else if (rateTypeB === 2) {
|
|
224
|
+
return -1;
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
if (sortDirection === "asc") {
|
|
228
|
+
return orderA - orderB;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return orderB - orderA;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
else if (sortBy === "Client Name") {
|
|
237
|
+
sortedProjects = sortedData.sort((a, b) => {
|
|
238
|
+
var _a, _b;
|
|
239
|
+
const clientA = (_a = a === null || a === void 0 ? void 0 : a.client) === null || _a === void 0 ? void 0 : _a.name;
|
|
240
|
+
const clientB = (_b = b === null || b === void 0 ? void 0 : b.client) === null || _b === void 0 ? void 0 : _b.name;
|
|
241
|
+
if (sortDirection === "asc") {
|
|
242
|
+
return String(clientA).localeCompare(clientB);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
return String(clientB).localeCompare(clientA);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
else if (sortBy === "Unrealized Earnings") {
|
|
250
|
+
sortedProjects = sortedData.sort((a, b) => {
|
|
251
|
+
const unrealizedEarningsKey1 = (a === null || a === void 0 ? void 0 : a.maxHours) * (a === null || a === void 0 ? void 0 : a.expertRate);
|
|
252
|
+
const unrealizedEarningsKey2 = (b === null || b === void 0 ? void 0 : b.maxHours) * (b === null || b === void 0 ? void 0 : b.expertRate);
|
|
253
|
+
if (sortDirection === "asc") {
|
|
254
|
+
return unrealizedEarningsKey1 - unrealizedEarningsKey2;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
return unrealizedEarningsKey2 - unrealizedEarningsKey1;
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
else if (sortBy === "Fixed Projects") {
|
|
262
|
+
sortedProjects = sortedData.sort((a, b) => {
|
|
263
|
+
var _a, _b;
|
|
264
|
+
const rateTypeA = (_a = a === null || a === void 0 ? void 0 : a.projectScope) === null || _a === void 0 ? void 0 : _a.freelanceRateTypeId;
|
|
265
|
+
const rateTypeB = (_b = b === null || b === void 0 ? void 0 : b.projectScope) === null || _b === void 0 ? void 0 : _b.freelanceRateTypeId;
|
|
266
|
+
if (rateTypeA === 2 && rateTypeB === 2) {
|
|
267
|
+
return sortDirection === "asc" ? +(0, moment_1.default)(a.startDate) - +(0, moment_1.default)(b.startDate) : +(0, moment_1.default)(b.startDate) - +(0, moment_1.default)(a.startDate);
|
|
268
|
+
}
|
|
269
|
+
else if (rateTypeA === 2) {
|
|
270
|
+
return -1;
|
|
271
|
+
}
|
|
272
|
+
else if (rateTypeB === 2) {
|
|
273
|
+
return 1;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
return 0;
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
else if (sortBy === "Start Date") {
|
|
281
|
+
sortedProjects = sortedData === null || sortedData === void 0 ? void 0 : sortedData.slice().sort((a, b) => {
|
|
282
|
+
const keyA = getSortKey(a);
|
|
283
|
+
const keyB = getSortKey(b);
|
|
284
|
+
return keyA[1] - keyB[1];
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
else if (sortBy === "End Date") {
|
|
288
|
+
sortedProjects = sortedData === null || sortedData === void 0 ? void 0 : sortedData.slice().sort((a, b) => {
|
|
289
|
+
const keyA = getSortKey(a);
|
|
290
|
+
const keyB = getSortKey(b);
|
|
291
|
+
return keyB[3] - keyA[3];
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
else if (sortBy === "Nearest") {
|
|
295
|
+
sortedProjects = sortedData === null || sortedData === void 0 ? void 0 : sortedData.sort((a, b) => {
|
|
296
|
+
if (a.endDate === null && b.endDate === null) {
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
299
|
+
else if (a.endDate === null) {
|
|
300
|
+
return 1;
|
|
301
|
+
}
|
|
302
|
+
else if (b.endDate === null) {
|
|
303
|
+
return -1;
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const diffA = Math.abs((0, moment_1.default)(a.endDate).diff((0, moment_1.default)(), 'days'));
|
|
307
|
+
const diffB = Math.abs((0, moment_1.default)(b.endDate).diff((0, moment_1.default)(), 'days'));
|
|
308
|
+
return diffA - diffB;
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const handleChangeValue = (event, newValue) => {
|
|
314
|
+
setSortBy(sortOptions[0].value);
|
|
315
|
+
setSortDirection('asc');
|
|
316
|
+
setSelectedTab(newValue);
|
|
317
|
+
};
|
|
318
|
+
const today = new Date();
|
|
319
|
+
const currMonth = today.toLocaleDateString('en-US', { month: 'long' });
|
|
320
|
+
const tabPanelProps = mobileScreen ? { component: StyledTabPanel } : { component: TabPanel_1.default };
|
|
321
|
+
const handleSort = (e) => {
|
|
322
|
+
setSortBy(e.currentTarget.value);
|
|
323
|
+
};
|
|
324
|
+
const handleSortDirectionChange = () => {
|
|
325
|
+
setSortDirection(sortDirection === "asc" ? "desc" : "asc");
|
|
326
|
+
let isKeyExist = sortOptions.find(i => i.value === sortBy);
|
|
327
|
+
if (!isKeyExist) {
|
|
328
|
+
setSortBy(sortOptions[0].value);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
let unrealizedEarnings = 0;
|
|
332
|
+
const calculateTotalUnrealizedEarnings = (projectData) => {
|
|
333
|
+
var _a, _b, _c;
|
|
334
|
+
const payRate = (_a = projectData === null || projectData === void 0 ? void 0 : projectData.expertRate) !== null && _a !== void 0 ? _a : 0;
|
|
335
|
+
const loggedHours = (_b = projectData === null || projectData === void 0 ? void 0 : projectData.hoursInvoiced) !== null && _b !== void 0 ? _b : 0;
|
|
336
|
+
const maxHours = (_c = projectData === null || projectData === void 0 ? void 0 : projectData.maxHours) !== null && _c !== void 0 ? _c : 0;
|
|
337
|
+
const invoicedAmount = payRate * loggedHours;
|
|
338
|
+
const maxProjectEarnings = maxHours * payRate;
|
|
339
|
+
return maxProjectEarnings - invoicedAmount > 0 ? maxProjectEarnings - invoicedAmount : 0;
|
|
340
|
+
};
|
|
341
|
+
if (sortedData.length > 0) {
|
|
342
|
+
unrealizedEarnings = sortedData.reduce((acc, project) => {
|
|
343
|
+
return acc + calculateTotalUnrealizedEarnings(project);
|
|
344
|
+
}, 0);
|
|
345
|
+
}
|
|
346
|
+
const getTitle = () => {
|
|
347
|
+
switch (selectedTab) {
|
|
348
|
+
case 0:
|
|
349
|
+
return "Active";
|
|
350
|
+
case 1:
|
|
351
|
+
return "Ad Hoc";
|
|
352
|
+
case 2:
|
|
353
|
+
return "Upcoming";
|
|
354
|
+
case 3:
|
|
355
|
+
return "Inactive";
|
|
356
|
+
case 4:
|
|
357
|
+
return "Completed";
|
|
358
|
+
case 5:
|
|
359
|
+
return "Paused";
|
|
360
|
+
default:
|
|
361
|
+
return "Active";
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
return (react_1.default.createElement("div", { className: "flex flex-col w-full" },
|
|
365
|
+
react_1.default.createElement("h1", { className: "font-bold text-3xl ml-4", "data-tut": 'reactour__projectmanagement' }, "Earnings Tracker"),
|
|
366
|
+
loading && isAuthenticated ? react_1.default.createElement("div", { className: "m-8" },
|
|
367
|
+
react_1.default.createElement(Loader_1.default, null)) :
|
|
368
|
+
react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(base_ui_1.Card, { className: "w-full bg-white flex flex-col sm:flex-row justify-space-between p-8 m-4" },
|
|
369
|
+
selectedTab !== 1 && (react_1.default.createElement("div", { className: "flex flex-col w-full mb-4 md:mb-0" },
|
|
370
|
+
react_1.default.createElement("h1", { className: "font-bold text-xl ml-4" },
|
|
371
|
+
"Avg. Project Grading for ",
|
|
372
|
+
getTitle(),
|
|
373
|
+
" Projects"),
|
|
374
|
+
react_1.default.createElement("div", { className: "flex flex-row" },
|
|
375
|
+
react_1.default.createElement("div", { className: "flex flex-col items-center rounded-md bg-[#FDD8A5] p-4 m-4" },
|
|
376
|
+
react_1.default.createElement("p", null, "Hourly Projects"),
|
|
377
|
+
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "The average health card grade is based on all your active projects shown below.", placement: "top", arrow: true },
|
|
378
|
+
react_1.default.createElement("div", { className: "h-12 w-16 rounded-md flex place-content-center items-center m-1" }, ((_d = data === null || data === void 0 ? void 0 : data.overallProjectHealth) === null || _d === void 0 ? void 0 : _d.trim()) !== '' ? react_1.default.createElement("h1", { className: "font-bold text-2xl self-center" }, data === null || data === void 0 ? void 0 : data.overallProjectHealth) : react_1.default.createElement("h1", { className: "text-xl text-red-500" }, "N/A"))),
|
|
379
|
+
react_1.default.createElement("div", { className: 'flex items-center' },
|
|
380
|
+
react_1.default.createElement("p", null, "Why this score?"),
|
|
381
|
+
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "This grade does not have an impact on your standing with Paro but if you see a low grade or action required, please reach out to the Customer Success Team to help make sure you are staying up to date with your projects.", placement: "top", arrow: true },
|
|
382
|
+
react_1.default.createElement("div", null,
|
|
383
|
+
react_1.default.createElement(base_icons_1.IconInfoCircle, { size: "sm" }))))),
|
|
384
|
+
react_1.default.createElement("div", { className: "flex flex-col gap-y-4" },
|
|
385
|
+
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "The Minimum Floor Hours shows how many active projects you have currently completed the minimum floor hours requirement for and how many active projects that require minimum floor hours to be completed", placement: "top", arrow: true },
|
|
386
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-content-start mt-4 bg-[#F1F5F9] p-1 rounded-md" },
|
|
387
|
+
react_1.default.createElement(ActiveProjectCard_1.CheckItem, { checked: ((data === null || data === void 0 ? void 0 : data.minFloorHoursCountNumerator) > 0 && (data === null || data === void 0 ? void 0 : data.minFloorHoursCountDenominator) > 0), text: "Avg. Min Floor Hours Completed" }),
|
|
388
|
+
react_1.default.createElement("div", { className: "p-2 w-1/5 border-2 border-solid border-[#F1F5F9] rounded-md flex place-content-center items-start" }, ((data === null || data === void 0 ? void 0 : data.minFloorHoursCountNumerator) >= 0 && (data === null || data === void 0 ? void 0 : data.minFloorHoursCountDenominator) >= 0) ? react_1.default.createElement("p", null, data === null || data === void 0 ? void 0 :
|
|
389
|
+
data.minFloorHoursCountNumerator,
|
|
390
|
+
"/", data === null || data === void 0 ? void 0 :
|
|
391
|
+
data.minFloorHoursCountDenominator) : react_1.default.createElement("p", { className: "text-xl text-red-500" }, "N/A")))),
|
|
392
|
+
react_1.default.createElement(core_1.Tooltip, { classes: { tooltip: classes.tooltip }, title: "The Weekly Minimum Hours shows if you have submitted hours for a given week for an active project. If so, a check mark will appear next to it on the project card below. This does not impact your project grade but is a reminder to log hours consistently.", placement: "top", arrow: true },
|
|
393
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-content-start mb-4 bg-[#F1F5F9] p-1 rounded-md" },
|
|
394
|
+
react_1.default.createElement(ActiveProjectCard_1.CheckItem, { checked: ((data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountNumerator) > 0 && (data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountDenominator) > 0), text: "Avg. Weekly Min Hours Logged" }),
|
|
395
|
+
react_1.default.createElement("div", { className: "p-2 w-1/5 border-2 border-solid border-[#F1F5F9] rounded-md flex place-content-center items-start" }, ((data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountNumerator) >= 0 && (data === null || data === void 0 ? void 0 : data.weeklyMinHoursLoggedCountDenominator) >= 0) ? react_1.default.createElement("p", null, data === null || data === void 0 ? void 0 :
|
|
396
|
+
data.weeklyMinHoursLoggedCountNumerator,
|
|
397
|
+
"/", data === null || data === void 0 ? void 0 :
|
|
398
|
+
data.weeklyMinHoursLoggedCountDenominator) : react_1.default.createElement("p", { className: "text-xl text-red-500" }, "N/A")))))))),
|
|
399
|
+
react_1.default.createElement("div", { className: "flex flex-col w-full mb-4 md:mb-0" },
|
|
400
|
+
react_1.default.createElement("h1", { className: "font-bold text-xl ml-4" }, "Monthly Earnings"),
|
|
401
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-items-stretch gap-x-4 p-4" },
|
|
402
|
+
react_1.default.createElement("div", { className: "flex flex-col bg-[#F1F5F9] p-4 text-md rounded-md w-1/2", "data-tut": 'reactour__monthlyearnings' },
|
|
403
|
+
react_1.default.createElement("p", null, currMonth),
|
|
404
|
+
(data === null || data === void 0 ? void 0 : data.monthlyEarnings) > 0 ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
405
|
+
"$ ",
|
|
406
|
+
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.monthlyEarnings)) : react_1.default.createElement("h1", { className: "text-xl font-bold" }, "$ 0"),
|
|
407
|
+
(data === null || data === void 0 ? void 0 : data.expertCurrMonthGoal) >= 0 ? react_1.default.createElement("p", { className: "text-sm" },
|
|
408
|
+
"Goal: $ ",
|
|
409
|
+
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.expertCurrMonthGoal)) : react_1.default.createElement("p", { className: "text-sm" },
|
|
410
|
+
react_1.default.createElement("small", null, "Goal: No Goal set for current month"),
|
|
411
|
+
" ")),
|
|
412
|
+
react_1.default.createElement("div", { className: "flex flex-col bg-[#F1F5F9] p-4 text-md rounded-md w-1/2" },
|
|
413
|
+
react_1.default.createElement("p", null, "Avg./Month"),
|
|
414
|
+
averageInvoicedRevenue ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
415
|
+
"$ ",
|
|
416
|
+
(0, ProgressBar_1.formatNumberingSystem)(averageInvoicedRevenue)) : react_1.default.createElement("h1", { className: "text-xl font-bold" }, "$ 0"),
|
|
417
|
+
(data === null || data === void 0 ? void 0 : data.freelancerGoal) >= 0 ? react_1.default.createElement("p", { className: "text-sm" },
|
|
418
|
+
"Avg Goal: $ ",
|
|
419
|
+
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.freelancerGoal)) : react_1.default.createElement("p", { className: "text-sm" },
|
|
420
|
+
react_1.default.createElement("small", null, "Avg Goal: No Monthly Goal Set"),
|
|
421
|
+
" ")))),
|
|
422
|
+
react_1.default.createElement("div", { className: "flex flex-col w-full" },
|
|
423
|
+
react_1.default.createElement("h1", { className: "font-bold text-xl ml-4" }, "Lifetime Earnings Health"),
|
|
424
|
+
react_1.default.createElement("div", { className: "flex flex-col justify-between p-4 gap-y-4" },
|
|
425
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-between bg-[#F1F5F9] p-2 px-4 text-md rounded-md" },
|
|
426
|
+
react_1.default.createElement("p", null, "Invoiced to Projected:"),
|
|
427
|
+
lifetimeIRToPR > 0 ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
428
|
+
(0, ProgressBar_1.formatNumberingSystem)(lifetimeIRToPR),
|
|
429
|
+
"%") : react_1.default.createElement("h1", { className: "text-xl font-bold" }, "--")),
|
|
430
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-between bg-[#F1F5F9] p-2 px-4 text-md rounded-md" },
|
|
431
|
+
react_1.default.createElement("p", null, "Avg Contract Value:"),
|
|
432
|
+
(data === null || data === void 0 ? void 0 : data.averageContractValue) > 0 ? react_1.default.createElement("h1", { className: "text-xl font-bold" },
|
|
433
|
+
"$",
|
|
434
|
+
(0, ProgressBar_1.formatNumberingSystem)(data === null || data === void 0 ? void 0 : data.averageContractValue)) : react_1.default.createElement("h1", { className: "text-sm text-red-500 w-36" }, "Data will appear once you have won your first project")),
|
|
435
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-between bg-[#F1F5F9] p-2 px-4 text-md rounded-md" },
|
|
436
|
+
react_1.default.createElement("p", null,
|
|
437
|
+
"Total Unrealized Earnings for ",
|
|
438
|
+
getTitle(),
|
|
439
|
+
" Projects:"),
|
|
440
|
+
react_1.default.createElement("h1", { className: "text-xl font-bold", "data-tut": 'reactour__totalunrealizedearnings' },
|
|
441
|
+
"$",
|
|
442
|
+
(0, ProgressBar_1.formatNumberingSystem)(unrealizedEarnings))))))),
|
|
443
|
+
!isAuthenticated && react_1.default.createElement("div", { className: 'border ml-4 w-full text-white rounded-md bg-[#1878bd]' },
|
|
444
|
+
react_1.default.createElement("ul", { className: "list-disc px-8 py-3" },
|
|
445
|
+
react_1.default.createElement("li", null, "The projects shown below are only your active projects."),
|
|
446
|
+
react_1.default.createElement("li", null,
|
|
447
|
+
"Please ",
|
|
448
|
+
react_1.default.createElement("a", { className: 'underline font-bold', href: "/earnings-tracker", target: "_blank" }, "log in"),
|
|
449
|
+
" here to view all your projects that are Upcoming, Ad Hoc, Completed, or Inactive."),
|
|
450
|
+
react_1.default.createElement("li", null, "Active projects will show up 7 days before they start for you to make changes and keep track of reporting."))),
|
|
451
|
+
react_1.default.createElement("div", { className: "m-4 w-full" },
|
|
452
|
+
react_1.default.createElement(TabContext_1.default, { value: selectedTab + '' },
|
|
453
|
+
react_1.default.createElement(core_1.Tabs, { TabIndicatorProps: { style: { background: '#248384' } }, value: selectedTab, onChange: handleChangeValue, variant: "scrollable", scrollButtons: "off" },
|
|
454
|
+
react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Active") }),
|
|
455
|
+
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Ad Hoc") })),
|
|
456
|
+
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center", "data-tut": 'reacttour__upcomingsubheader' }, "\u00A0Upcoming") })),
|
|
457
|
+
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Inactive") })),
|
|
458
|
+
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Completed") })),
|
|
459
|
+
isAuthenticated && (react_1.default.createElement(core_1.Tab, { label: react_1.default.createElement("div", { className: "flex flex-row items-center" }, "\u00A0Paused") }))),
|
|
460
|
+
((sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) > 0 || (isAuthenticated && !loading)) && selectedTab !== 5 &&
|
|
461
|
+
react_1.default.createElement("div", { className: 'flex items-end gap-2 w-full justify-end mt-4', "data-tut": 'reacttour__sortby' },
|
|
462
|
+
react_1.default.createElement(base_ui_1.Select, { label: "Sort by", required: false, value: sortBy, onChange: e => handleSort(e), options: sortOptions, className: 'max-w-fit' }),
|
|
463
|
+
react_1.default.createElement(core_1.IconButton, { onClick: handleSortDirectionChange, title: sortDirection }, sortDirection === "asc" ? react_1.default.createElement(icons_1.ArrowUpwardRounded, null) : react_1.default.createElement(icons_1.ArrowDownwardRounded, null))),
|
|
464
|
+
react_1.default.createElement(tabPanelProps.component, { value: 0 + '' }, loading && isAuthenticated ? react_1.default.createElement(Loader_1.default, null) :
|
|
465
|
+
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
466
|
+
react_1.default.createElement("p", null,
|
|
467
|
+
"You currently have no active hourly projects. ",
|
|
468
|
+
react_1.default.createElement("a", { className: "underline cursor-pointer", onClick: () => { setFaqModal(true); } }, "Learn more"),
|
|
469
|
+
" about winning projects here or visit the ",
|
|
470
|
+
react_1.default.createElement("a", { className: "underline cursor-pointer", href: "/opportunities", target: "_blank" }, "opportunity board"),
|
|
471
|
+
".")) :
|
|
472
|
+
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
473
|
+
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: true, selectedTab: selectedTab, projectTagsMap: projectTagsMap, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
474
|
+
})))),
|
|
475
|
+
react_1.default.createElement(tabPanelProps.component, { value: 1 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
476
|
+
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
477
|
+
react_1.default.createElement("p", null, "You have no Ad Hoc projects at this time.")) :
|
|
478
|
+
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
479
|
+
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: true, adhocProject: true, selectedTab: selectedTab, projectTagsMap: projectTagsMap, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
480
|
+
})))),
|
|
481
|
+
react_1.default.createElement(tabPanelProps.component, { value: 2 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
482
|
+
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
483
|
+
react_1.default.createElement("p", null, "You have no upcoming projects at this time.")) :
|
|
484
|
+
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
485
|
+
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: false, upcomingProject: true, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
486
|
+
})))),
|
|
487
|
+
react_1.default.createElement(tabPanelProps.component, { value: 3 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
488
|
+
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
489
|
+
react_1.default.createElement("p", null, "You have no Inactive projects at this time.")) :
|
|
490
|
+
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
491
|
+
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: false, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
492
|
+
})))),
|
|
493
|
+
react_1.default.createElement(tabPanelProps.component, { value: 4 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
494
|
+
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
495
|
+
react_1.default.createElement("p", null, "You currently have no completed projects.")) :
|
|
496
|
+
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
497
|
+
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: false, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
498
|
+
})))),
|
|
499
|
+
react_1.default.createElement(tabPanelProps.component, { value: 5 + '' }, loading ? react_1.default.createElement(Loader_1.default, null) :
|
|
500
|
+
(!(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) ? react_1.default.createElement("div", { className: "flex items-center" },
|
|
501
|
+
react_1.default.createElement("p", null, "You currently have no paused projects.")) :
|
|
502
|
+
react_1.default.createElement(react_1.default.Fragment, null, sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.slice(firstItem, lastItem).map((project) => {
|
|
503
|
+
return (react_1.default.createElement(ActiveProjectCard_1.ActiveProjectCard, { project: project, projectsData: projectsData, expertName: data === null || data === void 0 ? void 0 : data.fullName, freelancerId: data === null || data === void 0 ? void 0 : data.freelancerId, freelancerEmail: project === null || project === void 0 ? void 0 : project.freelancerEmail, isAuthenticated: isAuthenticated, activeProject: true, selectedTab: selectedTab, updateProjectStatusMutation: updateProjectStatusMutation, GetAllProjectIrprDetailsForFreelancerDocument: GetAllProjectIrprDetailsForFreelancerDocument, updateParoProjectTagsMutation: updateParoProjectTagsMutation, GetParoProjectsDocument: GetParoProjectsDocument, updateProjectTagReviewStatusMutation: updateProjectTagReviewStatusMutation, updateProjectStatus: updateProjectStatus, updateProjectTags: updateProjectTags, sendParoSupportEmail: sendParoSupportEmail, getSowLazyQuery: getSowLazyQuery, createChangeRequestMutation: createChangeRequestMutation, createChangeRequest: createChangeRequest, createOrUpdateRatingRequestMutation: createOrUpdateRatingRequestMutation, updateProjectTaskMutation: updateProjectTaskMutation, updateProjectTask: updateProjectTask, submitProjectHoursMutation: submitProjectHoursMutation, getAuth0Roles: getAuth0Roles, submitProjectHoursLambda: submitProjectHoursLambda, user: user }));
|
|
504
|
+
})))),
|
|
505
|
+
(sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length) > 10 && (react_1.default.createElement("div", { className: `${!mobileScreen && "mx-7"}` },
|
|
506
|
+
react_1.default.createElement(Pagination_1.default, { total: sortedProjects === null || sortedProjects === void 0 ? void 0 : sortedProjects.length, currentPage: currentPage, setCurrentPage: setCurrentPage, perPageItems: perPageItems, setPerPageItems: setPerPageItems, displayText: "projects" })))))));
|
|
507
|
+
};
|
|
508
|
+
exports.EarningsTracker = EarningsTracker;
|