From 2d680d8d6e56496f949e1693103281dc1d3ab402 Mon Sep 17 00:00:00 2001 From: seung365 Date: Mon, 5 Aug 2024 03:27:59 +0900 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20mainheader=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/MainHeader.tsx | 131 +++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/components/Layout/MainHeader.tsx diff --git a/src/components/Layout/MainHeader.tsx b/src/components/Layout/MainHeader.tsx new file mode 100644 index 0000000..fe0ec50 --- /dev/null +++ b/src/components/Layout/MainHeader.tsx @@ -0,0 +1,131 @@ +import styled from '@emotion/styled'; +import { Link } from 'react-router-dom'; +import { Button } from '@chakra-ui/react'; +import { breakpoints } from '@/styles/variants'; +import { useMail } from '@/Provider/MailContext'; + +const scrollToSection = (sectionId: string) => { + const element = document.getElementById(sectionId); + if (element) { + const elementPosition = element.getBoundingClientRect().top + window.scrollY - 80; + window.scrollTo({ top: elementPosition, behavior: 'smooth' }); + } +}; + +export const MainHeader = () => { + const mailContext = useMail(); + + if (!mailContext) { + throw new Error('MailContext not found'); + } + const { handleMail } = mailContext; + + const handleMailInput = () => { + handleMail({ + sender: '', + content: '', + department: '', + studentId: '', + subject: '', + receiver: '', + }); + }; + + return ( + + +
Login
+ + + +
+
+ scrollToSection('section2')}> 서비스 체험 + scrollToSection('section3')}> 기능 살펴보기 +
+ + AI 메일 생성하기 + +
+
+
+ ); +}; + +export const HEADER_HEIGHT = '80px'; + +const Wrapper = styled.header` + z-index: 100; + height: ${HEADER_HEIGHT}; + padding: 16px 40px; + background: linear-gradient(90deg, #e6e9ff 0%, #e5f3ff 100%); + box-shadow: 0px 2px 18px 2px rgba(0, 0, 0, 0.1); +`; + +const Logo = styled.img` + height: 48px; + cursor: pointer; +`; + +const Container = styled.div` + display: flex; + flex-direction: row; + font-size: 14px; + justify-content: space-between; +`; + +const AiButton = styled(Button)` + position: relative; + display: flex; + height: 40px; + width: 136px; + padding: 10px 20px; + border-radius: 20px; + align-items: center; + justify-content: center; + gap: 10px; + background-color: transparent; + color: #000000; + font-family: 'Inter', sans-serif; + font-weight: 400; + font-size: 14px; + line-height: 19.6px; + letter-spacing: -2%; + background-clip: padding-box; + + &:hover { + background: linear-gradient(to right, #6ab9f2, #7a89f0); + color: white; + } + + &:before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 20px; + padding: 1px; + background: linear-gradient(to right, #6ab9f2, #7a89f0); + -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + } +`; + +const MidWrapper = styled.div` + cursor: pointer; + margin: 0px 20px; + @media (max-width: ${breakpoints.md}) { + display: none; + } +`; + +const LogoLink = styled(Link)` + margin-left: 250px; + + @media (max-width: ${breakpoints.md}) { + margin-left: 100px; + } +`; From 564e27603b09b200c7669962a0f05bcd6864f115 Mon Sep 17 00:00:00 2001 From: seung365 Date: Mon, 5 Aug 2024 03:30:43 +0900 Subject: [PATCH 02/18] =?UTF-8?q?feat:=20homepage=20layout=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/index.tsx | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 01f9e4e..5f7e898 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -1,14 +1,18 @@ import styled from '@emotion/styled'; import { Outlet } from 'react-router-dom'; -import { Header, HEADER_HEIGHT } from './Header'; - import { Footer } from './Footer'; - +import { MainHeader } from './MainHeader'; +import { UpperImage } from './UpperImage'; export const Layout = () => { return ( -
+ + + + + + @@ -22,9 +26,20 @@ const Wrapper = styled.div` position: relative; `; +const UpperImageWrapper = styled.div` + width: 100%; + height: 93vh; /* 필요에 따라 조정 */ +`; + +const HeaderWrapper = styled.div` + width: 100%; + position: sticky; + top: 0; + z-index: 100; +`; + const InnerWrapper = styled.div` width: 100%; - padding-top: ${HEADER_HEIGHT}; position: relative; background-color: transparent; `; From 6eac535103e8ff70f475433f2e9cc498fc52c967 Mon Sep 17 00:00:00 2001 From: seung365 Date: Mon, 5 Aug 2024 03:31:37 +0900 Subject: [PATCH 03/18] =?UTF-8?q?design:=20homepage=20wrapper=20height=201?= =?UTF-8?q?00%=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Home/index.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index b78621a..3844c8a 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -1,13 +1,13 @@ -import { Contents } from "@/components/HomePage/Contents" -import styled from "@emotion/styled" +import { Contents } from '@/components/HomePage/Contents'; +import styled from '@emotion/styled'; export const HomePage = () => { return ( - ) -} + ); +}; const Wrapper = styled.div` width: 100%; @@ -15,4 +15,5 @@ const Wrapper = styled.div` radial-gradient(50% 50% at 25% 25%, #dee2fd 0%, rgba(230, 233, 255, 0) 100%), linear-gradient(180deg, #e5efff 0%, #fff 100%); overflow-x: hidden; -` + height: 100%; +`; From 61b34f8a552b1b4fef81a2c5d43631e2fb7037e4 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:02:17 +0900 Subject: [PATCH 04/18] =?UTF-8?q?feat:=20mock=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=A7=81=EC=9E=A5=EC=9D=B8=20=EB=B2=84=EC=A0=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/mock/mockBusiness.ts | 82 ++++++++++++++++++++++++++++++++++ src/types/mock/mockUniv.ts | 82 ++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/types/mock/mockBusiness.ts create mode 100644 src/types/mock/mockUniv.ts diff --git a/src/types/mock/mockBusiness.ts b/src/types/mock/mockBusiness.ts new file mode 100644 index 0000000..16e7278 --- /dev/null +++ b/src/types/mock/mockBusiness.ts @@ -0,0 +1,82 @@ +export const mockDataBusiness = [ + { + content: '프로젝트 제안서 전달', + sender: '김철수', + company: 'ABC 주식회사', + department: '영업부', + additional: '계약서 초안 첨부', + receiver: '이영희', + }, + { + content: '신제품 출시 안내', + sender: '박민수', + company: 'XYZ 코퍼레이션', + department: '마케팅부', + additional: '브로셔 포함', + receiver: '최현우', + }, + { + content: '협력 요청', + sender: '이준호', + company: '테크노 로지스틱스', + department: '기술부', + additional: '기술 사양서 동봉', + receiver: '정예린', + }, + { + content: '견적 요청', + sender: '홍길동', + company: '스마트솔루션', + department: '구매부', + additional: '상세 요구사항 기재', + receiver: '김혜진', + }, + { + content: '출장 계획 공유', + sender: '김영희', + company: '글로벌 네트워크', + department: 'HR부', + additional: '일정표 첨부', + receiver: '박지성', + }, + { + content: '이벤트 초청', + sender: '박지훈', + company: '크리에이티브 미디어', + department: 'PR부', + additional: '초청장 동봉', + receiver: '김수현', + }, + { + content: '계약서 확인 요청', + sender: '이수진', + company: '네오테크', + department: '법무부', + additional: '계약서 초안 검토 요청', + receiver: '이서준', + }, + { + content: '제품 사용 설명서 전달', + sender: '정민호', + company: '에이스 전자', + department: '고객지원부', + additional: '사용 설명서 PDF 파일 첨부', + receiver: '오지현', + }, + { + content: '연말 파티 초대', + sender: '최지우', + company: '스타트업 스튜디오', + department: '이벤트 기획부', + additional: '참석 여부 회신 요청', + receiver: '장민혁', + }, + { + content: '프로젝트 진행 상황 보고', + sender: '한지민', + company: '알파인 소프트웨어', + department: '프로젝트 관리부', + additional: '진행 상황 요약 문서 포함', + receiver: '조은별', + }, +]; diff --git a/src/types/mock/mockUniv.ts b/src/types/mock/mockUniv.ts new file mode 100644 index 0000000..05bc53b --- /dev/null +++ b/src/types/mock/mockUniv.ts @@ -0,0 +1,82 @@ +export const mockDataUniv = [ + { + subject: '자료구조', + department: '컴퓨터공학과', + studentId: '2020123456', + content: '질문', + sender: '홍길동', + receiver: '안지선', + }, + { + subject: '회로이론', + department: '전자공학과', + studentId: '2020234567', + content: '과제 제출', + sender: '이영희', + receiver: '김서현', + }, + { + subject: '열역학', + department: '기계공학과', + studentId: '2020345678', + content: '성적 정정', + sender: '박준영', + receiver: '최은지', + }, + { + subject: '운영관리', + department: '산업공학과', + studentId: '2020456789', + content: '병결 요청', + sender: '정수현', + receiver: '강민호', + }, + { + subject: '화학반응공학', + department: '화학공학과', + studentId: '2020567890', + content: '상담 요청', + sender: '최지우', + receiver: '홍길동', + }, + { + subject: '건축설계', + department: '건축학과', + studentId: '2020678901', + content: '질문', + sender: '김도윤', + receiver: '이수민', + }, + { + subject: '구조역학', + department: '토목공학과', + studentId: '2020789012', + content: '과제 제출', + sender: '한지민', + receiver: '박현우', + }, + { + subject: '알고리즘', + department: '컴퓨터공학과', + studentId: '2020890123', + content: '성적 정정', + sender: '윤재현', + receiver: '정다은', + }, + { + subject: '전자기학', + department: '전자공학과', + studentId: '2020901234', + content: '병결 요청', + sender: '서지훈', + receiver: '김나윤', + }, + { + subject: '기계진동', + department: '기계공학과', + studentId: '2021012345', + content: '상담 요청', + sender: '장예은', + receiver: '오준석', + }, +]; From be4918c38ee0a60a167c5c266d20c6caa776ee5f Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:02:58 +0900 Subject: [PATCH 05/18] =?UTF-8?q?feat:=20=EC=A7=81=EC=9E=A5=EC=9D=B8=20api?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/hooks/usePostBusiness.tsx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/api/hooks/usePostBusiness.tsx diff --git a/src/api/hooks/usePostBusiness.tsx b/src/api/hooks/usePostBusiness.tsx new file mode 100644 index 0000000..5524afa --- /dev/null +++ b/src/api/hooks/usePostBusiness.tsx @@ -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 => { + const response = await axios.post(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 }; +}; From c3408160060e470e6179a2cf6bdc809319fe05b2 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:03:44 +0900 Subject: [PATCH 06/18] =?UTF-8?q?feat:=20=EB=8C=80=ED=95=99=EC=83=9D=20api?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/hooks/usePostUniv.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/api/hooks/usePostUniv.tsx b/src/api/hooks/usePostUniv.tsx index 81eab0c..e8e296b 100644 --- a/src/api/hooks/usePostUniv.tsx +++ b/src/api/hooks/usePostUniv.tsx @@ -1,17 +1,21 @@ 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 => { +export const postUniv = async (mailData: mailSendUniv): Promise => { const response = await axios.post(postUnivPath(), mailData); return response.data; }; export const usePostUniv = () => { - const mutation = useMutation({ + const { mutate: univMutate, status: univStatus } = useMutation< + mailResponseData, + Error, + mailSendUniv + >({ mutationFn: postUniv, retry: 3, onError: (error) => { @@ -19,5 +23,5 @@ export const usePostUniv = () => { }, }); - return mutation; + return { univMutate, univStatus }; }; From 96c7465f15dfc4657b51bed5f9c68d569af46f3a Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:04:24 +0900 Subject: [PATCH 07/18] =?UTF-8?q?feat:=20type=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/index.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/types/index.ts b/src/types/index.ts index c4f6f4c..a128e26 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,4 +1,4 @@ -export type mailSend = { +export type mailSendUniv = { sender: string; receiver: string; department: string; @@ -7,7 +7,27 @@ export type mailSend = { content: string; }; +export type mailSendBusiness = { + content: string; + sender: string; + company: string; + department: string; + additional: string; + receiver: string; +}; + export type mailResponseData = { title: string; content: string; }; + +export interface AskListProps { + randomInput: mailSendUniv | mailSendBusiness; +} + +export interface Question { + ask: string; + input: string; +} + +export type MailInput = mailSendUniv | mailSendBusiness; From e881dfbe68c8afe02ad265c5f948135888d76ce1 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:05:11 +0900 Subject: [PATCH 08/18] =?UTF-8?q?feat:=20mailcontext=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Provider/MailContext.tsx | 63 ++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/src/Provider/MailContext.tsx b/src/Provider/MailContext.tsx index d1ec4ba..a8b0f1c 100644 --- a/src/Provider/MailContext.tsx +++ b/src/Provider/MailContext.tsx @@ -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(null); export const MailProvider = ({ children }: { children: ReactNode }) => { - const [isActive, setIsActive] = useState('univ'); - const [mailInput, setMailInput] = useState({ + const [isActive, setIsActive] = useState<'univ' | 'business'>('univ'); + const [mailInput, setMailInput] = useState({ sender: '', content: '', department: '', @@ -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 ( From 37f2f4865174859bc672ca70eeb5f1cba86f85c8 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:06:26 +0900 Subject: [PATCH 09/18] =?UTF-8?q?feat:=20=ED=99=88=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20header=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/Header.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx index e8d4aca..136fbf7 100644 --- a/src/components/Layout/Header.tsx +++ b/src/components/Layout/Header.tsx @@ -29,6 +29,7 @@ export const Header = () => { subject: '', receiver: '', }); + window.location.reload(); }; return ( From 1cafa9fa241473cdd209322d9d92950a23023c77 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:06:53 +0900 Subject: [PATCH 10/18] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=BC=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Mail/Header.tsx | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/components/Mail/Header.tsx b/src/components/Mail/Header.tsx index b89663b..bf6c62b 100644 --- a/src/components/Mail/Header.tsx +++ b/src/components/Mail/Header.tsx @@ -2,14 +2,26 @@ import styled from '@emotion/styled'; interface HeaderProps { isActive: string; - onIsActive: (isActive: string) => void; + onIsActive: (state: 'univ' | 'business') => void; + onOpen: () => void; + onClose: () => void; } -interface StudentProps { +interface ActiveProps { isActive: string; } -export const Header = ({ isActive, onIsActive }: HeaderProps) => { +export const Header = ({ isActive, onIsActive, onOpen, onClose }: HeaderProps) => { + const handleUniv = () => { + onIsActive('univ'); + onOpen(); + }; + + const handleBusiness = () => { + onIsActive('business'); + onOpen(); + }; + return ( <>
{ paddingTop: '33px', }} > - onIsActive('univ')}> + 대학생 - + 직장인 -
@@ -34,35 +45,22 @@ export const Header = ({ isActive, onIsActive }: HeaderProps) => { ); }; -const Student = styled.div` +const Student = styled.div` margin-left: 167px; cursor: pointer; - box-shadow: ${(props) => (props.isActive ? '0 4px 0 0 #6AB9F2' : 'none')}; + box-shadow: ${(props) => (props.isActive === 'univ' ? '0 4px 0 0 #6AB9F2' : 'none')}; position: relative; z-index: 2; bottom: -13px; `; -const Office = styled.div` +const Office = styled.div` margin-left: 44px; + cursor: pointer; + box-shadow: ${(props) => (props.isActive === 'business' ? '0 4px 0 0 #6AB9F2' : 'none')}; position: relative; z-index: 2; bottom: -13px; - &:hover > img { - visibility: visible; - } -`; - -const HoverImage = styled.img` - visibility: hidden; - position: relative; - top: -70px; - left: 50%; - transform: translateX(-50%); - width: 174px; - height: 34px; - flex-shrink: 0; - z-index: 3; `; const Bar = styled.div` @@ -70,5 +68,5 @@ const Bar = styled.div` width: 1200px; height: 3px; position: absolute; - bottom: 24px; + bottom: 8px; `; From ece05e8c7d2b7404765e53b08037f48515c83f63 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:07:27 +0900 Subject: [PATCH 11/18] =?UTF-8?q?feat:=20mail=EC=9D=98=20asklist=20?= =?UTF-8?q?=EC=A7=81=EC=9E=A5=EC=9D=B8=20=EB=B2=84=EC=A0=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Mail/AskList.tsx | 67 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/components/Mail/AskList.tsx b/src/components/Mail/AskList.tsx index 78e3541..a4eefb6 100644 --- a/src/components/Mail/AskList.tsx +++ b/src/components/Mail/AskList.tsx @@ -1,39 +1,42 @@ import styled from '@emotion/styled'; -import { mailSend } from '@/types'; +import { AskListProps, Question } from '@/types'; +import { useMail } from '@/Provider/MailContext'; +import { useState, useEffect } from 'react'; + +export const AskList = ({ randomInput }: AskListProps) => { + const { isActive } = useMail(); + const [questions, setQuestions] = useState([]); + + 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]); -export const AskList = ({ randomInput }: { randomInput: mailSend }) => { return ( - - 메일 작성 목적을 입력해 주세요 - {randomInput.content || ' '} - - - 보내는 사람의 이름을 입력해 주세요 - {randomInput.sender || ' '} - - - 보내는 사람의 학과를 입력해 주세요 - - {randomInput.department || ' '} - - - - 보내는 사람의 학번을 입력해 주세요 - - {randomInput.studentId || ' '} - - - - 강의명을 입력해 주세요 - {randomInput.subject || ' '} - - - 받는 사람의 이름을 입력해주세요 - - {randomInput.receiver || ' '} - - + {questions.map((question, index) => ( + + {question.ask} + {question.input || ' '} + + ))} ); }; From ce6072e9e7e57bf65bcb3c117a16813e9336d8ca Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:07:52 +0900 Subject: [PATCH 12/18] =?UTF-8?q?feat:=20=ED=99=88=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=B2=B4=ED=97=98=ED=95=98=EA=B8=B0=20asklist=20?= =?UTF-8?q?=EC=A7=81=EC=9E=A5=EC=9D=B8=20=EB=B2=84=EC=A0=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomePage/TestersBox/AskList.tsx | 86 ++++++++++--------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/components/HomePage/TestersBox/AskList.tsx b/src/components/HomePage/TestersBox/AskList.tsx index 3fa2fc2..afa01df 100644 --- a/src/components/HomePage/TestersBox/AskList.tsx +++ b/src/components/HomePage/TestersBox/AskList.tsx @@ -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: '🙋🏻‍♂️질문' }, @@ -15,45 +13,56 @@ const purposes = [ ]; export const AskList = ({ randomInput }: AskListProps) => { + const { isActive } = useMail(); + const [questions, setQuestions] = useState([]); + + 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 ( - - 메일 작성 목적을 입력해 주세요 - - {purposes.map((purpose) => ( - - {purpose.label} - - ))} - - - - 보내는 사람의 이름을 입력해 주세요 - {randomInput.sender} - - - 보내는 사람의 학과를 입력해 주세요 - {randomInput.department} - - - 보내는 사람의 학번을 입력해 주세요 - {randomInput.studentId} - - - 강의명을 입력해 주세요 - {randomInput.subject} - - - 받는 사람의 이름을 입력해주세요 - {randomInput.receiver} - + {questions.map((question, index) => ( + + {question.ask} + {isActive === 'univ' && index === 0 ? ( + + {purposes.map((purpose) => ( + + {purpose.label} + + ))} + + ) : ( + {question.input} + )} + + ))} ); }; 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); @@ -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; From b30d420d821e8bfd9d9701032e02714e2c445dcc Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:08:32 +0900 Subject: [PATCH 13/18] =?UTF-8?q?feat:=20=ED=99=88=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=98=88=EC=8B=9C=20=EC=83=9D=EC=84=B1=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomePage/TestersBox/Buttons.tsx | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/src/components/HomePage/TestersBox/Buttons.tsx b/src/components/HomePage/TestersBox/Buttons.tsx index 9f40a94..77331fe 100644 --- a/src/components/HomePage/TestersBox/Buttons.tsx +++ b/src/components/HomePage/TestersBox/Buttons.tsx @@ -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 { @@ -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); @@ -48,15 +73,21 @@ export const Buttons = ({ handleList, randomInput }: ButtonsProps) => { ); }; + const isLoading = univStatus === 'pending' || businessStatus === 'pending'; + return ( - + (isActive === 'univ' ? handleListUniv() : handleListBusiness())} + > 예시 변경 - + (isActive === 'univ' ? setMailInputUniv() : setMailInputBusiness())} + > 메일 생성하기 @@ -64,14 +95,12 @@ export const Buttons = ({ handleList, randomInput }: ButtonsProps) => { - {status === 'pending' || status === 'error' ? ( + {isLoading ? ( - - {status === 'pending' ? '메일 생성 중...조금만 기다려 주세요!' : title} - + 메일 생성 중...조금만 기다려 주세요! - {status === 'pending' ? :

{content}

} +
) : ( @@ -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` From 1ce5e472f985a3c9e3fe2d3ac178606b1c28d7b9 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:09:19 +0900 Subject: [PATCH 14/18] =?UTF-8?q?feat:=20=ED=99=88=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=B2=B4=ED=97=98=ED=95=98=EA=B8=B0=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=88=98?= =?UTF-8?q?=EC=A0=95+=20=EC=A7=81=EC=9E=A5=EC=9D=B8=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/HomePage/TestersBox/Header.tsx | 88 +++++++------------ 1 file changed, 31 insertions(+), 57 deletions(-) diff --git a/src/components/HomePage/TestersBox/Header.tsx b/src/components/HomePage/TestersBox/Header.tsx index 5e0dfff..25cf29e 100644 --- a/src/components/HomePage/TestersBox/Header.tsx +++ b/src/components/HomePage/TestersBox/Header.tsx @@ -1,90 +1,64 @@ import styled from '@emotion/styled'; -import { breakpoints } from '@/styles/variants'; // breakpoints를 가져옵니다. interface HeaderProps { isActive: string; - onIsActive: (isActive: string) => void; + onIsActive: (state: 'univ' | 'business') => void; } interface StudentProps { isActive: string; } +interface BusinessProps { + isActive: string; +} + export const Header = ({ isActive, onIsActive }: HeaderProps) => { return ( - - onIsActive('univ')}> - 대학생 - - - 직장인 - - + <> +
+ onIsActive('univ')}> + 대학생 + + onIsActive('business')}> + 직장인 + +
-
+ ); }; -const HeaderWrapper = styled.div` - display: flex; - flex-direction: row; - align-items: flex-start; - width: 100%; - padding-top: 33px; - position: relative; -`; - const Student = styled.div` margin-left: 167px; cursor: pointer; - box-shadow: ${(props) => (props.isActive ? '0 4px 0 0 #6AB9F2' : 'none')}; + box-shadow: ${(props) => (props.isActive === 'univ' ? '0 4px 0 0 #6AB9F2' : 'none')}; position: relative; z-index: 2; - bottom: -1px; - - @media (${breakpoints.md}) { - margin-left: 20px; - } + bottom: -13px; `; -const Office = styled.div` +const Business = styled.div` margin-left: 44px; + cursor: pointer; + box-shadow: ${(props) => (props.isActive === 'business' ? '0 4px 0 0 #6AB9F2' : 'none')}; position: relative; z-index: 2; - bottom: -1px; - - &:hover > img { - visibility: visible; - } - - @media (${breakpoints.md}) { - margin-left: 20px; - } -`; - -const HoverImage = styled.img` - visibility: hidden; - position: relative; - top: -70px; - left: 50%; - transform: translateX(-50%); - width: 174px; - height: 34px; - flex-shrink: 0; - z-index: 3; + bottom: -13px; `; const Bar = styled.div` background: white; - width: 1300px; + width: 1200px; height: 3px; position: absolute; - bottom: 45px; - z-index: 1; /* Ensure it is below Student and Office */ - - @media (${breakpoints.md}) { - position: relative; - bottom: -20px; - margin-top: 10px; - } + bottom: 8px; `; From c9ba0faf4f5ea1adcb9c023cd76c9fa0f31c3aa1 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:10:22 +0900 Subject: [PATCH 15/18] =?UTF-8?q?design:=20=ED=99=88=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20layout=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 5f7e898..528b2fd 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -1,7 +1,7 @@ import styled from '@emotion/styled'; import { Outlet } from 'react-router-dom'; import { Footer } from './Footer'; -import { MainHeader } from './MainHeader'; +import { HEADER_HEIGHT, MainHeader } from './MainHeader'; import { UpperImage } from './UpperImage'; export const Layout = () => { @@ -28,7 +28,7 @@ const Wrapper = styled.div` const UpperImageWrapper = styled.div` width: 100%; - height: 93vh; /* 필요에 따라 조정 */ + height: calc(100vh - ${HEADER_HEIGHT}); `; const HeaderWrapper = styled.div` From 1ec0822cb9996f8173516dad358eeb83add1c3ea Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:10:54 +0900 Subject: [PATCH 16/18] =?UTF-8?q?feat:=20mail=EC=9D=98=20header=20props=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Mail/index.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pages/Mail/index.tsx b/src/pages/Mail/index.tsx index c5823a4..490ef3b 100644 --- a/src/pages/Mail/index.tsx +++ b/src/pages/Mail/index.tsx @@ -16,6 +16,10 @@ export const MailPage = () => { } const { mailInput } = mailContext; + const openModal = () => { + setIsModalOpen(true); + }; + const closeModal = () => { setIsModalOpen(false); }; @@ -42,12 +46,17 @@ export const MailPage = () => { justifyContent="center" position="relative" > -
+
- + Date: Tue, 6 Aug 2024 01:12:18 +0900 Subject: [PATCH 17/18] =?UTF-8?q?feat:=20=ED=99=88=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=B2=B4=ED=97=98=ED=95=98=EA=B8=B0=20=EC=A7=81?= =?UTF-8?q?=EC=9E=A5=EC=9D=B8=20=EB=B2=84=EC=A0=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/HomePage/TestersBox/index.tsx | 59 ++++++++++++++------ 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/components/HomePage/TestersBox/index.tsx b/src/components/HomePage/TestersBox/index.tsx index 95e30ee..3a2beff 100644 --- a/src/components/HomePage/TestersBox/index.tsx +++ b/src/components/HomePage/TestersBox/index.tsx @@ -2,15 +2,19 @@ import { Img } from '@chakra-ui/react'; import styled from '@emotion/styled'; import { Grid, GridItem } from '@chakra-ui/react'; import { useState } from 'react'; -import { mockData } from '@/types/mock'; + import { AskList } from './AskList'; import { Header } from './Header'; import { Buttons } from './Buttons'; import { breakpoints } from '@/styles/variants'; import { useMail } from '@/Provider/MailContext'; +import { mockDataUniv } from '@/types/mock/mockUniv'; +import { mockDataBusiness } from '@/types/mock/mockBusiness'; +import { MailInput } from '@/types'; +import { useEffect } from 'react'; export const TestersBox = () => { - const [randomInput, setRandomInput] = useState({ + const [randomInput, setRandomInput] = useState({ sender: '홍길동', content: '질문', department: '컴퓨터공학과', @@ -20,11 +24,24 @@ export const TestersBox = () => { }); const { isActive, onIsActive } = useMail(); - const handleList = () => { - const randomIndex = Math.floor(Math.random() * mockData.length); - setRandomInput(mockData[randomIndex]); + const handleListUniv = () => { + const randomIndex = Math.floor(Math.random() * mockDataUniv.length); + setRandomInput(mockDataUniv[randomIndex]); + }; + + const handleListBusiness = () => { + const randomIndex = Math.floor(Math.random() * mockDataBusiness.length); + setRandomInput(mockDataBusiness[randomIndex]); }; + useEffect(() => { + if (isActive === 'univ') { + handleListUniv(); + } else { + handleListBusiness(); + } + }, [isActive]); + return ( @@ -33,13 +50,20 @@ export const TestersBox = () => { - +
- + { templateColumns={{ base: 'repeat(1, 1fr)', md: 'repeat(3, 1fr)' }} gap={{ base: '20px', md: '0' }} > - + { justifyContent={{ base: 'center', md: 'space-between' }} alignItems={{ base: 'center', md: 'flex-end' }} flexDirection={{ base: 'column', md: 'column' }} - marginRight={{ base: '0', md: '56px' }} - marginBottom={{ base: '0', md: '25px' }} - backgroundImage={'/images/exampleImage2.svg'} - backgroundSize="cover" - backgroundPosition="center" - maxWidth={400} + position={'relative'} + width={'fit-content'} > - + + @@ -98,3 +123,5 @@ const MedeaItems = styled(Grid)` display: none; } `; + +const ImageWrapper = styled.img``; From d575e6cffe72f299db9427b0d04adfa0c3486655 Mon Sep 17 00:00:00 2001 From: seung365 Date: Tue, 6 Aug 2024 01:12:33 +0900 Subject: [PATCH 18/18] =?UTF-8?q?feat:=20mailmodal=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Mail/MailModal.tsx | 169 ++++++++++++++++++++++-------- src/types/mock.ts | 84 --------------- 2 files changed, 124 insertions(+), 129 deletions(-) delete mode 100644 src/types/mock.ts diff --git a/src/components/Mail/MailModal.tsx b/src/components/Mail/MailModal.tsx index a554876..4e08391 100644 --- a/src/components/Mail/MailModal.tsx +++ b/src/components/Mail/MailModal.tsx @@ -13,16 +13,54 @@ import { Spinner, } from '@chakra-ui/react'; import styled from '@emotion/styled'; -import { mailSend } from '@/types'; +import { mailSendUniv, mailSendBusiness } from '@/types'; import { usePostUniv } from '@/api/hooks/usePostUniv'; import { useForm, Controller } from 'react-hook-form'; +import { usePostBusiness } from '@/api/hooks/usePostBusiness'; interface MailModalProps { isOpen: boolean; onClose: () => void; } -const mailLetterInitialState: mailSend = { +const mailLetterInitialStateBusiness: mailSendBusiness = { + content: '', + sender: '', + company: '', + department: '', + additional: '', + receiver: '', +}; + +const currentInputNamesBusiness: (keyof mailSendBusiness)[] = [ + 'content', + 'sender', + 'company', + 'department', + 'additional', + 'receiver', +]; + +const placeholderTextsBusiness = [ + '글자 수 제한: 5자 이상~300자 이하', + '홍길동', + '알파코', + '인사팀', + '추가 기재사항', + '김알파', +]; + +const modalHeaderContentBusiness = [ + '메일 작성 목적을 선택해 주세요', + '보내는 사람의 이름을 입력해 주세요', + '소속 회사명을 입력해 주세요', + '소속 부서를 입력해 주세요', + '추가 기재사항을 입력해 주세요', + '받는 사람의 이름을 입력해 주세요', + '메일을 생성 중 입니다', +]; + +const mailLetterInitialState: mailSendUniv = { content: '', sender: '', department: '', @@ -41,7 +79,7 @@ const modalHeaderContent = [ '메일을 생성 중 입니다', ]; -const inputNames: (keyof mailSend)[] = [ +const currentInputNames: (keyof mailSendUniv)[] = [ 'content', 'sender', 'department', @@ -67,11 +105,15 @@ const options = [ { label: '📝 상담 요청', value: '상담 요청' }, ]; -const warningTexts = { +const warningTextsUniv = { content: ['메일 작성 목적을 선택하거나 입력해주세요', '5자 이상~300자 이하로 입력해주세요'], studentId: '숫자만 입력 가능해요', }; +const warningTextsBusiness = { + content: ['메일 작성 목적을 입력해주세요', '5자 이상~300자 이하로 입력해주세요'], +}; + interface OptionButtonProps extends React.ButtonHTMLAttributes { selected?: boolean; // selected prop 추가 } @@ -86,43 +128,70 @@ export const MailModal = ({ isOpen, onClose }: MailModalProps) => { const [isFocused, setIsFocused] = useState(false); const [isHide, setIsHide] = useState(false); const [firstInput, setFirstInput] = useState(''); + const { isActive } = useMail(); + + const currentcurrentInputNames = + isActive === 'univ' ? currentInputNames : currentInputNamesBusiness; + const currentPlaceholderTexts = isActive === 'univ' ? placeholderTexts : placeholderTextsBusiness; + const currentModalHeaderContent = + isActive === 'univ' ? modalHeaderContent : modalHeaderContentBusiness; const handleOptionClick = (value: string) => { setFirstInput(value); }; - const { mutate } = usePostUniv(); + const { univMutate } = usePostUniv(); + const { businessMutate } = usePostBusiness(); + const { control, handleSubmit, setValue, trigger, - formState: { errors, isValid }, - } = useForm({ + formState: { isValid }, + } = useForm({ mode: 'onChange', - defaultValues: { - ...mailLetterInitialState, - }, + defaultValues: isActive === 'univ' ? mailLetterInitialState : mailLetterInitialStateBusiness, }); - const onSubmit = (data: mailSend) => { + const setMailInputUniv = (data: mailSendUniv) => { + setIsLoading(true); + handleMail(data); + setIsHide(true); + + univMutate( + { ...(data as unknown as mailSendUniv) }, + { + onSuccess: (data) => { + console.log(data); + setTitle(data.title || '메일 생성 성공'); + setContent(data.content || '메일이 성공적으로 생성되었습니다.'); + }, + onError: (error) => { + setTitle('메일 생성 실패'); + setContent('메일 생성 중 오류가 발생했습니다.'); + }, + }, + ); + setIsHide(!isHide); + }; + + const setMailInputBusiness = (data: mailSendBusiness) => { setIsLoading(true); handleMail(data); setIsHide(true); - mutate( - { ...data }, + + businessMutate( + { ...(data as unknown as mailSendBusiness) }, { - onSuccess: (response) => { - setTitle(response.title || '메일 생성 성공'); - setContent(response.content || '메일이 성공적으로 생성되었습니다.'); - setIsSubmitted(true); - setIsLoading(false); + onSuccess: (data) => { + console.log(data); + setTitle(data.title || '메일 생성 성공'); + setContent(data.content || '메일이 성공적으로 생성되었습니다.'); }, onError: (error) => { setTitle('메일 생성 실패'); setContent('메일 생성 중 오류가 발생했습니다.'); - setIsSubmitted(true); - setIsLoading(false); }, }, ); @@ -130,14 +199,14 @@ export const MailModal = ({ isOpen, onClose }: MailModalProps) => { }; const handleNextClick = async (inputValue: string) => { - const isValid = await trigger(inputNames[currentIndex]); + const isValid = await trigger(currentcurrentInputNames[currentIndex]); if (currentIndex === 0 && firstInput && !inputValue) { - setValue(inputNames[currentIndex], firstInput, { shouldValidate: true }); + setValue(currentcurrentInputNames[currentIndex], firstInput, { shouldValidate: true }); } if (isValid) { - if (currentIndex < inputNames.length - 1) { + if (currentIndex < currentInputNames.length - 1) { setCurrentIndex(currentIndex + 1); setIsFocused(false); } @@ -157,9 +226,9 @@ export const MailModal = ({ isOpen, onClose }: MailModalProps) => { if (currentIndex === 0 && firstInput) { event.preventDefault(); const combinedValue = `${firstInput} : ${inputValue}`.trim(); - await setValue(inputNames[currentIndex], combinedValue, { shouldValidate: true }); + await setValue(currentInputNames[currentIndex], combinedValue, { shouldValidate: true }); } else { - await setValue(inputNames[currentIndex], inputValue, { shouldValidate: true }); + await setValue(currentInputNames[currentIndex], inputValue, { shouldValidate: true }); } await handleNextClick(inputValue); return; @@ -168,9 +237,11 @@ export const MailModal = ({ isOpen, onClose }: MailModalProps) => { useEffect(() => { setIsFocused(false); - setValue(inputNames[currentIndex], '', { shouldValidate: true }); + setValue(currentInputNames[currentIndex], '', { shouldValidate: true }); }, [currentIndex, setValue]); + const currentWarningTexts = isActive === 'univ' ? warningTextsUniv : warningTextsBusiness; + return ( { ? title : isLoading ? '메일 생성 중 입니다...' - : modalHeaderContent[currentIndex]} + : currentModalHeaderContent[currentIndex]} {isSubmitted ? ( @@ -206,7 +277,7 @@ export const MailModal = ({ isOpen, onClose }: MailModalProps) => { ) : ( <> - {currentIndex === 0 && ( + {currentIndex === 0 && isActive === 'univ' && ( {options.map((option) => ( { )} { if (currentIndex === 0) { if (!value && !firstInput) { - return warningTexts.content[0]; + return currentWarningTexts.content[0]; } if (value.length < 5 || value.length > 300) { - return warningTexts.content[1]; + return currentWarningTexts.content[1]; } } - if (currentIndex === 3 && (!/^\d+$/.test(value) || '')) { - return warningTexts.studentId; + if (currentIndex === 3) { + if (isActive === 'univ' && (!/^\d+$/.test(value) || '')) { + return (currentWarningTexts as typeof warningTextsUniv).studentId; + } + if (isActive === 'business' && value.length < 5) { + return currentWarningTexts.content[1]; + } } + return true; }, }} @@ -244,20 +321,17 @@ export const MailModal = ({ isOpen, onClose }: MailModalProps) => { <> setIsFocused(true)} onBlur={() => setIsFocused(false)} onChange={(e) => { field.onChange(e); - setValue(inputNames[currentIndex], e.target.value, { + setValue(currentInputNames[currentIndex], e.target.value, { shouldValidate: true, }); }} onKeyDown={handleKeyDown} /> - {errors[inputNames[currentIndex]] && ( - {errors[inputNames[currentIndex]]?.message} - )} )} /> @@ -268,10 +342,15 @@ export const MailModal = ({ isOpen, onClose }: MailModalProps) => { {!isHide && ( - {currentIndex < inputNames.length - 1 ? ( + {currentIndex < currentInputNames.length - 1 ? ( handleNextClick('')} /> ) : ( - + + isActive === 'univ' ? setMailInputUniv : setMailInputBusiness, + )} + disabled={!isValid} + > 생성하기 @@ -412,11 +491,11 @@ const StyledInput = styled(Input)` text-align: center; `; -const WarningText = styled(Text)` - color: red; - font-size: 15px; - margin-top: 10px; -`; +// const WarningText = styled(Text)` +// color: red; +// font-size: 15px; +// margin-top: 10px; +// `; const ArrowButton = styled(Button)` background: none; diff --git a/src/types/mock.ts b/src/types/mock.ts deleted file mode 100644 index 8cf3bb4..0000000 --- a/src/types/mock.ts +++ /dev/null @@ -1,84 +0,0 @@ -export const mockData = [ - { - subject: '자료구조', - department: '컴퓨터공학과', - studentId: '2020123456', - content: '질문', - sender: '홍길동', - receiver: '안지선', - }, - { - subject: '회로이론', - department: '전자공학과', - studentId: '2020234567', - content: '과제 제출', - sender: '이영희', - receiver: '김서현', - }, - { - subject: '열역학', - department: '기계공학과', - studentId: '2020345678', - content: '성적 정정', - sender: '박준영', - receiver: '최은지', - }, - { - subject: '운영관리', - department: '산업공학과', - studentId: '2020456789', - content: '병결 요청', - sender: '정수현', - receiver: '강민호', - }, - { - subject: '화학반응공학', - department: '화학공학과', - studentId: '2020567890', - content: '상담 요청', - sender: '최지우', - receiver: '홍길동', - }, - { - subject: '건축설계', - department: '건축학과', - studentId: '2020678901', - content: '질문', - sender: '김도윤', - receiver: '이수민', - }, - { - subject: '구조역학', - department: '토목공학과', - studentId: '2020789012', - content: '과제 제출', - sender: '한지민', - receiver: '박현우', - }, - { - subject: '알고리즘', - department: '컴퓨터공학과', - studentId: '2020890123', - content: '성적 정정', - sender: '윤재현', - receiver: '정다은', - }, - { - subject: '전자기학', - department: '전자공학과', - studentId: '2020901234', - content: '병결 요청', - sender: '서지훈', - receiver: '김나윤', - }, - { - subject: '기계진동', - department: '기계공학과', - studentId: '2021012345', - content: '상담 요청', - sender: '장예은', - receiver: '오준석', - }, -]; - -export default mockData;