Compare commits
10 Commits
16e3a2649d
...
fixes_task
Author | SHA1 | Date | |
---|---|---|---|
7b4b4f37fc | |||
33af4ebbd6 | |||
5608e4e4f2 | |||
214d309ffb | |||
a156557d57 | |||
1254557a08 | |||
c22f26f6fe | |||
9cb59b61d6 | |||
4464324ae2 | |||
4cd3118649 |
3
src/assets/icons/folder.svg
Normal file
3
src/assets/icons/folder.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.4339 2.66676H7.24725L7.03392 2.0001C6.89562 1.60892 6.63908 1.27043 6.29985 1.03154C5.96062 0.792642 5.55549 0.665163 5.14059 0.666763H2.10059C1.57015 0.666763 1.06145 0.877477 0.686373 1.25255C0.3113 1.62762 0.100586 2.13633 0.100586 2.66676V11.3334C0.100586 11.8639 0.3113 12.3726 0.686373 12.7476C1.06145 13.1227 1.57015 13.3334 2.10059 13.3334H11.4339C11.9644 13.3334 12.4731 13.1227 12.8481 12.7476C13.2232 12.3726 13.4339 11.8639 13.4339 11.3334V4.66676C13.4339 4.13633 13.2232 3.62762 12.8481 3.25255C12.4731 2.87748 11.9644 2.66676 11.4339 2.66676ZM12.1006 11.3334C12.1006 11.5102 12.0303 11.6798 11.9053 11.8048C11.7803 11.9299 11.6107 12.0001 11.4339 12.0001H2.10059C1.92378 12.0001 1.75421 11.9299 1.62918 11.8048C1.50416 11.6798 1.43392 11.5102 1.43392 11.3334V2.66676C1.43392 2.48995 1.50416 2.32038 1.62918 2.19536C1.75421 2.07033 1.92378 2.0001 2.10059 2.0001H5.14059C5.28035 1.99974 5.41669 2.04331 5.53034 2.12466C5.64399 2.20601 5.7292 2.32102 5.77392 2.45343L6.13392 3.54676C6.17864 3.67918 6.26385 3.79419 6.3775 3.87553C6.49115 3.95688 6.62749 4.00046 6.76725 4.0001H11.4339C11.6107 4.0001 11.7803 4.07033 11.9053 4.19536C12.0303 4.32038 12.1006 4.48995 12.1006 4.66676V11.3334Z" fill="#52B709"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -39,13 +39,13 @@ export const AuthHeader = () => {
|
|||||||
<div className="auth-nav">
|
<div className="auth-nav">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<NavLink to={"/stack"}>аутстафинг</NavLink>
|
<NavLink to={"/stack"}>Аутстафинг</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<NavLink to={"/tracker-intro"}>трекер</NavLink>
|
<NavLink to={"/tracker-intro"}>Трекер</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<NavLink to={"/auth-candidate"}>работа в IT</NavLink>
|
<NavLink to={"/auth-candidate"}>Работа в IT</NavLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -490,8 +490,10 @@ export const ModalTiсket = ({
|
|||||||
}, [taskTags]);
|
}, [taskTags]);
|
||||||
|
|
||||||
async function handleUpload(event) {
|
async function handleUpload(event) {
|
||||||
|
try {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("uploadFile", event.target.files[0]);
|
formData.append("uploadFile", event.target.files[0]);
|
||||||
|
|
||||||
const res = await fetch("https://itguild.info/api/file/upload", {
|
const res = await fetch("https://itguild.info/api/file/upload", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
@ -502,6 +504,13 @@ export const ModalTiсket = ({
|
|||||||
|
|
||||||
// setUploadedFile(data);
|
// setUploadedFile(data);
|
||||||
attachFile(data[0].id);
|
attachFile(data[0].id);
|
||||||
|
} catch {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Неверный формат файла",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// function deleteLoadedFile() {
|
// function deleteLoadedFile() {
|
||||||
@ -543,7 +552,7 @@ export const ModalTiсket = ({
|
|||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
updateTimerSec++;
|
updateTimerSec++;
|
||||||
if (updateTimerSec > 60) {
|
if (updateTimerSec > 59) {
|
||||||
updateTimerMinute++;
|
updateTimerMinute++;
|
||||||
updateTimerSec = 0;
|
updateTimerSec = 0;
|
||||||
}
|
}
|
||||||
@ -561,7 +570,7 @@ export const ModalTiсket = ({
|
|||||||
|
|
||||||
function correctTimerTime(time) {
|
function correctTimerTime(time) {
|
||||||
if (time < 10) return `0${time}`;
|
if (time < 10) return `0${time}`;
|
||||||
if (time > 10) return time;
|
if (time >= 10) return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -800,7 +809,7 @@ export const ModalTiсket = ({
|
|||||||
name="file"
|
name="file"
|
||||||
id="input__file"
|
id="input__file"
|
||||||
type="file"
|
type="file"
|
||||||
accept="image/*,.png,.jpg,.svg,.jpeg"
|
accept="image/*,.png,.jpg,.svg,.jpeg,.doc,.docx,.xls,.xlsx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||||
className="input__file"
|
className="input__file"
|
||||||
onChange={handleUpload}
|
onChange={handleUpload}
|
||||||
/>
|
/>
|
||||||
|
@ -381,7 +381,7 @@ export const TicketFullScreen = () => {
|
|||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
updateTimerSec++;
|
updateTimerSec++;
|
||||||
if (updateTimerSec > 60) {
|
if (updateTimerSec > 59) {
|
||||||
updateTimerMinute++;
|
updateTimerMinute++;
|
||||||
updateTimerSec = 0;
|
updateTimerSec = 0;
|
||||||
}
|
}
|
||||||
@ -399,7 +399,7 @@ export const TicketFullScreen = () => {
|
|||||||
|
|
||||||
function correctTimerTime(time) {
|
function correctTimerTime(time) {
|
||||||
if (time < 10) return `0${time}`;
|
if (time < 10) return `0${time}`;
|
||||||
if (time > 10) return time;
|
if (time >= 10) return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteTaskExecutor() {
|
function deleteTaskExecutor() {
|
||||||
@ -479,8 +479,10 @@ export const TicketFullScreen = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleUpload(event) {
|
async function handleUpload(event) {
|
||||||
|
try {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("uploadFile", event.target.files[0]);
|
formData.append("uploadFile", event.target.files[0]);
|
||||||
|
|
||||||
const res = await fetch("https://itguild.info/api/file/upload", {
|
const res = await fetch("https://itguild.info/api/file/upload", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
@ -489,7 +491,15 @@ export const TicketFullScreen = () => {
|
|||||||
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
setUploadedFile(data);
|
// setUploadedFile(data);
|
||||||
|
attachFile(data[0].id);
|
||||||
|
} catch {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Неверный формат файла",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function attachFile() {
|
function attachFile() {
|
||||||
@ -774,7 +784,7 @@ export const TicketFullScreen = () => {
|
|||||||
name="file"
|
name="file"
|
||||||
id="input__file"
|
id="input__file"
|
||||||
type="file"
|
type="file"
|
||||||
accept="image/*,.png,.jpg,.svg,.jpeg"
|
accept="image/*,.png,.jpg,.svg,.jpeg,.doc,.docx,.xls,.xlsx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||||
className="input__file"
|
className="input__file"
|
||||||
onChange={handleUpload}
|
onChange={handleUpload}
|
||||||
/>
|
/>
|
||||||
|
@ -844,7 +844,7 @@ export const TrackerModal = ({
|
|||||||
)}
|
)}
|
||||||
{modalType === "create-project" && (
|
{modalType === "create-project" && (
|
||||||
<div>
|
<div>
|
||||||
<div className="title-project">
|
<div className="title-project" style={{ minWidth: "350px" }}>
|
||||||
<h4>{titleProject}</h4>
|
<h4>{titleProject}</h4>
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<input
|
<input
|
||||||
|
@ -88,12 +88,12 @@ export const Landing = () => {
|
|||||||
регистрация
|
регистрация
|
||||||
</div>
|
</div>
|
||||||
<BurgerButton active={menuActive} setActive={setMenuActive} />
|
<BurgerButton active={menuActive} setActive={setMenuActive} />
|
||||||
<div className="head__tracker">
|
<Link className="head__tracker" to="/tracker-intro">
|
||||||
<div>
|
<div>
|
||||||
<img src={tracker} alt="tracker" />
|
<img src={tracker} alt="tracker" />
|
||||||
</div>
|
</div>
|
||||||
<span>трекер</span>
|
<span>трекер</span>
|
||||||
</div>
|
</Link>
|
||||||
<SVG className="head__auth" src={authIcon} />
|
<SVG className="head__auth" src={authIcon} />
|
||||||
</div>
|
</div>
|
||||||
<div className="landing__info">
|
<div className="landing__info">
|
||||||
|
@ -92,13 +92,13 @@ export const PartnerEmployeeReport = () => {
|
|||||||
<>
|
<>
|
||||||
<div className="employee-report__info">
|
<div className="employee-report__info">
|
||||||
<div className="employee-report__name">
|
<div className="employee-report__name">
|
||||||
<h2>{userInfo.fio}</h2>
|
<h2>{userInfo?.userCard.fio}</h2>
|
||||||
<p>{userInfo.position}</p>
|
<p>{userInfo?.userCard.position.name}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="employee-report__skills">
|
<div className="employee-report__skills">
|
||||||
{userInfo?.stack &&
|
{userInfo?.userCard?.skillValues &&
|
||||||
userInfo.stack.map((skill, index) => {
|
userInfo?.userCard?.skillValues.map((skill) => {
|
||||||
return <span key={index}>{skill}</span>;
|
return <span key={skill.id}>{skill.skill.name}</span>;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,13 +34,13 @@ export const PartnerSettings = () => {
|
|||||||
const [loader, setLoader] = useState(false);
|
const [loader, setLoader] = useState(false);
|
||||||
const [tgLoader, setTgLoader] = useState(false);
|
const [tgLoader, setTgLoader] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
apiRequest("/user-tg-bot/get-token", {
|
// apiRequest("/user-tg-bot/get-token", {
|
||||||
method: "GET"
|
// method: "GET"
|
||||||
}).then((data) => {
|
// }).then((data) => {
|
||||||
setTgToken(data.token);
|
// setTgToken(data.token);
|
||||||
});
|
// });
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
const setSettings = () => {
|
const setSettings = () => {
|
||||||
if (inputsValue.name.length < 2) {
|
if (inputsValue.name.length < 2) {
|
||||||
@ -92,7 +92,25 @@ export const PartnerSettings = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleGenerate = async () => {
|
||||||
|
if (tgToken == undefined) {
|
||||||
|
setTgLoader(true);
|
||||||
|
apiRequest("/user-tg-bot/get-token", {
|
||||||
|
method: "GET"
|
||||||
|
}).then((data) => {
|
||||||
|
setTgToken(data.token);
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Телеграм токен успешно сгенерирован",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
setTgLoader(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleCopy = async () => {
|
const handleCopy = async () => {
|
||||||
|
if (tgToken !== undefined) {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(tgToken);
|
await navigator.clipboard.writeText(tgToken);
|
||||||
showNotification({
|
showNotification({
|
||||||
@ -107,6 +125,13 @@ export const PartnerSettings = () => {
|
|||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Необходимо сгенерировать код",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -225,13 +250,19 @@ export const PartnerSettings = () => {
|
|||||||
{tgLoader ? (
|
{tgLoader ? (
|
||||||
<Loader style={"green"} width={"40px"} height={"40px"} />
|
<Loader style={"green"} width={"40px"} height={"40px"} />
|
||||||
) : (
|
) : (
|
||||||
|
<BaseButton
|
||||||
|
onClick={handleGenerate}
|
||||||
|
styles={"settings__buttons-save"}
|
||||||
|
>
|
||||||
|
Сгенерировать
|
||||||
|
</BaseButton>
|
||||||
|
)}
|
||||||
<BaseButton
|
<BaseButton
|
||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
styles={"settings__buttons-save"}
|
styles={"settings__buttons-save"}
|
||||||
>
|
>
|
||||||
Скопировать
|
Скопировать
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="settings__agreement-tg">
|
<div className="settings__agreement-tg">
|
||||||
<a href="#" target="_blank" rel="noopener noreferrer">
|
<a href="#" target="_blank" rel="noopener noreferrer">
|
||||||
|
@ -94,8 +94,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: space-around;
|
||||||
gap: 20px;
|
|
||||||
margin: 30px 0 20px;
|
margin: 30px 0 20px;
|
||||||
|
|
||||||
&-cancel,
|
&-cancel,
|
||||||
@ -130,21 +129,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 440px) {
|
||||||
&__input {
|
|
||||||
width: 95%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__buttons {
|
&__buttons {
|
||||||
margin: 15px 0 14px 0;
|
flex-direction: column;
|
||||||
width: 100%;
|
gap: 10px;
|
||||||
flex-direction: column-reverse;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0px;
|
|
||||||
|
|
||||||
&-save {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import { useTheme } from "@table-library/react-table-library/theme";
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Link, Navigate } from "react-router-dom";
|
import { Link, Navigate } from "react-router-dom";
|
||||||
|
|
||||||
import { LEVELS, SKILLS } from "@utils/constants";
|
|
||||||
import { urlForLocal } from "@utils/helper";
|
import { urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
@ -18,26 +17,12 @@ import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadc
|
|||||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
||||||
|
|
||||||
import rightArrow from "assets/icons/arrows/arrowRight.svg";
|
import rightArrow from "assets/icons/arrows/arrowRight.svg";
|
||||||
|
import folder from "assets/icons/folder.svg";
|
||||||
import report from "assets/icons/report.svg";
|
import report from "assets/icons/report.svg";
|
||||||
|
|
||||||
// import PartnerPersonCard from "@components/PartnerPersonCard/PartnerPersonCard";
|
|
||||||
// import { useDispatch } from "react-redux";
|
|
||||||
// import { setPartnerEmployees } from "@redux/outstaffingSlice";
|
|
||||||
// import rightArrow from "assets/icons/arrows/arrowRight.svg";
|
|
||||||
// import avatarImg from "assets/images/avatarMok.png";
|
|
||||||
// import AdminImg from "assets/images/partnerProfile/PersonalAdmin.svg";
|
|
||||||
// import ArchitectureImg from "assets/images/partnerProfile/PersonalArchitecture.svg";
|
|
||||||
// import CopyImg from "assets/images/partnerProfile/PersonalCopy.svg";
|
|
||||||
// import DesignImg from "assets/images/partnerProfile/PersonalDesign.svg";
|
|
||||||
// import FrontendImg from "assets/images/partnerProfile/PersonalFrontend.svg";
|
|
||||||
// import ManageImg from "assets/images/partnerProfile/PersonalMng.svg";
|
|
||||||
// import SmmImg from "assets/images/partnerProfile/PersonalSMM.svg";
|
|
||||||
// import TestImg from "assets/images/partnerProfile/PersonalTesters.svg";
|
|
||||||
// import BackEndImg from "assets/images/partnerProfile/personalBackEnd.svg";
|
|
||||||
import "./partnerСategories.scss";
|
import "./partnerСategories.scss";
|
||||||
|
|
||||||
export const PartnerCategories = () => {
|
export const PartnerCategories = () => {
|
||||||
// const dispatch = useDispatch();
|
|
||||||
if (localStorage.getItem("role_status") !== "18") {
|
if (localStorage.getItem("role_status") !== "18") {
|
||||||
return <Navigate to="/profile" replace />;
|
return <Navigate to="/profile" replace />;
|
||||||
}
|
}
|
||||||
@ -46,7 +31,7 @@ export const PartnerCategories = () => {
|
|||||||
const theme = useTheme(getTheme());
|
const theme = useTheme(getTheme());
|
||||||
const [nodes, setNodes] = useState([]);
|
const [nodes, setNodes] = useState([]);
|
||||||
const [initialNodes, setInitialNodes] = useState([]);
|
const [initialNodes, setInitialNodes] = useState([]);
|
||||||
const [activeTab, setActiveTab] = useState("Все");
|
const [activeTab, setActiveTab] = useState(0);
|
||||||
|
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
@ -65,32 +50,39 @@ export const PartnerCategories = () => {
|
|||||||
{
|
{
|
||||||
label: "",
|
label: "",
|
||||||
renderCell: (item) => (
|
renderCell: (item) => (
|
||||||
|
<Link to={`/profile/summary/${item.user_id}`}>
|
||||||
<img
|
<img
|
||||||
className="table__avatar"
|
className="table__avatar"
|
||||||
src={urlForLocal(item?.employee.avatar)}
|
src={urlForLocal(item?.employee.avatar)}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
|
</Link>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Данные",
|
label: "Данные",
|
||||||
renderCell: (item) => (
|
renderCell: (item) => (
|
||||||
<div className="table__info">
|
<Link className="table__info" to={`/profile/summary/${item.user_id}`}>
|
||||||
<p>{item?.employee.fio}</p>
|
<p>{item?.employee.fio}</p>
|
||||||
<span>
|
<span>
|
||||||
{LEVELS[item?.resume.userCard.level]} /{" "}
|
{item?.employee.level_title} / {item?.employee.position.name}
|
||||||
{SKILLS[item?.resume.userCard.position_id]}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</Link>
|
||||||
)
|
)
|
||||||
// sort: { sortKey: "NAME" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Участвует в проекте",
|
label: "Участвует в проекте",
|
||||||
renderCell: (item) => (
|
renderCell: (item) => (
|
||||||
<div className="table__project">
|
<div className="table__project">
|
||||||
{item.resume.userCard.at_project ? (
|
{item?.employee.projects.length ? (
|
||||||
<div>item.resume.userCard.at_project</div>
|
item.employee.projects.map((project) => {
|
||||||
|
return (
|
||||||
|
<div className="table__project__item" key={project.id}>
|
||||||
|
<img src={folder} alt="folder" />{" "}
|
||||||
|
<p>{project.project.name}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<span>Нет проектов</span>
|
<span>Нет проектов</span>
|
||||||
)}
|
)}
|
||||||
@ -143,23 +135,9 @@ export const PartnerCategories = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoader(true);
|
setLoader(true);
|
||||||
apiRequest("/project/my-employee").then((el) => {
|
apiRequest("/project/my-employee").then((el) => {
|
||||||
const fetchResumes = async () => {
|
setNodes(el.managerEmployees);
|
||||||
const promises = el.managerEmployees.map(async (manager) => {
|
setInitialNodes(el.managerEmployees);
|
||||||
const resume = await apiRequest(`/resume?userId=${manager.user_id}`);
|
|
||||||
return { ...manager, resume }; // Возвращаем объект с добавленным ключом resume
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const updatedManagers = await Promise.all(promises);
|
|
||||||
setInitialNodes(updatedManagers);
|
|
||||||
setNodes(updatedManagers);
|
|
||||||
setLoader(false);
|
setLoader(false);
|
||||||
} catch (error) {
|
|
||||||
console.error("Ошибка при получении резюме:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchResumes();
|
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -178,108 +156,6 @@ export const PartnerCategories = () => {
|
|||||||
console.log(action, state);
|
console.log(action, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// const [personalInfoItems] = useState([
|
|
||||||
// {
|
|
||||||
// title: "Backend разработчики",
|
|
||||||
// link: "/profile/categories/employees",
|
|
||||||
// description:
|
|
||||||
// "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
|
|
||||||
// available: true,
|
|
||||||
// img: BackEndImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Frontend разработчики",
|
|
||||||
// link: "/profile/categories/employees",
|
|
||||||
// description:
|
|
||||||
// "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
|
|
||||||
// available: true,
|
|
||||||
// img: FrontendImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Архитектура проектов",
|
|
||||||
// link: "/profile/categories/employees",
|
|
||||||
// description: "Потоки данных ER ERP CRM CQRS UML BPMN",
|
|
||||||
// available: true,
|
|
||||||
// img: ArchitectureImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Дизайн проектов",
|
|
||||||
// link: "/profile/categories/employees",
|
|
||||||
// description:
|
|
||||||
// "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
|
|
||||||
// available: true,
|
|
||||||
// img: DesignImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Тестирование проектов",
|
|
||||||
// link: "/profile/add-request",
|
|
||||||
// description: "SQL Postman TestRail Kibana Ручное тестирование",
|
|
||||||
// available: false,
|
|
||||||
// img: TestImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Администрирование проектов",
|
|
||||||
// link: "/profile/add-request",
|
|
||||||
// description: "DevOps ELK Kubernetes Docker Bash Apache Oracle Git",
|
|
||||||
// available: false,
|
|
||||||
// img: AdminImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Управление проектом",
|
|
||||||
// link: "/profile/add-request",
|
|
||||||
// description: "Scrum Kanban Agile Miro CustDev",
|
|
||||||
// available: false,
|
|
||||||
// img: ManageImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Копирайтинг проектов",
|
|
||||||
// link: "/profile/add-request",
|
|
||||||
// description: "Теги Заголовок H1 Дескриптор Абзац Сценарий",
|
|
||||||
// available: false,
|
|
||||||
// img: CopyImg
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Реклама и SMM",
|
|
||||||
// link: "/profile/add-request",
|
|
||||||
// description:
|
|
||||||
// "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
|
|
||||||
// available: false,
|
|
||||||
// img: SmmImg
|
|
||||||
// }
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
// const [mokPersons] = useState([
|
|
||||||
// {
|
|
||||||
// personAvatar: avatarImg,
|
|
||||||
// name: "Макаренко Дмитрий",
|
|
||||||
// qualification: "PHP Backend - разработчик",
|
|
||||||
// level: "Middle",
|
|
||||||
// project: "Админка НВД Консалтинг",
|
|
||||||
// tasks_in_progress: 5,
|
|
||||||
// month_hours: 140,
|
|
||||||
// id: 1
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// personAvatar: avatarImg,
|
|
||||||
// name: "Макаренко Дмитрий",
|
|
||||||
// qualification: "PHP Backend - разработчик",
|
|
||||||
// level: "Middle",
|
|
||||||
// project: "Админка НВД Консалтинг",
|
|
||||||
// tasks_in_progress: 5,
|
|
||||||
// month_hours: 140,
|
|
||||||
// id: 2
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// personAvatar: avatarImg,
|
|
||||||
// name: "Макаренко Дмитрий",
|
|
||||||
// qualification: "PHP Backend - разработчик",
|
|
||||||
// level: "Middle",
|
|
||||||
// project: "Админка НВД Консалтинг",
|
|
||||||
// tasks_in_progress: 5,
|
|
||||||
// month_hours: 140,
|
|
||||||
// id: 3
|
|
||||||
// }
|
|
||||||
// ]);
|
|
||||||
return (
|
return (
|
||||||
<div className="partner-categories">
|
<div className="partner-categories">
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
@ -311,11 +187,11 @@ export const PartnerCategories = () => {
|
|||||||
<div className="table__tabs">
|
<div className="table__tabs">
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActiveTab("Все");
|
setActiveTab(0);
|
||||||
setNodes(initialNodes);
|
setNodes(initialNodes);
|
||||||
}}
|
}}
|
||||||
className={
|
className={
|
||||||
activeTab === "Все"
|
activeTab === 0
|
||||||
? "table__tab table__tab--active"
|
? "table__tab table__tab--active"
|
||||||
: "table__tab"
|
: "table__tab"
|
||||||
}
|
}
|
||||||
@ -329,8 +205,7 @@ export const PartnerCategories = () => {
|
|||||||
setActiveTab(tab.name);
|
setActiveTab(tab.name);
|
||||||
setNodes(
|
setNodes(
|
||||||
initialNodes.filter(
|
initialNodes.filter(
|
||||||
(item) =>
|
(item) => item.employee.position.id === tab.value
|
||||||
item.resume.userCard.position_id === tab.value
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@ -353,10 +228,14 @@ export const PartnerCategories = () => {
|
|||||||
sort={sort}
|
sort={sort}
|
||||||
pagination={pagination}
|
pagination={pagination}
|
||||||
/>
|
/>
|
||||||
|
{Boolean(nodes.length) &&
|
||||||
|
pagination.state.getPages(data.nodes).length > 1 && (
|
||||||
<div className="table__pagination">
|
<div className="table__pagination">
|
||||||
<button
|
<button
|
||||||
className={
|
className={
|
||||||
pagination.state.page === 0 ? "switch disable" : "switch"
|
pagination.state.page === 0
|
||||||
|
? "switch disable"
|
||||||
|
: "switch"
|
||||||
}
|
}
|
||||||
type="button"
|
type="button"
|
||||||
disabled={pagination.state.page === 0}
|
disabled={pagination.state.page === 0}
|
||||||
@ -367,7 +246,9 @@ export const PartnerCategories = () => {
|
|||||||
{"<"}
|
{"<"}
|
||||||
</button>
|
</button>
|
||||||
<span className="table__pages">
|
<span className="table__pages">
|
||||||
{pagination.state.getPages(data.nodes).map((_, index) => (
|
{pagination.state
|
||||||
|
.getPages(data.nodes)
|
||||||
|
.map((_, index) => (
|
||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
type="button"
|
type="button"
|
||||||
@ -401,6 +282,7 @@ export const PartnerCategories = () => {
|
|||||||
{">"}
|
{">"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="partner-categories__empty">
|
<div className="partner-categories__empty">
|
||||||
@ -411,39 +293,6 @@ export const PartnerCategories = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/*{personalInfoItems.map((item, index) => {*/}
|
|
||||||
{/* return (*/}
|
|
||||||
{/* <Link*/}
|
|
||||||
{/* to={item.link}*/}
|
|
||||||
{/* key={index}*/}
|
|
||||||
{/* className={*/}
|
|
||||||
{/* item.available*/}
|
|
||||||
{/* ? "partner-categories__item item"*/}
|
|
||||||
{/* : "partner-categories__item item item__disable"*/}
|
|
||||||
{/* }*/}
|
|
||||||
{/* onClick={() => {*/}
|
|
||||||
{/* dispatch(setPartnerEmployees(mokPersons));*/}
|
|
||||||
{/* }}*/}
|
|
||||||
{/* >*/}
|
|
||||||
{/* <div className="item__title">*/}
|
|
||||||
{/* <img src={item.img} alt={item.title} />*/}
|
|
||||||
{/* <h4>{item.title}</h4>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* <div className="item__info">*/}
|
|
||||||
{/* <p>{item.description}</p>*/}
|
|
||||||
{/* <div className="more">*/}
|
|
||||||
{/* <img src={rightArrow} alt="arrow" />*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* {!item.available && (*/}
|
|
||||||
{/* <div className="item__disable-hover">*/}
|
|
||||||
{/* <p>У вас нет персонала из категории</p>*/}
|
|
||||||
{/* <button>Подобрать</button>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* )}*/}
|
|
||||||
{/* </Link>*/}
|
|
||||||
{/* );*/}
|
|
||||||
{/*})}*/}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -255,6 +255,26 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 17.5px;
|
line-height: 17.5px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 11px;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 8px;
|
||||||
|
color: rgba(46, 58, 89, 1);
|
||||||
|
font-size: 14px;
|
||||||
|
border: 1px solid rgba(237, 237, 237, 1);
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
max-width: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__action {
|
&__action {
|
||||||
|
@ -2,7 +2,7 @@ import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
|
|||||||
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { Navigate } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
import { getProfileInfo } from "@redux/outstaffingSlice";
|
import { getProfileInfo } from "@redux/outstaffingSlice";
|
||||||
|
|
||||||
@ -27,19 +27,18 @@ import avatarMok from "assets/images/avatarMok.webp";
|
|||||||
import "./summary.scss";
|
import "./summary.scss";
|
||||||
|
|
||||||
export const Summary = () => {
|
export const Summary = () => {
|
||||||
if (localStorage.getItem("role_status") === "18") {
|
|
||||||
return <Navigate to="/profile" replace />;
|
|
||||||
}
|
|
||||||
const profileInfo = useSelector(getProfileInfo);
|
const profileInfo = useSelector(getProfileInfo);
|
||||||
const [openGit, setOpenGit] = useState(false);
|
const [openGit, setOpenGit] = useState(false);
|
||||||
const [gitInfo, setGitInfo] = useState([]);
|
const [gitInfo, setGitInfo] = useState([]);
|
||||||
const [editSummaryOpen, setEditSummaryOpen] = useState(false);
|
const [editSummaryOpen, setEditSummaryOpen] = useState(false);
|
||||||
const [editSkills, setEditSkills] = useState(false);
|
const [editSkills, setEditSkills] = useState(false);
|
||||||
|
const [userInfo, setUserInfo] = useState({});
|
||||||
const [summary, setSummary] = useState("");
|
const [summary, setSummary] = useState("");
|
||||||
const [selectedSkills, setSelectedSkills] = useState([]);
|
const [selectedSkills, setSelectedSkills] = useState([]);
|
||||||
const [selectSkillsOpen, setSelectSkillsOpen] = useState(false);
|
const [selectSkillsOpen, setSelectSkillsOpen] = useState(false);
|
||||||
const [skillsList, seSkillsList] = useState([]);
|
const [skillsList, seSkillsList] = useState([]);
|
||||||
const { showNotification } = useNotification();
|
const { showNotification } = useNotification();
|
||||||
|
const { id: userId } = useParams();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
apiRequest(
|
apiRequest(
|
||||||
@ -48,8 +47,10 @@ export const Summary = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!userId) {
|
||||||
setSummary(profileInfo.vc_text);
|
setSummary(profileInfo.vc_text);
|
||||||
setSelectedSkills(profileInfo.skillValues);
|
setSelectedSkills(profileInfo.skillValues);
|
||||||
|
}
|
||||||
}, [profileInfo]);
|
}, [profileInfo]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -58,6 +59,22 @@ export const Summary = () => {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (userId) {
|
||||||
|
apiRequest(`/resume?userId=${userId}`).then((res) => {
|
||||||
|
setUserInfo({
|
||||||
|
photo: res.userCard.photo,
|
||||||
|
fio: res.userCard.fio,
|
||||||
|
specification: res.userCard.specification,
|
||||||
|
level: res.userCard.level_title,
|
||||||
|
position: res.userCard.position.name
|
||||||
|
});
|
||||||
|
setSummary(res.userCard.vc_text);
|
||||||
|
setSelectedSkills(res.userCard.skillValues);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [userId]);
|
||||||
|
|
||||||
const addSkill = (skill) => {
|
const addSkill = (skill) => {
|
||||||
const isSkillFound = selectedSkills.some(
|
const isSkillFound = selectedSkills.some(
|
||||||
(item) => item.skill_id == skill.id
|
(item) => item.skill_id == skill.id
|
||||||
@ -133,7 +150,9 @@ export const Summary = () => {
|
|||||||
<div className="summary__person">
|
<div className="summary__person">
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
profileInfo?.photo
|
userId
|
||||||
|
? urlForLocal(userInfo.photo)
|
||||||
|
: profileInfo?.photo
|
||||||
? urlForLocal(profileInfo.photo)
|
? urlForLocal(profileInfo.photo)
|
||||||
: avatarMok
|
: avatarMok
|
||||||
}
|
}
|
||||||
@ -141,12 +160,18 @@ export const Summary = () => {
|
|||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<p className="summary__name">
|
<p className="summary__name">
|
||||||
{profileInfo?.fio || profileInfo?.username}{" "}
|
{userId
|
||||||
{profileInfo.specification}
|
? userInfo.fio
|
||||||
|
: profileInfo?.fio || profileInfo?.username}{" "}
|
||||||
|
{userId ? userInfo.specification : profileInfo.specification}
|
||||||
</p>
|
</p>
|
||||||
<hr />
|
<hr />
|
||||||
<div className="summary__direction">Front End</div>
|
<div className="summary__direction">
|
||||||
<div className="summary__level">Middle+</div>
|
{userId ? userInfo.position : profileInfo?.position?.name}
|
||||||
|
</div>
|
||||||
|
<div className="summary__level">
|
||||||
|
{userId ? userInfo.level : profileInfo?.level_title}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!openGit && (
|
{!openGit && (
|
||||||
<button className="summary__git" onClick={() => setOpenGit(true)}>
|
<button className="summary__git" onClick={() => setOpenGit(true)}>
|
||||||
@ -159,6 +184,7 @@ export const Summary = () => {
|
|||||||
<div className="summary__skills skills__section">
|
<div className="summary__skills skills__section">
|
||||||
<div className="summary__sections__head">
|
<div className="summary__sections__head">
|
||||||
<h3>Основной стек</h3>
|
<h3>Основной стек</h3>
|
||||||
|
{!userId && (
|
||||||
<button
|
<button
|
||||||
className={editSkills ? "edit" : ""}
|
className={editSkills ? "edit" : ""}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -170,6 +196,7 @@ export const Summary = () => {
|
|||||||
>
|
>
|
||||||
{editSkills ? "Сохранить" : "Редактировать"}
|
{editSkills ? "Сохранить" : "Редактировать"}
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="skills__section__items">
|
<div className="skills__section__items">
|
||||||
{editSkills ? (
|
{editSkills ? (
|
||||||
@ -239,6 +266,7 @@ export const Summary = () => {
|
|||||||
<div className="experience__block">
|
<div className="experience__block">
|
||||||
<div className="summary__sections__head">
|
<div className="summary__sections__head">
|
||||||
<h3>Опыт работы</h3>
|
<h3>Опыт работы</h3>
|
||||||
|
{!userId && (
|
||||||
<button
|
<button
|
||||||
className={editSummaryOpen ? "edit" : ""}
|
className={editSummaryOpen ? "edit" : ""}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -250,6 +278,7 @@ export const Summary = () => {
|
|||||||
>
|
>
|
||||||
{editSummaryOpen ? "Сохранить" : "Редактировать"}
|
{editSummaryOpen ? "Сохранить" : "Редактировать"}
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{editSummaryOpen ? (
|
{editSummaryOpen ? (
|
||||||
<CKEditor
|
<CKEditor
|
||||||
|
@ -20,6 +20,7 @@ import { Profile } from "@pages/Profile/Profile";
|
|||||||
import { ProjectTracker } from "@pages/ProjectTracker/ProjectTracker";
|
import { ProjectTracker } from "@pages/ProjectTracker/ProjectTracker";
|
||||||
import { Stack } from "@pages/Stack/Stack";
|
import { Stack } from "@pages/Stack/Stack";
|
||||||
import Statistics from "@pages/Statistics/Statistics";
|
import Statistics from "@pages/Statistics/Statistics";
|
||||||
|
import { Summary } from "@pages/Summary/Summary";
|
||||||
import { Tracker } from "@pages/Tracker/Tracker";
|
import { Tracker } from "@pages/Tracker/Tracker";
|
||||||
import { TrackerIntro } from "@pages/TrackerIntro/TrackerIntro";
|
import { TrackerIntro } from "@pages/TrackerIntro/TrackerIntro";
|
||||||
import { ViewReport } from "@pages/ViewReport/ViewReport";
|
import { ViewReport } from "@pages/ViewReport/ViewReport";
|
||||||
@ -27,6 +28,7 @@ import { WelcomePage } from "@pages/WelcomePage/WelcomePage";
|
|||||||
|
|
||||||
import { Calendar } from "@components/Calendar/Calendar";
|
import { Calendar } from "@components/Calendar/Calendar";
|
||||||
import { Candidate } from "@components/Candidate/Candidate";
|
import { Candidate } from "@components/Candidate/Candidate";
|
||||||
|
import TicketFullScreen from "@components/Modal/Tracker/TicketFullScreen/TicketFullScreen";
|
||||||
|
|
||||||
export const PartnerPage = () => {
|
export const PartnerPage = () => {
|
||||||
return (
|
return (
|
||||||
@ -45,6 +47,7 @@ export const PartnerPage = () => {
|
|||||||
<Route exact path="/candidate/:id/form" element={<FormPage />} />
|
<Route exact path="/candidate/:id/form" element={<FormPage />} />
|
||||||
<Route path="/:userId/calendar" element={<Calendar />} />
|
<Route path="/:userId/calendar" element={<Calendar />} />
|
||||||
|
|
||||||
|
<Route exact path="/tracker/task/:id" element={<TicketFullScreen />} />
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/tracker/project/:id/task/:taskId"
|
path="/tracker/project/:id/task/:taskId"
|
||||||
@ -64,6 +67,7 @@ export const PartnerPage = () => {
|
|||||||
<Route exact path="requests-edit" element={<PartnerAddRequest />} />
|
<Route exact path="requests-edit" element={<PartnerAddRequest />} />
|
||||||
<Route exact path="requests-bid" element={<PartnerBid />} />
|
<Route exact path="requests-bid" element={<PartnerBid />} />
|
||||||
<Route exact path="employees" element={<PartnerCategories />} />
|
<Route exact path="employees" element={<PartnerCategories />} />
|
||||||
|
<Route exact path="summary/:id" element={<Summary />} />
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="employees/report/:uuid"
|
path="employees/report/:uuid"
|
||||||
|
Reference in New Issue
Block a user