Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/joinProject.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const getProjectData = async (
return response.data;
};

export const createProject = async (formData: FormData) => {
export const postProject = async (formData: FormData) => {
const response = await httpClient.post(`/project`, formData);
return response.status;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const CareerContainer = styled.div`
width: 100%;
margin-bottom: 10px;

@media (max-width: 963px) {
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
flex-direction: column;
gap: 10px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const dateStyle = css`
export const CareerInput = styled.input`
${basicStyle}
padding: 10px;
font-size: 18px;
font-size: 16px;

&:focus {
outline: none;
Expand All @@ -40,18 +40,19 @@ export const CareerInput = styled.input`
font-size: ${({ theme }) => theme.heading.small.fontSize};
}

@media (max-width: 963px) {
width: 100%;
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
flex: 1;
margin-bottom: 10px;

&:nth-child(1),
&:nth-child(4) {
width: 60%;
flex: 1;
}

&:nth-child(2),
&:nth-child(3) {
width: 20%;
flex: 1;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,6 @@ export const PhoneInputContainer = styled.div`
position: relative;
`;

export const PhoneInput = styled.input<{ name: string }>`
width: 60px;
padding: 10px;
border: 1px solid ${({ theme }) => theme.color.border};
border-radius: ${({ theme }) => theme.borderRadius.primary};
text-align: center;
font-size: 18px;

&:focus {
outline: none;
border-color: #888;
}
`;

export const Dash = styled.span`
align-self: center;
font-size: 25px;
Expand All @@ -30,7 +16,7 @@ export const Dash = styled.span`

export const FormError = styled.p`
margin-top: 0.3px;
font-size: 1rem;
font-size: 0.9rem;
color: ${({ theme }) => theme.color.red};
position: absolute;
top: 115%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,9 @@ export const PhoneInput = styled.input`
border: 1px solid ${({ theme }) => theme.color.border};
border-radius: ${({ theme }) => theme.borderRadius.primary};
text-align: center;
font-size: 19px;
font-size: 17px;

&:focus {
outline: none;
border-color: #888;
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
font-size: 15px;
}
`;

export const FormError = styled.p`
margin-top: 0.3px;
font-size: 1rem;
color: ${({ theme }) => theme.color.red};
position: absolute;
top: 100%;
left: 0;
white-space: nowrap;
`;
15 changes: 5 additions & 10 deletions src/components/common/modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import { useRef, useState } from 'react';
import { useState } from 'react';
import { createPortal } from 'react-dom';
import { XMarkIcon, CheckCircleIcon } from '@heroicons/react/24/outline';
import * as S from './Modal.styled';
import ScrollPreventor from './ScrollPreventor';
import { useOutsideClick } from '../../../hooks/useOutsideClick';

interface ModalProps {
children: React.ReactNode;
isOpen: boolean;
onClose: () => void;
}

const Modal = ({ children, isOpen, onClose }: ModalProps) => {
const modalRef = useRef<HTMLDivElement | null>(null);
const modalRefs = useOutsideClick(() => handleClose());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useOutsideClick을 활용해서 로직이 더 간결해 졌네요! 감사합니다~

const [isFadingOut, setIsFadingOut] = useState(false);

const handleClose = () => {
setIsFadingOut(true);
};

const handleOverlayClick = (e: React.MouseEvent) => {
if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
handleClose();
}
};

const handleAnimationEnd = () => {
if (isFadingOut) {
onClose();
Expand All @@ -36,10 +32,9 @@ const Modal = ({ children, isOpen, onClose }: ModalProps) => {
<ScrollPreventor>
<S.ModalContainer
className={isFadingOut ? 'fade-out' : 'fade-in'}
onClick={handleOverlayClick}
onAnimationEnd={handleAnimationEnd}
>
<S.ModalBody ref={modalRef}>
<S.ModalBody ref={modalRefs}>
<S.ModalCloseButton onClick={handleClose}>
<XMarkIcon />
</S.ModalCloseButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const InputStyle = styled.input<{ type?: string }>`
padding: 10px;
border: 1px solid ${({ theme }) => theme.color.border};
border-radius: ${({ theme }) => theme.borderRadius.primary};
font-size: ${({ theme }) => theme.heading.semiSmall.fontSize};
font-size: ${({ theme }) => theme.heading.small.fontSize};

${({ type }) => {
switch (type) {
Expand All @@ -24,7 +24,6 @@ export const InputStyle = styled.input<{ type?: string }>`
flex: 0.1;
background-color: #ffffff;
color: #aaa;
font-family: 'Arial', sans-serif;

&::placeholder {
color: #aaa;
Expand Down Expand Up @@ -74,7 +73,7 @@ export const InputInfoStyle = styled.input<{ type?: string }>`

export const FormError = styled.p`
margin-top: 0.3px;
font-size: 1rem;
font-size: 0.9rem;
color: ${({ theme }) => theme.color.red};
position: absolute;
top: 115%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const SectionInput = styled.div`
flex-direction: column;
gap: 1px;

@media (max-width: 1024px) {
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
margin-bottom: 25px;
}
`;
Expand All @@ -25,9 +25,9 @@ export const InfoRow = styled.div`
margin-right: 10px;
}

@media (max-width: 1024px) {
margin-bottom: 15px;
}
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
align-items: flex-start;
margin-bottom: 15px;
`;

export const InfoLabel = styled.label`
Expand All @@ -39,7 +39,7 @@ export const InfoLabel = styled.label`
margin-right: 15px;
white-space: nowrap;

@media (max-width: 1024px) {
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
margin-right: 30px;
margin-bottom: 8px;
font-size: 0.9rem;
Expand All @@ -53,7 +53,7 @@ export const InfoText = styled.p`
flex: 0.8;
text-align: left;

@media (max-width: 1024px) {
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
font-size: 0.95rem;
flex: 1;
}
Expand All @@ -65,7 +65,7 @@ export const SkillTagContainer = styled.div`
gap: 10px;
flex: 0.9;

@media (max-width: 1024px) {
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
grid-template-columns: repeat(6, 1fr);
gap: 8px;
width: 100%;
Expand Down Expand Up @@ -94,7 +94,7 @@ export const SkillTagImage = styled.div`
margin-top: 2px;
}

@media (max-width: 1024px) {
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
img {
width: 35px;
height: 35px;
Expand All @@ -116,7 +116,7 @@ export const BeginnerIcon = styled.img`
object-fit: contain;
margin-bottom: 15px;

@media (max-width: 1024px) {
@media screen and ${({ theme }) => theme.mediaQuery.tablet} {
width: 18px;
height: 18px;
margin-bottom: 10px;
Expand Down
6 changes: 6 additions & 0 deletions src/constants/modalMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@ export const MODAL_MESSAGE = {
myProfileFail: '프로필 수정에 실패했습니다.',
profileImgSuccess: '프로필 이미지가 업로드 되었습니다.',
profileImgFail: '이미지는 5MB 이하, .png.jpg.jpeg.svg 형식만 가능합니다.',
ModifyProjectSuccess: '공고 수정이 정상적으로 완료 되었습니다.',
ModifyProjectFail: '공고 수정을 실패 했습니다.',
createProjectSuccess: '공고 생성을 완료 했습니다.',
createProjectFail: '공고 생성을 실패 했습니다.',
applyProjectSuccess: '해당 공고에 지원을 완료 되었습니다.',
applyProjectFail: '해당 공고에 지원을 실패 되었습니다.',
} as const;
44 changes: 44 additions & 0 deletions src/hooks/useApplyProject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useMutation } from '@tanstack/react-query';
import { MODAL_MESSAGE } from '../constants/modalMessage';
import { postApplicantProject } from '../api/joinProject.api';
import { ROUTES } from '../constants/routes';
import { useNavigate } from 'react-router-dom';
import { joinProject } from '../models/joinProject';

interface UseApplyProjectProps {
id: number;
handleModalOpen: (newMessage: string) => void;
}

const useApplyProject = ({ id, handleModalOpen }: UseApplyProjectProps) => {
const navigate = useNavigate();

const mutation = useMutation({
mutationFn: (formData: joinProject) => postApplicantProject(formData, id),
onSuccess: () => {
handleModalOpen(MODAL_MESSAGE.applyProjectSuccess);

setTimeout(() => {
navigate(ROUTES.main);
}, 3000);
},
onError: (error) => {
console.log(error);
handleModalOpen(MODAL_MESSAGE.applyProjectFail);
},
});

const applyProject = async (formData: joinProject) => {
mutation.mutate(formData);
};

return {
applyProject,
isLoading: mutation.isPending,
isError: mutation.isError,
error: mutation.error,
isSuccess: mutation.isSuccess,
};
};

export default useApplyProject;
52 changes: 52 additions & 0 deletions src/hooks/useCreateProject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useMutation } from '@tanstack/react-query';
import { FormData } from '../models/createProject';
import { MODAL_MESSAGE } from '../constants/modalMessage';
import { postProject } from '../api/joinProject.api';
import { Dispatch, SetStateAction } from 'react';
import { useSaveSearchFiltering } from './useSaveSearchFiltering';
import { ROUTES } from '../constants/routes';
import { useNavigate } from 'react-router-dom';

interface UseCreateProjectProps {
handleModalOpen: (newMessage: string) => void;
setIsSubmit: Dispatch<SetStateAction<boolean>>;
}

const useCreateProject = ({
handleModalOpen,
setIsSubmit,
}: UseCreateProjectProps) => {
const navigate = useNavigate();
const { handleUpdateFilters } = useSaveSearchFiltering();

const mutation = useMutation({
mutationFn: (formData: FormData) => postProject(formData),
onSuccess: () => {
handleModalOpen(MODAL_MESSAGE.createProjectSuccess);
setIsSubmit(true);
handleUpdateFilters('skillTag', []);

setTimeout(() => {
navigate(ROUTES.main);
}, 3000);
},
onError: (error) => {
console.log(error);
handleModalOpen(MODAL_MESSAGE.createProjectFail);
},
});

const createProject = async (formData: FormData) => {
mutation.mutate(formData);
};

return {
createProject,
isLoading: mutation.isPending,
isError: mutation.isError,
error: mutation.error,
isSuccess: mutation.isSuccess,
};
};

export default useCreateProject;
9 changes: 8 additions & 1 deletion src/hooks/useModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useState } from 'react';
export const useModal = () => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [message, setMessage] = useState<string>('');

const handleModalOpen = (newMessage: string) => {
setMessage(newMessage);
setIsOpen(true);
Expand All @@ -13,5 +14,11 @@ export const useModal = () => {
setIsOpen(false);
};

return { isOpen, message, setIsOpen, handleModalClose, handleModalOpen };
return {
isOpen,
message,
setIsOpen,
handleModalClose,
handleModalOpen,
};
};
Loading