Skip to content

Commit

Permalink
Merge pull request #56 from Beside-Potenday/seungbeom
Browse files Browse the repository at this point in the history
feat: 직장인 기능 추가
  • Loading branch information
seung365 authored Aug 5, 2024
2 parents 8599bb8 + d575e6c commit 29dab06
Show file tree
Hide file tree
Showing 18 changed files with 705 additions and 266 deletions.
63 changes: 46 additions & 17 deletions src/Provider/MailContext.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import React, { createContext, useContext, useState } from 'react';
import type { ReactNode } from 'react';
import { MailInput } from '@/types';

import { mailSend } from '@/types';
export type mailSendUniv = {
sender: string;
content: string;
department: string;
studentId: string;
subject: string;
receiver: string;
};

export type mailSendBusiness = {
content: string;
sender: string;
company: string;
department: string;
additional: string;
name: string;
};

interface MailContextProps {
mailInput: mailSend;
handleMail: (mailBox: mailSend) => void;
isActive: string;
onIsActive: (state: string) => void;
mailInput: MailInput;
handleMail: (mailBox: MailInput) => void;
isActive: 'univ' | 'business';
onIsActive: (state: 'univ' | 'business') => void;
}

export const MailContext = createContext<MailContextProps | null>(null);

export const MailProvider = ({ children }: { children: ReactNode }) => {
const [isActive, setIsActive] = useState('univ');
const [mailInput, setMailInput] = useState<mailSend>({
const [isActive, setIsActive] = useState<'univ' | 'business'>('univ');
const [mailInput, setMailInput] = useState<MailInput>({
sender: '',
content: '',
department: '',
Expand All @@ -23,19 +40,31 @@ export const MailProvider = ({ children }: { children: ReactNode }) => {
receiver: '',
});

const handleMail = (mailBox: mailSend) => {
setMailInput({
sender: mailBox.sender,
content: mailBox.content,
department: mailBox.department,
studentId: mailBox.studentId,
subject: mailBox.subject,
receiver: mailBox.receiver,
});
const handleMail = (mailBox: MailInput) => {
setMailInput(mailBox);
};

const onIsActive = (state: string) => {
const onIsActive = (state: 'univ' | 'business') => {
setIsActive(state);
if (state === 'business') {
setMailInput({
content: '',
sender: '',
company: '',
department: '',
additional: '',
receiver: '',
});
} else {
setMailInput({
sender: '',
content: '',
department: '',
studentId: '',
subject: '',
receiver: '',
});
}
};

return (
Expand Down
27 changes: 27 additions & 0 deletions src/api/hooks/usePostBusiness.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useMutation } from '@tanstack/react-query';
import { mailSendBusiness, mailResponseData } from '@/types';
import { BASE_URL } from '..';
import axios from 'axios';

export const postBusinessPath = () => `${BASE_URL}/api/mails/business`;

export const postBusiness = async (mailData: mailSendBusiness): Promise<mailResponseData> => {
const response = await axios.post<mailResponseData>(postBusinessPath(), mailData);
return response.data;
};

export const usePostBusiness = () => {
const { mutate: businessMutate, status: businessStatus } = useMutation<
mailResponseData,
Error,
mailSendBusiness
>({
mutationFn: postBusiness,
retry: 3,
onError: (error) => {
console.error('API call failed:', error);
},
});

return { businessMutate, businessStatus };
};
12 changes: 8 additions & 4 deletions src/api/hooks/usePostUniv.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import { useMutation } from '@tanstack/react-query';
import { mailSend, mailResponseData } from '@/types';
import { mailSendUniv, mailResponseData } from '@/types';
import { BASE_URL } from '..';
import axios from 'axios';

export const postUnivPath = () => `${BASE_URL}/api/mails/univ`;

export const postUniv = async (mailData: mailSend): Promise<mailResponseData> => {
export const postUniv = async (mailData: mailSendUniv): Promise<mailResponseData> => {
const response = await axios.post<mailResponseData>(postUnivPath(), mailData);
return response.data;
};

export const usePostUniv = () => {
const mutation = useMutation<mailResponseData, Error, mailSend>({
const { mutate: univMutate, status: univStatus } = useMutation<
mailResponseData,
Error,
mailSendUniv
>({
mutationFn: postUniv,
retry: 3,
onError: (error) => {
console.error('API call failed:', error);
},
});

return mutation;
return { univMutate, univStatus };
};
86 changes: 47 additions & 39 deletions src/components/HomePage/TestersBox/AskList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import React from 'react';
import styled from '@emotion/styled';
import { mailSend } from '@/types';

interface AskListProps {
randomInput: mailSend;
}
import { AskListProps, Question } from '@/types';
import { useMail } from '@/Provider/MailContext';
import { useState, useEffect } from 'react';

const purposes = [
{ id: '질문', label: '🙋🏻‍♂️질문' },
Expand All @@ -15,45 +13,56 @@ const purposes = [
];

export const AskList = ({ randomInput }: AskListProps) => {
const { isActive } = useMail();
const [questions, setQuestions] = useState<Question[]>([]);

useEffect(() => {
if (isActive === 'business' && 'company' in randomInput) {
setQuestions([
{ ask: '메일 작성 목적을 입력해 주세요', input: randomInput.content },
{ ask: '보내는 사람의 이름을 입력해 주세요', input: randomInput.sender },
{ ask: '소속 회사명을 입력해 주세요', input: randomInput.company },
{ ask: '소속 부서를 입력해 주세요', input: randomInput.department },
{ ask: '추가 기재사항을 입력해 주세요', input: randomInput.additional },
{ ask: '받는 사람의 이름을 입력해 주세요', input: randomInput.receiver },
]);
} else if (isActive !== 'business' && 'studentId' in randomInput) {
setQuestions([
{ ask: '메일 작성 목적을 입력해 주세요', input: randomInput.content },
{ ask: '보내는 사람의 이름을 입력해 주세요', input: randomInput.sender },
{ ask: '보내는 사람의 학과를 입력해 주세요', input: randomInput.department },
{ ask: '보내는 사람의 학번을 입력해 주세요', input: randomInput.studentId },
{ ask: '강의명을 입력해 주세요', input: randomInput.subject },
{ ask: '받는 사람의 이름을 입력해주세요', input: randomInput.receiver },
]);
}
}, [isActive, randomInput]);

return (
<AskListWrapper>
<AskListItemWrapper>
<AskListItem>메일 작성 목적을 입력해 주세요</AskListItem>
<InputListItem style={{ display: 'flex', flexDirection: 'row', gap: '4px' }}>
{purposes.map((purpose) => (
<PurposeButton key={purpose.id} selected={randomInput.content === purpose.id}>
{purpose.label}
</PurposeButton>
))}
</InputListItem>
</AskListItemWrapper>
<AskListItemWrapper>
<AskListItem>보내는 사람의 이름을 입력해 주세요</AskListItem>
<InputListItem>{randomInput.sender}</InputListItem>
</AskListItemWrapper>
<AskListItemWrapper>
<AskListItem>보내는 사람의 학과를 입력해 주세요</AskListItem>
<InputListItem>{randomInput.department}</InputListItem>
</AskListItemWrapper>
<AskListItemWrapper>
<AskListItem>보내는 사람의 학번을 입력해 주세요</AskListItem>
<InputListItem>{randomInput.studentId}</InputListItem>
</AskListItemWrapper>
<AskListItemWrapper>
<AskListItem>강의명을 입력해 주세요</AskListItem>
<InputListItem>{randomInput.subject}</InputListItem>
</AskListItemWrapper>
<AskListItemWrapper>
<AskListItem>받는 사람의 이름을 입력해주세요</AskListItem>
<InputListItem>{randomInput.receiver}</InputListItem>
</AskListItemWrapper>
{questions.map((question, index) => (
<AskListItemWrapper key={index}>
<AskListItem>{question.ask}</AskListItem>
{isActive === 'univ' && index === 0 ? (
<InputListItem style={{ display: 'flex', flexDirection: 'row', gap: '4px' }}>
{purposes.map((purpose) => (
<PurposeButton key={purpose.id} selected={randomInput.content === purpose.id}>
{purpose.label}
</PurposeButton>
))}
</InputListItem>
) : (
<InputListItem>{question.input}</InputListItem>
)}
</AskListItemWrapper>
))}
</AskListWrapper>
);
};

const AskListWrapper = styled.div`
width: 768px;
height: auto;
height: 750px;
flex-shrink: 0;
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.3);
Expand All @@ -62,10 +71,9 @@ const AskListWrapper = styled.div`
flex-direction: column;
padding-left: 36px;
padding-top: 46px;
padding-bottom: 46px;
gap: 40px;
padding-bottom: 86px;
gap: 10px;
`;

const AskListItemWrapper = styled.div`
display: flex;
flex-direction: column;
Expand Down
63 changes: 48 additions & 15 deletions src/components/HomePage/TestersBox/Buttons.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from '@emotion/styled';
import { mailSend } from '@/types';
import { MailInput, mailSendUniv, mailSendBusiness } from '@/types';
import { usePostUniv } from '@/api/hooks/usePostUniv';
import { useState } from 'react';
import {
Expand All @@ -13,27 +13,52 @@ import {
Button,
Spinner,
} from '@chakra-ui/react';
import { useMail } from '@/Provider/MailContext';
import { usePostBusiness } from '@/api/hooks/usePostBusiness';

interface ButtonsProps {
handleList: () => void;
randomInput: mailSend;
handleListUniv: () => void;
handleListBusiness: () => void;
randomInput: MailInput;
}

export const Buttons = ({ handleList, randomInput }: ButtonsProps) => {
const { mutate, status } = usePostUniv();
export const Buttons = ({ handleListUniv, handleListBusiness, randomInput }: ButtonsProps) => {
const { univMutate, univStatus } = usePostUniv();
const { businessMutate, businessStatus } = usePostBusiness();

const [isOpen, setIsOpen] = useState(false);
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
const { isActive } = useMail();

const onClose = () => {
setIsOpen(false);
};

const setMailInput = () => {
const setMailInputUniv = () => {
setIsOpen(true);

univMutate(
{ ...(randomInput as unknown as mailSendUniv) },
{
onSuccess: (data) => {
console.log(data);
setTitle(data.title || '메일 생성 성공');
setContent(data.content || '메일이 성공적으로 생성되었습니다.');
},
onError: (error) => {
setTitle('메일 생성 실패');
setContent('메일 생성 중 오류가 발생했습니다.');
},
},
);
};

const setMailInputBusiness = () => {
setIsOpen(true);

mutate(
{ ...randomInput },
businessMutate(
{ ...(randomInput as unknown as mailSendBusiness) },
{
onSuccess: (data) => {
console.log(data);
Expand All @@ -48,30 +73,34 @@ export const Buttons = ({ handleList, randomInput }: ButtonsProps) => {
);
};

const isLoading = univStatus === 'pending' || businessStatus === 'pending';

return (
<ButtonsWrapper>
<ButtonContainer>
<ExampleButton onClick={handleList}>
<ExampleButton
onClick={() => (isActive === 'univ' ? handleListUniv() : handleListBusiness())}
>
<ExampleChangeIcon className="example-change-icon" /> 예시 변경
</ExampleButton>
</ButtonContainer>
<ButtonContainer>
<MailButton onClick={setMailInput}>
<MailButton
onClick={() => (isActive === 'univ' ? setMailInputUniv() : setMailInputBusiness())}
>
<MakeMailIcon className="make-mail-icon" />
메일 생성하기
</MailButton>
</ButtonContainer>
<ModalWrapper>
<StyledModal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
{status === 'pending' || status === 'error' ? (
{isLoading ? (
<SmallModalContent>
<ModalHeader>
{status === 'pending' ? '메일 생성 중...조금만 기다려 주세요!' : title}
</ModalHeader>
<ModalHeader>메일 생성 중...조금만 기다려 주세요!</ModalHeader>
<ModalCloseButton />
<ModalBody>
{status === 'pending' ? <Spinner size="xl" /> : <p>{content}</p>}
<Spinner size="xl" />
</ModalBody>
</SmallModalContent>
) : (
Expand Down Expand Up @@ -105,6 +134,10 @@ const ButtonsWrapper = styled.div`
align-items: center;
justify-content: space-around;
padding: 20px 0;
z-index: 2;
position: absolute;
top: 50%;
left: 20%;
`;

const ButtonContainer = styled.div`
Expand Down
Loading

0 comments on commit 29dab06

Please sign in to comment.