Skip to content
This repository has been archived by the owner on Apr 14, 2024. It is now read-only.

Commit

Permalink
refactor: принятие\отклонение (#79)
Browse files Browse the repository at this point in the history
Co-authored-by: Ruslan Kutliakhmetov <[email protected]>
  • Loading branch information
DieWerkself and ko22009 authored Nov 27, 2023
1 parent c183245 commit cd5f945
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 44 deletions.
40 changes: 22 additions & 18 deletions src/entities/project/contacts/Contacts.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
import { Flex, Heading, Stack, Text } from '@chakra-ui/layout';
import { Avatar, Skeleton } from '@chakra-ui/react';
import React from 'react';
import { Link, generatePath } from 'react-router-dom';
import { generatePath } from 'react-router-dom';

import { useApi } from '~/shared/hooks';
import { useApi, useAuth } from '~/shared/hooks';
import { PATHS } from '~/shared/lib/router';
import { Rating } from '~/shared/ui/rating';
import { SLink } from '~/shared/ui/SLink';

import { useGetUser } from '../api';

export const Contacts = ({ ownerId }: { ownerId: string }) => {
const { userApi } = useApi();
const { isAuth } = useAuth();
const avatar = userApi.getAvatar(ownerId);
const { data: owner, isSuccess: loadedOwner } = useGetUser(ownerId);

return (
<>
<Heading variant="h2">Контакты</Heading>
<Link key={ownerId} to={generatePath(PATHS.profile, { id: ownerId })}>
<Skeleton isLoaded={loadedOwner} borderRadius="2xl" fadeDuration={2}>
<Flex alignItems="flex-start">
<Avatar src={avatar} name={`${owner?.first_name} ${owner?.last_name}`} />
<Stack pl={2} gap={0}>
<Heading variant="h3">
{owner?.first_name} {owner?.last_name}
</Heading>
<Text variant="caption">Организатор</Text>
</Stack>
{/* <Flex ml="auto">
<Heading variant="h2">Участники</Heading>
<Skeleton isLoaded={loadedOwner} borderRadius="2xl" fadeDuration={2}>
<Flex alignItems="center">
<Avatar src={avatar} name={`${owner?.first_name} ${owner?.last_name}`} />
<Stack pl={2} gap={0}>
<Heading variant="h3">
{owner?.first_name} {owner?.last_name}
</Heading>
<Text variant="caption">Организатор</Text>
{isAuth && (
<SLink to={generatePath(PATHS.profile, { id: ownerId })}>
Перейти в профиль
</SLink>
)}
</Stack>
{/* <Flex ml="auto">
<Rating />
</Flex> */}
</Flex>
</Skeleton>
</Link>
</Flex>
</Skeleton>
</>
);
};
4 changes: 2 additions & 2 deletions src/entities/project/filter/ui/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export const Filter = ({ totalItems = 0 }: FilterProps) => {
/>
</Box>
<Box>
<Stack gap={1} mb={4}>
<Stack gap={1} mb={3}>
<Heading variant="h2" mb={3}>
Профессиональные навыки
</Heading>
Expand Down Expand Up @@ -129,7 +129,7 @@ export const Filter = ({ totalItems = 0 }: FilterProps) => {
</Container>
<Container maxW="md" py={6} bg="bg" position="sticky" bottom="0" mt="auto">
<Button fontSize="sm" fontWeight="600" w="full" onClick={onClose}>
Показать {totalItems ?? 0} проектов
Найдено позиций: {totalItems ?? 0}
</Button>
</Container>
</ModalContent>
Expand Down
32 changes: 28 additions & 4 deletions src/entities/project/info/ProjectInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { Heading, Stack } from '@chakra-ui/layout';
import { Skeleton } from '@chakra-ui/react';

import { GetSpecsData } from '~/shared/api';
import { GetProjectPositionsData } from '~/shared/api/types';
import {
GetAllParticipantsDataResponse,
GetProjectPositionsData,
} from '~/shared/api/types';
import { STag } from '~/shared/ui/STag';
import { Status } from '~/shared/ui/Status';

Expand All @@ -27,6 +30,9 @@ interface ProjectInfoProps {
project: Project;
positions?: GetProjectPositionsData;
ioadedPositions: boolean;
userIsOwner: boolean;
userId?: string;
participants: GetAllParticipantsDataResponse;
}

export const ProjectInfo = ({
Expand All @@ -36,13 +42,25 @@ export const ProjectInfo = ({
project,
positions,
ioadedPositions,
userId,
userIsOwner,
participants,
}: ProjectInfoProps) => {
const participantIds = participants
.filter(({ user_id }) => user_id === userId)
.map(({ position_id }) => position_id);

const filterMainTag = (positionId?: string) => {
const mainTag = allSpecs
?.filter(({ id }) => id === positionId)
.map(({ name }) => name ?? '');
return mainTag;
};

const filteredPositions = userIsOwner
? positions
: positions?.filter(({ id }) => participantIds.includes(id));

return (
<>
<Stack gap={0} mb={3} alignItems="start">
Expand All @@ -56,11 +74,17 @@ export const ProjectInfo = ({
</Stack>

<Stack gap={0} mb={6}>
<Heading variant="h2">В проект требуются</Heading>
<Heading variant="h2">
{userIsOwner ? 'В проект требуются' : 'Мои отклики'}
</Heading>
<Skeleton isLoaded={ioadedPositions} borderRadius="2xl" fadeDuration={2}>
<Stack>
{positions?.map((_, i) => (
<STag key={i} mainTags={filterMainTag(specs[i])} tags={skills[i]} />
{filteredPositions?.map((position, i) => (
<STag
key={position.id}
mainTags={filterMainTag(specs[i])}
tags={skills[i]}
/>
))}
</Stack>
</Skeleton>
Expand Down
8 changes: 7 additions & 1 deletion src/entities/project/request/RequestInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { Flex, Heading, Stack, Text } from '@chakra-ui/layout';
import { Avatar } from '@chakra-ui/react';
import { generatePath } from 'react-router-dom';

import { GetSpecsData } from '~/shared/api';
import { GetUserResponse } from '~/shared/api/types';
import { useApi } from '~/shared/hooks';
import { PATHS } from '~/shared/lib/router';
import { SLink } from '~/shared/ui/SLink';

interface RequestInfoProps {
userInfo: GetUserResponse;
Expand All @@ -20,7 +23,7 @@ export const RequestInfo = ({ userInfo, allSpecs }: RequestInfoProps) => {
return specName;
};
return (
<Flex alignItems="flex-start">
<Flex alignItems="center">
<Avatar
name={`${userInfo.first_name} ${userInfo.last_name}`}
src={userApi.getAvatar(userInfo.id)}
Expand All @@ -34,6 +37,9 @@ export const RequestInfo = ({ userInfo, allSpecs }: RequestInfoProps) => {
? getSpecName(userInfo.main_specialization_id)
: 'У пользователя не выбрана специализация'}
</Text>
<SLink to={generatePath(PATHS.profile, { id: userInfo.id })}>
Перейти в профиль
</SLink>
</Stack>
<Flex ml="auto">{/* <Rating /> */}</Flex>
</Flex>
Expand Down
30 changes: 28 additions & 2 deletions src/pages/position/Position.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
useGetParticipants,
useGetUserStatus,
} from '~/entities/project';
import { useGetAllSkills, useGetSpecs } from '~/entities/storage';
import { useGetSkillsByIds, useGetSpecs } from '~/entities/storage';

import { useApi, useAuth, useIsMobile, useLayoutRefs } from '~/shared/hooks';
import { GoBack } from '~/shared/ui/GoBack';
Expand All @@ -45,7 +45,9 @@ export const Position = ({ positionId }: ProjectBase) => {
});

const { data: allSpecs, isSuccess: loadedSpecs } = useGetSpecs();
const { data: allSkills, isSuccess: loadedSkills } = useGetAllSkills();
const { data: allSkills, isSuccess: loadedSkills } = useGetSkillsByIds(
position?.skills,
);

const isLoaded = loadedSkills && loadedSpecs;

Expand Down Expand Up @@ -162,6 +164,30 @@ export const Position = ({ positionId }: ProjectBase) => {
Отклик отправлен
</Button>
)}
{userStatus === 'left' && (
<Button
isDisabled
bg="gray.400"
color="gray.900"
fontSize="sm"
fontWeight="600"
w="full"
>
Вы покинули проект
</Button>
)}
{userStatus === 'declined' && (
<Button
isDisabled
bg="gray.400"
color="gray.900"
fontSize="sm"
fontWeight="600"
w="full"
>
Ваш отклик отклонен
</Button>
)}
{!isAuth && (
<Button
type="button"
Expand Down
70 changes: 54 additions & 16 deletions src/pages/projects/ui/ProjectBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@ import {
CardBody,
Skeleton,
Portal,
Modal,
Modal as ChakraModal,
ModalOverlay,
ModalContent,
useDisclosure,
Text,
IconButton,
Icon,
Stack,
} from '@chakra-ui/react';
import { useEffect, useState } from 'react';
import { FiChevronRight } from 'react-icons/fi';
import { Link, generatePath } from 'react-router-dom';

import { Requests } from '~/widgets/project';
import { RequestParticipant, Requests } from '~/widgets/project';

import { useUpdateParticipant } from '~/features/project';

Expand All @@ -34,7 +36,9 @@ import {
import { useGetSkills, useGetSpecs } from '~/entities/storage';

import { useAuth, useIsMobile, useLayoutRefs } from '~/shared/hooks';
import { PATHS } from '~/shared/lib/router';
import { GoBack } from '~/shared/ui/GoBack';
import { Modal } from '~/shared/ui/Modal';

interface ProjectBase {
projectId: string;
Expand All @@ -45,6 +49,11 @@ export const ProjectBase = ({ projectId }: ProjectBase) => {
const { userId } = useAuth();
const isMobile = useIsMobile();
const { isOpen, onOpen, onClose } = useDisclosure();
const {
isOpen: leftIsOpen,
onOpen: leftOnOpen,
onClose: leftOnClose,
} = useDisclosure();
const [specsIds, setSpecsIds] = useState<string[]>([]);
const [unvaluedSkillsIds, setUnvaluedSkillsIds] = useState<string[][]>([]);
const [readySkillsIds, setReadySkillsIds] = useState<string[][]>([]);
Expand Down Expand Up @@ -96,10 +105,11 @@ export const ProjectBase = ({ projectId }: ProjectBase) => {
loadedPositionSkillsValue &&
!!positionSkillsValue.length;

const leaveProject = () => {
const leaveProject = async () => {
const participantId = allParticipant?.data.find(({ user_id }) => userId === user_id);
if (participantId) {
updateParticipant({ participant_id: participantId.id, status: 'left' });
await updateParticipant({ participant_id: participantId.id, status: 'left' });
leftOnClose();
}
};

Expand Down Expand Up @@ -138,14 +148,19 @@ export const ProjectBase = ({ projectId }: ProjectBase) => {
>
<Avatar projectId={projectId} />
<CardBody padding={isMobile ? 5 : 6}>
<ProjectInfo
allSpecs={specs}
specs={specsIds}
skills={readySkillsIds}
project={project}
positions={projectPositions}
ioadedPositions={loadedAllPositions}
/>
{allParticipant && (
<ProjectInfo
allSpecs={specs}
specs={specsIds}
skills={readySkillsIds}
project={project}
positions={projectPositions}
ioadedPositions={loadedAllPositions}
userIsOwner={!userNotOwner}
userId={userId}
participants={allParticipant.data}
/>
)}
{!userNotOwner && (
<IconButton
size="md"
Expand All @@ -170,7 +185,7 @@ export const ProjectBase = ({ projectId }: ProjectBase) => {
}
/>
)}
<Modal onClose={onClose} size="full" isOpen={isOpen}>
<ChakraModal onClose={onClose} size="full" isOpen={isOpen}>
<ModalOverlay />
<ModalContent bg="bg" display="flex" alignItems="center">
{allParticipant && projectPositions && (
Expand All @@ -184,9 +199,23 @@ export const ProjectBase = ({ projectId }: ProjectBase) => {
/>
)}
</ModalContent>
</Modal>
</ChakraModal>

{userNotOwner && <Contacts ownerId={project.owner_id} />}
<Stack mt={3}>
<Contacts ownerId={project.owner_id} />
<Stack>
{allParticipant?.data
.filter(({ status }) => status === 'joined')
.map((participant) => (
<Link
key={participant.user_id}
to={generatePath(PATHS.profile, { id: participant.user_id })}
>
<RequestParticipant userId={participant.user_id} allSpecs={specs} />
</Link>
))}
</Stack>
</Stack>
</CardBody>
</ChakraCard>
)}
Expand All @@ -207,10 +236,19 @@ export const ProjectBase = ({ projectId }: ProjectBase) => {
</Button>
)}
{userStatus === 'joined' && (
<Button onClick={leaveProject} fontSize="sm" fontWeight="600" w="full">
<Button onClick={leftOnOpen} fontSize="sm" fontWeight="600" w="full">
Покинуть проект
</Button>
)}
<Modal
isOpen={leftIsOpen}
onClose={leftOnClose}
submitText="Покинуть проект"
cancelText="Отмена"
onSubmit={leaveProject}
>
Вы уверены, что хотите покинуть проект?
</Modal>
{userStatus === 'declined' && (
<Button
isDisabled
Expand Down
8 changes: 7 additions & 1 deletion src/pages/projects/ui/ProjectsBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@ export const ProjectsBase = ({ userId }: ProjectPageProps) => {
description={project.description}
>
<Flex justifyContent="space-between" alignItems="center">
<STag mainTags={['Организатор']} />
<STag
mainTags={
project.owner_id === userId
? ['Организатор']
: ['Участник']
}
/>
{/* <AvatarsGroup avatars={dummyAvatars} /> */}
</Flex>
</ProjectCard>
Expand Down
1 change: 1 addition & 0 deletions src/widgets/project/requests/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './Requests';
export * from './RequestParticipant';

0 comments on commit cd5f945

Please sign in to comment.