diff --git a/package.json b/package.json index 8314c506..c0a79a13 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@hello-pangea/dnd": "^18.0.1", "@hookform/resolvers": "^4.1.3", "@tanstack/react-query": "^5.61.3", - "@tanstack/react-query-devtools": "^5.75.7", + "@tanstack/react-query-devtools": "^5.76.1", "autoprefixer": "^10.4.20", "axios": "^1.8.1", "date-fns": "^4.1.0", diff --git a/src/app/routes/Router.tsx b/src/app/routes/Router.tsx index 88df03e5..838b30d3 100644 --- a/src/app/routes/Router.tsx +++ b/src/app/routes/Router.tsx @@ -4,7 +4,7 @@ import Layout from '../Layout'; import AgreementPage from '../../pages/join/AgreementPage'; import InfoInputPage from '../../pages/join/InfoInputPage'; import MainPage from '../../pages/home/ui/MainPage'; -import FunnelPage from '../../pages/event-manage/ui/FunnelPage'; +import FunnelPage from '../../pages/event/ui/create-event/FunnelPage'; import AllEventsPage from '../../pages/event/ui/AllEventsPage'; import MyTicketPage from '../../pages/menu/ui/MyTicketPage'; import SearchPage from '../../pages/search/ui/SearchPage'; @@ -97,4 +97,4 @@ const router = createBrowserRouter( })) ); -export default router; \ No newline at end of file +export default router; diff --git a/src/entities/event/api/event.ts b/src/entities/event/api/eventDetail.ts similarity index 81% rename from src/entities/event/api/event.ts rename to src/entities/event/api/eventDetail.ts index fadee027..2ee13340 100644 --- a/src/entities/event/api/event.ts +++ b/src/entities/event/api/eventDetail.ts @@ -1,8 +1,8 @@ import { axiosClient } from '../../../shared/types/api/http-client'; -import { EventDetailRequest } from '../model/event'; +import { EventDetailRequest } from '../model/eventDetail'; import { CategoryType, TagType } from '../../../shared/types/baseEventType'; import { ApiResponse } from '../../../shared/types/api/apiResponse'; -import { EventItem, PaginationParams } from '../model/event'; +import { EventItem, PaginationParams } from '../model/eventDetail'; export const eventDetail = async (dto: EventDetailRequest) => { const response = await axiosClient.get(`/events/${dto.eventId}`, { @@ -11,22 +11,6 @@ export const eventDetail = async (dto: EventDetailRequest) => { return response.data; }; -// 이벤트 검색 (기본 정보) -export const searchEvents = async ( - keyword: string, - { page, size }: PaginationParams -): Promise> => { - const params = new URLSearchParams(); - - params.append('keyword', keyword); - params.append('page', page.toString()); - params.append('size', size.toString()); - - const response = await axiosClient.get>(`/events/search?${params.toString()}`); - - return response.data; -}; - // 전체 이벤트 목록 조회 (무한 스크롤) export const getAllEventsInfinite = async ({ page, diff --git a/src/entities/event/hook/useEventHook.ts b/src/entities/event/hook/useEventHook.ts index 7ab82739..93624910 100644 --- a/src/entities/event/hook/useEventHook.ts +++ b/src/entities/event/hook/useEventHook.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { eventDetail } from '../api/event'; +import { eventDetail } from '../api/eventDetail'; import { useParams } from 'react-router-dom'; import { useUserInfo } from '../../../features/join/hooks/useUserHook'; diff --git a/src/entities/event/hook/useEventListHook.ts b/src/entities/event/hook/useEventListHook.ts index c2a6ae7c..294a6c6c 100644 --- a/src/entities/event/hook/useEventListHook.ts +++ b/src/entities/event/hook/useEventListHook.ts @@ -1,6 +1,6 @@ -import { EventList } from '../../../features/event-manage/event-list/model/eventList'; +import { EventList } from '../../../features/event/event-list/model/eventList'; import { useInfiniteScroll } from '../../../shared/hooks/useInfiniteScroll'; -import { getAllEventsInfinite } from '../api/event'; +import { getAllEventsInfinite } from '../api/eventDetail'; const useEventList = () => { const { data, fetchNextPage, hasNextPage, isFetching } = useInfiniteScroll({ diff --git a/src/entities/event/model/event.ts b/src/entities/event/model/eventDetail.ts similarity index 100% rename from src/entities/event/model/event.ts rename to src/entities/event/model/eventDetail.ts diff --git a/src/features/bookmark/hook/useBookmarkHook.ts b/src/features/bookmark/hook/useBookmarkHook.ts new file mode 100644 index 00000000..43d89756 --- /dev/null +++ b/src/features/bookmark/hook/useBookmarkHook.ts @@ -0,0 +1,80 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { BookmarkResponse } from '../model/bookmarkInformation'; +import { createBookmark, deleteBookmark, readBookmark } from '../api/bookmark'; +import { EventDetailResponse } from '../../../entities/event/model/eventDetail'; + +export const useBookmarks = () => { + return useQuery({ + queryKey: ['bookmarks'], + queryFn: readBookmark, + }); +}; + +export const useCreateBookmark = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: createBookmark, + // Optimistic + onMutate: async (eventId: number) => { + await queryClient.cancelQueries({ queryKey: ['eventDetail', eventId] }); + const previous = queryClient.getQueryData(['eventDetail', eventId]); + + queryClient.setQueryData(['eventDetail', eventId], old => + old + ? { + ...old, + result: { + ...old.result, + bookmarked: true, + }, + } + : old + ); + + return { previous }; + }, + onError: (_err, eventId, context) => { + if (context?.previous) { + queryClient.setQueryData(['eventDetail', eventId], context.previous); + alert('좋아요 등록에 실패했습니다. 잠시후 다시 시도해 주세요.'); + } + }, + onSettled: (_data, _error, eventId) => { + queryClient.invalidateQueries({ queryKey: ['eventDetail', eventId] }); + }, + }); +}; +export const useDeleteBookmark = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (params: { eventId: number; bookmarkId: number }) => deleteBookmark(params.eventId, params.bookmarkId), + // Optimistic + onMutate: async ({ eventId }) => { + await queryClient.cancelQueries({ queryKey: ['eventDetail', eventId] }); + const previous = queryClient.getQueryData(['eventDetail', eventId]); + + queryClient.setQueryData(['eventDetail', eventId], old => + old + ? { + ...old, + result: { + ...old.result, + bookmarked: false, + }, + } + : old + ); + + return { previous }; + }, + onError: (_err, { eventId }, context) => { + if (context?.previous) { + queryClient.setQueryData(['eventDetail', eventId], context.previous); + alert('좋아요 삭제에 실패했습니다. 잠시후 다시 시도해 주세요.'); + } + }, + onSettled: (_data, _error, { eventId }) => { + queryClient.invalidateQueries({ queryKey: ['eventDetail', eventId] }); + }, + }); +}; diff --git a/src/features/bookmark/model/useBookmarkHook.ts b/src/features/bookmark/model/useBookmarkHook.ts deleted file mode 100644 index 54def98d..00000000 --- a/src/features/bookmark/model/useBookmarkHook.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" -import { BookmarkResponse } from "./bookmarkInformation" -import { createBookmark, deleteBookmark, readBookmark } from "../api/bookmark" - -export const useBookmarks = () => { - return useQuery({ - queryKey: ['bookmarks'], - queryFn: readBookmark, - }) -} - -export const useCreateBookmark = () => { - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: createBookmark, - // Optimistic - onMutate: async (eventId: number) => { - await queryClient.cancelQueries({ queryKey: ['eventDetail', eventId] }); - const previous = queryClient.getQueryData(['eventDetail', eventId]); - - queryClient.setQueryData(['eventDetail', eventId], (old: any) => ({ - ...old, - bookmarked: true, - })); - - return { previous }; - }, - onError: (_err, eventId, context) => { - if (context?.previous) { - queryClient.setQueryData(['eventDetail', eventId], context.previous); - alert("좋아요 등록에 실패했습니다. 잠시후 다시 시도해 주세요."); - } - }, - onSettled: (_data, _error, eventId) => { - queryClient.invalidateQueries({ queryKey: ['eventDetail', eventId] }); - }, - }) -} -export const useDeleteBookmark = () => { - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: (params: { eventId: number; bookmarkId: number }) => - deleteBookmark(params.eventId, params.bookmarkId), - // Optimistic - onMutate: async ({ eventId }) => { - await queryClient.cancelQueries({ queryKey: ['eventDetail', eventId] }); - const previous = queryClient.getQueryData(['eventDetail', eventId]); - - queryClient.setQueryData(['eventDetail', eventId], (old: any) => ({ - ...old, - bookmarked: false, - })); - - return { previous }; - }, - onError: (_err, { eventId }, context) => { - if (context?.previous) { - queryClient.setQueryData(['eventDetail', eventId], context.previous); - alert("좋아요 삭제에 실패했습니다. 잠시후 다시 시도해 주세요."); - } - }, - onSettled: (_data, _error, { eventId }) => { - queryClient.invalidateQueries({ queryKey: ['eventDetail', eventId] }); - }, - }); -} \ No newline at end of file diff --git a/src/features/dashboard/api/event.ts b/src/features/dashboard/api/event.ts index 9e56f132..615fb5f4 100644 --- a/src/features/dashboard/api/event.ts +++ b/src/features/dashboard/api/event.ts @@ -1,15 +1,6 @@ import { axiosClient } from '../../../shared/types/api/http-client'; import { UpdateEventRequest } from '../model/event'; -export const getHostDashboard = async (eventId: number) => { - const response = await axiosClient.get('/host-channels/dashboard', { - params: { - eventId: eventId, - }, - }); - return response.data.result; -}; - export const updateEventInfo = async (eventId: number, dto: Partial) => { const response = await axiosClient.put(`/events/${eventId}`, dto); return response.data; diff --git a/src/features/dashboard/api/hostDashboard.ts b/src/features/dashboard/api/hostDashboard.ts new file mode 100644 index 00000000..b319d427 --- /dev/null +++ b/src/features/dashboard/api/hostDashboard.ts @@ -0,0 +1,10 @@ +import { axiosClient } from '../../../shared/types/api/http-client'; + +export const getHostDashboard = async (eventId: number) => { + const response = await axiosClient.get('/host-channels/dashboard', { + params: { + eventId: eventId, + }, + }); + return response.data.result; +}; diff --git a/src/features/dashboard/api/mail.ts b/src/features/dashboard/api/mail.ts index ff0e41f1..5398f176 100644 --- a/src/features/dashboard/api/mail.ts +++ b/src/features/dashboard/api/mail.ts @@ -1,44 +1,39 @@ import { axiosClient } from '../../../shared/types/api/http-client'; -import { EmailRequest, ReadEmailResponse } from '../model/emailInformation'; +import { EmailRequest, ReadEmailResponse } from '../model/email'; // 예약 메일 조회 export const readEmail = async (eventId: number, status: 'PENDING' | 'SENT'): Promise => { - const response = await axiosClient.get<{ result: ReadEmailResponse[] }>( - `/reservation-emails`, - { - params: { - eventId, - status, - }, - } - ); - return response.data.result; -} + const response = await axiosClient.get<{ result: ReadEmailResponse[] }>(`/reservation-emails`, { + params: { + eventId, + status, + }, + }); + return response.data.result; +}; // 전체/티켓별 구매자 이메일 조회 -export const readPurchaserEmails = async (eventId: number, ticketId?: number): Promise<{email: string[]}> => { - const response = await axiosClient.get('/orders/purchaser-emails', - { - params: { - eventId, - ...(ticketId !== undefined && { ticketId }), - }, - } - ); - return response.data.result; +export const readPurchaserEmails = async (eventId: number, ticketId?: number): Promise<{ email: string[] }> => { + const response = await axiosClient.get('/orders/purchaser-emails', { + params: { + eventId, + ...(ticketId !== undefined && { ticketId }), + }, + }); + return response.data.result; }; export const sendEmail = async (data: EmailRequest) => { - const response = await axiosClient.post('/reservation-emails', data); - return response.data.result; + const response = await axiosClient.post('/reservation-emails', data); + return response.data.result; }; export const editEmail = async (reservationEmailId: number, data: EmailRequest) => { - const response = await axiosClient.put(`/reservation-emails/${reservationEmailId}`, data); - return response.data.result; + const response = await axiosClient.put(`/reservation-emails/${reservationEmailId}`, data); + return response.data.result; }; export const deleteEmail = async (reservationEmailId: number) => { - const response = await axiosClient.delete(`/reservation-emails/${reservationEmailId}`); - return response.data.result; -} \ No newline at end of file + const response = await axiosClient.delete(`/reservation-emails/${reservationEmailId}`); + return response.data.result; +}; diff --git a/src/features/dashboard/hook/useEmailHook.ts b/src/features/dashboard/hook/useEmailHook.ts index 6475e2df..f8d807ba 100644 --- a/src/features/dashboard/hook/useEmailHook.ts +++ b/src/features/dashboard/hook/useEmailHook.ts @@ -1,71 +1,71 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { sendEmail, editEmail, readEmail, deleteEmail, readPurchaserEmails } from '../api/mail'; -import { EmailRequest, EmailResponse, ReadEmailResponse } from '../model/emailInformation'; +import { EmailRequest, EmailResponse, ReadEmailResponse } from '../model/email'; import { useNavigate, useParams } from 'react-router-dom'; -import { useEmailStore } from '../model/EmailStore'; +import { useEmailStore } from '../model/store/EmailStore'; export const useReadEmail = (eventId: number, status: 'PENDING' | 'SENT') => { - return useQuery({ - queryKey: ['emails', eventId, status], - queryFn: () => readEmail(eventId, status), - enabled: !!eventId && !!status, - }); -} + return useQuery({ + queryKey: ['emails', eventId, status], + queryFn: () => readEmail(eventId, status), + enabled: !!eventId && !!status, + }); +}; export const usePurchaserEmails = () => { - return useMutation({ - mutationFn: ({ eventId, ticketId }: { eventId: number; ticketId?: number }) => - readPurchaserEmails(eventId, ticketId), - onError: () => { - alert('이메일을 불러오는 데 실패했습니다.'); - }, - }); - }; - + return useMutation({ + mutationFn: ({ eventId, ticketId }: { eventId: number; ticketId?: number }) => + readPurchaserEmails(eventId, ticketId), + onError: () => { + alert('이메일을 불러오는 데 실패했습니다.'); + }, + }); +}; + export const useSendEmail = () => { - const { id } = useParams(); - const navigate = useNavigate(); - const { reset } = useEmailStore(); - return useMutation({ - mutationFn: sendEmail, - onSuccess: () => { - reset(); - alert("예약 메일이 성공적으로 발송되었습니다!"); - navigate(`/dashboard/${id}/mailBox`); - }, - onError: () => { - alert("메일 전송에 실패했습니다. 다시 시도해 주세요."); - }, - }); + const { id } = useParams(); + const navigate = useNavigate(); + const { reset } = useEmailStore(); + return useMutation({ + mutationFn: sendEmail, + onSuccess: () => { + reset(); + alert('예약 메일이 성공적으로 발송되었습니다!'); + navigate(`/dashboard/${id}/mailBox`); + }, + onError: () => { + alert('메일 전송에 실패했습니다. 다시 시도해 주세요.'); + }, + }); }; export const useEditEmail = () => { - const { id } = useParams(); - const navigate = useNavigate(); - const { reset } = useEmailStore(); - return useMutation({ - mutationFn: ({ reservationEmailId, data }) => editEmail(reservationEmailId, data), - onSuccess: () => { - reset(); - alert("예약 메일이 성공적으로 수정되었습니다!"); - navigate(`/dashboard/${id}/mailBox`); - }, - onError: () => { - alert("메일 수정에 실패했습니다. 다시 시도해 주세요."); - }, - }); + const { id } = useParams(); + const navigate = useNavigate(); + const { reset } = useEmailStore(); + return useMutation({ + mutationFn: ({ reservationEmailId, data }) => editEmail(reservationEmailId, data), + onSuccess: () => { + reset(); + alert('예약 메일이 성공적으로 수정되었습니다!'); + navigate(`/dashboard/${id}/mailBox`); + }, + onError: () => { + alert('메일 수정에 실패했습니다. 다시 시도해 주세요.'); + }, + }); }; export const useDeleteEmail = () => { - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: (reservationEmailId) => deleteEmail(reservationEmailId), - onSuccess: () => { - alert("메일이 삭제되었습니다."); - queryClient.invalidateQueries({ queryKey: ['emails'] }); - }, - onError: () => { - alert("메일 삭제에 실패했습니다. 다시 시도해 주세요."); - } - }); -} + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: reservationEmailId => deleteEmail(reservationEmailId), + onSuccess: () => { + alert('메일이 삭제되었습니다.'); + queryClient.invalidateQueries({ queryKey: ['emails'] }); + }, + onError: () => { + alert('메일 삭제에 실패했습니다. 다시 시도해 주세요.'); + }, + }); +}; diff --git a/src/features/dashboard/hook/useEventHook.ts b/src/features/dashboard/hook/useEventHook.ts index 4833dafb..31bfd409 100644 --- a/src/features/dashboard/hook/useEventHook.ts +++ b/src/features/dashboard/hook/useEventHook.ts @@ -1,22 +1,7 @@ -import { useMutation, useQuery } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import { useParams } from 'react-router-dom'; -import { getHostDashboard, updateEventInfo } from '../api/event'; -import { dashboardData } from '../../../shared/types/dashboardType'; import { UpdateEventRequest } from '../model/event'; - -export const useGetEventHook = () => { - const { id } = useParams(); - - const eventId = Number(id); - - const { data: eventInfo } = useQuery({ - queryKey: ['eventInfo', eventId], - queryFn: () => getHostDashboard(eventId), - }); - - return { eventInfo }; -}; - +import { updateEventInfo } from '../api/event'; export const useUpdateEventHook = () => { const { id } = useParams(); const eventId = Number(id); diff --git a/src/features/dashboard/hook/useHostDashboardHook.ts b/src/features/dashboard/hook/useHostDashboardHook.ts new file mode 100644 index 00000000..d78cff74 --- /dev/null +++ b/src/features/dashboard/hook/useHostDashboardHook.ts @@ -0,0 +1,17 @@ +import { useQuery } from '@tanstack/react-query'; +import { useParams } from 'react-router-dom'; +import { HostDashboardResponse } from '../../../entities/host/model/hostDashboard'; +import { getHostDashboard } from '../api/hostDashboard'; + +export const useGetEventHook = () => { + const { id } = useParams(); + + const eventId = Number(id); + + const { data: eventInfo } = useQuery({ + queryKey: ['eventInfo', eventId], + queryFn: () => getHostDashboard(eventId), + }); + + return { eventInfo }; +}; diff --git a/src/features/dashboard/hook/useParticipants.ts b/src/features/dashboard/hook/useParticipants.ts index d4fd62fa..42560948 100644 --- a/src/features/dashboard/hook/useParticipants.ts +++ b/src/features/dashboard/hook/useParticipants.ts @@ -4,7 +4,7 @@ import { useParams } from 'react-router-dom'; import { ApiResponse } from '../../../shared/types/api/apiResponse'; import { AxiosError } from 'axios'; import { approveParticipants } from '../../../features/dashboard/api/participants'; -import { useParticipantStore } from '../model/ParticipantStore'; +import { useParticipantStore } from '../model/store/ParticipantStore'; export const useParticipants = (tags = 'all', page = 0, size = 10) => { const { id } = useParams(); diff --git a/src/features/dashboard/model/ResponseStore.tsx b/src/features/dashboard/model/ResponseStore.tsx deleted file mode 100644 index 7a39cbc8..00000000 --- a/src/features/dashboard/model/ResponseStore.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { create } from 'zustand'; -import { responsesData } from '../../../shared/types/responseType'; - -interface ResponseState { - response: responsesData[]; - selectedField: string; - selectedResponse: responsesData[]; - currentIndex: number; - - setResponses: (responses: responsesData[]) => void; - setSelectedField: (field: string) => void; - setSelectedResponse: (responseName: string, responseEmail: string) => void; - setCurrentIndex: (updateFn: (prevIndex: number) => number) => void; -} - -export const useResponseStore = create((set) => ({ - response: [], - selectedField: '', - selectedResponse: [], - currentIndex: 0, - - setResponses: (response) => { - set(() => ({ - response: response, - selectedField: response.length > 0 ? Object.keys(response[0])[1] : '' - })); - }, - - setSelectedField: (field) => { - set({ selectedField: field }); - }, - - setSelectedResponse: (responseName, responseEmail) => { - set((state) => { - const filteredResponses = state.response.filter((res) => res.name === responseName && res.email === responseEmail); - return { - selectedResponse: filteredResponses, - currentIndex: 0, - }; - }); - }, - - setCurrentIndex: (updateFn) => set((state) => ({ - currentIndex: updateFn(state.currentIndex), - })), - -})); diff --git a/src/features/dashboard/model/emailInformation.ts b/src/features/dashboard/model/email.ts similarity index 100% rename from src/features/dashboard/model/emailInformation.ts rename to src/features/dashboard/model/email.ts diff --git a/src/features/dashboard/model/participantInformation.ts b/src/features/dashboard/model/participantInformation.ts deleted file mode 100644 index 4382e995..00000000 --- a/src/features/dashboard/model/participantInformation.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface ParticipantData { - id: number; - orderNumber: number; - participant: string; - email: string; - phoneNumber: string; - purchaseDate: string; - ticketName: string; - orderStatus: string; - checkedIn: boolean; -} \ No newline at end of file diff --git a/src/features/dashboard/model/EmailStore.tsx b/src/features/dashboard/model/store/EmailStore.tsx similarity index 100% rename from src/features/dashboard/model/EmailStore.tsx rename to src/features/dashboard/model/store/EmailStore.tsx diff --git a/src/features/dashboard/model/ParticipantStore.tsx b/src/features/dashboard/model/store/ParticipantStore.tsx similarity index 96% rename from src/features/dashboard/model/ParticipantStore.tsx rename to src/features/dashboard/model/store/ParticipantStore.tsx index e510241b..e50cd521 100644 --- a/src/features/dashboard/model/ParticipantStore.tsx +++ b/src/features/dashboard/model/store/ParticipantStore.tsx @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import { participantsData } from '../../../shared/types/participantInfoType'; +import { participantsData } from '../../../../shared/types/participantInfoType'; interface ParicipantState { all: boolean; diff --git a/src/features/dashboard/model/store/ResponseStore.tsx b/src/features/dashboard/model/store/ResponseStore.tsx new file mode 100644 index 00000000..e07a6ac5 --- /dev/null +++ b/src/features/dashboard/model/store/ResponseStore.tsx @@ -0,0 +1,47 @@ +import { create } from 'zustand'; +import { responsesData } from '../../../../shared/types/responseType'; + +interface ResponseState { + response: responsesData[]; + selectedField: string; + selectedResponse: responsesData[]; + currentIndex: number; + + setResponses: (responses: responsesData[]) => void; + setSelectedField: (field: string) => void; + setSelectedResponse: (responseName: string, responseEmail: string) => void; + setCurrentIndex: (updateFn: (prevIndex: number) => number) => void; +} + +export const useResponseStore = create(set => ({ + response: [], + selectedField: '', + selectedResponse: [], + currentIndex: 0, + + setResponses: response => { + set(() => ({ + response: response, + selectedField: response.length > 0 ? Object.keys(response[0])[1] : '', + })); + }, + + setSelectedField: field => { + set({ selectedField: field }); + }, + + setSelectedResponse: (responseName, responseEmail) => { + set(state => { + const filteredResponses = state.response.filter(res => res.name === responseName && res.email === responseEmail); + return { + selectedResponse: filteredResponses, + currentIndex: 0, + }; + }); + }, + + setCurrentIndex: updateFn => + set(state => ({ + currentIndex: updateFn(state.currentIndex), + })), +})); diff --git a/src/features/dashboard/model/TicketOptionStore.tsx b/src/features/dashboard/model/store/TicketOptionStore.tsx similarity index 100% rename from src/features/dashboard/model/TicketOptionStore.tsx rename to src/features/dashboard/model/store/TicketOptionStore.tsx diff --git a/src/features/dashboard/ui/EmailInput.tsx b/src/features/dashboard/ui/EmailInput.tsx index c493b53e..a6857cc5 100644 --- a/src/features/dashboard/ui/EmailInput.tsx +++ b/src/features/dashboard/ui/EmailInput.tsx @@ -3,7 +3,7 @@ import TextButton from '../../../../design-system/ui/buttons/TextButton'; import DefaultTextField from '../../../../design-system/ui/textFields/DefaultTextField'; import MultilineTextField from '../../../../design-system/ui/textFields/MultilineTextField'; import EmailInputBase from '../../../shared/ui/EmailInputBase'; -import { useEmailStore } from '../model/EmailStore'; +import { useEmailStore } from '../model/store/EmailStore'; interface EmailInputProps { type?: '이메일 예약 발송' | '선택 이메일 보내기' | '이메일 내용 수정'; @@ -12,26 +12,24 @@ interface EmailInputProps { isEdited?: boolean; } -const EmailInput = ({ type = '이메일 예약 발송', openSelectTicket, allParticipantEmails, isEdited }: EmailInputProps) => { +const EmailInput = ({ + type = '이메일 예약 발송', + openSelectTicket, + allParticipantEmails, + isEdited, +}: EmailInputProps) => { const [inputValue, setInputValue] = useState(''); - const { - title, - content, - recipients, - setTitle, - setContent, - setRecipients, - } = useEmailStore(); + const { title, content, recipients, setTitle, setContent, setRecipients } = useEmailStore(); useEffect(() => { if (!isEdited) { - setRecipients([]); + setRecipients([]); setTitle(''); - setContent(''); + setContent(''); } - }, [isEdited, setRecipients]); - + }, [isEdited, setRecipients, setTitle, setContent]); + const addAllEmails = () => { setRecipients([...new Set(allParticipantEmails)]); }; @@ -61,7 +59,13 @@ const EmailInput = ({ type = '이메일 예약 발송', openSelectTicket, allPar placeholder={recipients.length === 0 ? '위 필터로 이메일 보내실 대상을 선택하세요.' : ''} /> - setTitle(e.target.value)} /> + setTitle(e.target.value)} + /> {/* 이메일 내용 작성 부분 */} setContent(e.target.value)} + onChange={e => setContent(e.target.value)} /> ); diff --git a/src/features/dashboard/ui/ParicipantCard.tsx b/src/features/dashboard/ui/ParicipantCard.tsx index 0ae140d0..f3311ac2 100644 --- a/src/features/dashboard/ui/ParicipantCard.tsx +++ b/src/features/dashboard/ui/ParicipantCard.tsx @@ -1,6 +1,6 @@ import TertiaryButton from '../../../../design-system/ui/buttons/TertiaryButton'; import Checkbox from '../../../../design-system/ui/Checkbox'; -import { useParticipantStore } from '../model/ParticipantStore'; +import { useParticipantStore } from '../model/store/ParticipantStore'; import { participantsData } from '../../../shared/types/participantInfoType'; import SecondaryButton from '../../../../design-system/ui/buttons/SecondaryButton'; import { useNavigate } from 'react-router-dom'; diff --git a/src/features/dashboard/ui/PariticipantsList.tsx b/src/features/dashboard/ui/PariticipantsList.tsx index 44715978..4a007cc3 100644 --- a/src/features/dashboard/ui/PariticipantsList.tsx +++ b/src/features/dashboard/ui/PariticipantsList.tsx @@ -1,7 +1,7 @@ import { useEffect } from 'react'; import Checkbox from '../../../../design-system/ui/Checkbox'; import ParticipantCard from './ParicipantCard'; -import { useParticipantStore } from '../model/ParticipantStore'; +import { useParticipantStore } from '../model/store/ParticipantStore'; import { participantsData } from '../../../shared/types/participantInfoType'; interface ParticipantsListProps { diff --git a/src/features/dashboard/ui/ResponsesList.tsx b/src/features/dashboard/ui/ResponsesList.tsx index 524f0394..29470529 100644 --- a/src/features/dashboard/ui/ResponsesList.tsx +++ b/src/features/dashboard/ui/ResponsesList.tsx @@ -1,4 +1,4 @@ -import { useResponseStore } from '../model/ResponseStore'; +import { useResponseStore } from '../model/store/ResponseStore'; import { responsesInfo } from '../../../shared/types/responseType'; import ResponseFilter from './ResponseFilter'; import SelectedResponseList from './SelectedResponseList'; @@ -6,107 +6,116 @@ import { createFieldMappings } from '../../../shared/lib/createFieldMappings'; import { useEffect } from 'react'; interface ResponsesListProps { - listType: 'summary' | 'query' | 'individual'; + listType: 'summary' | 'query' | 'individual'; } const ResponsesList = ({ listType }: ResponsesListProps) => { - const { response, selectedField, setSelectedField, selectedResponse, setSelectedResponse, currentIndex, setCurrentIndex } = useResponseStore(); - const { fieldMap, fieldMapToKorean } = createFieldMappings(response); - const queryOptions = response && response[0] - ? Object.keys(response[0]) - .filter(key => key !== 'id' && key !== 'selectedOptions') - .map(key => ({ - v1: fieldMap[key] || key, - v2: "" - })) - : []; + const { + response, + selectedField, + setSelectedField, + selectedResponse, + setSelectedResponse, + currentIndex, + setCurrentIndex, + } = useResponseStore(); + const { fieldMap, fieldMapToKorean } = createFieldMappings(response); + const queryOptions = + response && response[0] + ? Object.keys(response[0]) + .filter(key => key !== 'id' && key !== 'selectedOptions') + .map(key => ({ + v1: fieldMap[key] || key, + v2: '', + })) + : []; - useEffect(() => { - setCurrentIndex(() => 0); - }, [listType, setCurrentIndex]); + useEffect(() => { + setCurrentIndex(() => 0); + }, [listType, setCurrentIndex]); - const renderSection = (title: string, key: keyof typeof responsesInfo[0], isSummaryPage: boolean) => { - const transTitle = fieldMapToKorean[title]; + const renderSection = (title: string, key: keyof (typeof responsesInfo)[0], isSummaryPage: boolean) => { + const transTitle = fieldMapToKorean[title]; - return ( -
-
-

{transTitle}

-

응답 {response.length}개

-
- - {response.length === 0 ? ( -

응답이 없습니다.

- ) : ( -
- {response.map((response) => ( -
-

{typeof response[key] === 'object' ? JSON.stringify(response[key]) : response[key]}

-
- ))} -
- )} -
- ); - }; - - const renderList = () => { - switch (listType) { - case 'summary': - return ( - <> - {renderSection('name', 'name', true)} - {renderSection('phone', 'phone', true)} - {renderSection('email', 'email', true)} - {renderSection('grade', 'grade', true)} - {renderSection('email', 'email', true)} - - ); - case 'query': - return ( - <> - - {renderSection(selectedField, selectedField as keyof typeof responsesInfo[0], false)} - - ); - case 'individual': - return ( -
- 0 ? - { v1: selectedResponse[0].name, v2: selectedResponse[0].email } : { v1: '전체', v2: '' }} - setSelectedField={setSelectedResponse} - setCurrentIndex={setCurrentIndex} - currentIndex={currentIndex} - responsesLength={selectedResponse.length > 0 ? selectedResponse.length : response.length} - options={[{ v1: '전체', v2: '' }, - ...response.map((res) => ({ v1: res.name, v2: res.email }))]} - /> - -
- ); - default: - return null; - } - }; return ( -
- {renderList()} +
+
+

{transTitle}

+

응답 {response.length}개

+ + {response.length === 0 ? ( +

응답이 없습니다.

+ ) : ( +
+ {response.map(response => ( +
+

{typeof response[key] === 'object' ? JSON.stringify(response[key]) : response[key]}

+
+ ))} +
+ )} +
); + }; + + const renderList = () => { + switch (listType) { + case 'summary': + return ( + <> + {renderSection('name', 'name', true)} + {renderSection('phone', 'phone', true)} + {renderSection('email', 'email', true)} + {renderSection('grade', 'grade', true)} + + ); + case 'query': + return ( + <> + + {renderSection(selectedField, selectedField as keyof (typeof responsesInfo)[0], false)} + + ); + case 'individual': + return ( +
+ 0 + ? { v1: selectedResponse[0].name, v2: selectedResponse[0].email } + : { v1: '전체', v2: '' } + } + setSelectedField={setSelectedResponse} + setCurrentIndex={setCurrentIndex} + currentIndex={currentIndex} + responsesLength={selectedResponse.length > 0 ? selectedResponse.length : response.length} + options={[{ v1: '전체', v2: '' }, ...response.map(res => ({ v1: res.name, v2: res.email }))]} + /> + +
+ ); + default: + return null; + } + }; + return
{renderList()}
; }; export default ResponsesList; diff --git a/src/features/dashboard/ui/SelectedResponseList.tsx b/src/features/dashboard/ui/SelectedResponseList.tsx index 8392ae0c..60c2fdce 100644 --- a/src/features/dashboard/ui/SelectedResponseList.tsx +++ b/src/features/dashboard/ui/SelectedResponseList.tsx @@ -1,70 +1,68 @@ -import { useResponseStore } from '../model/ResponseStore'; +import { useResponseStore } from '../model/store/ResponseStore'; import UnderlineTextField from '../../../../design-system/ui/textFields/UnderlineTextField'; import OptionSection from './OptionSection'; import { options } from '../../../shared/types/responseType'; interface SelectedResponseListProps { - currentIndex: number; + currentIndex: number; } interface Response { - id: number; - name: string; - grade: string; - num: string; - phone: string; - email: string; + id: number; + name: string; + grade: string; + num: string; + phone: string; + email: string; } -const SelectedResponseList = ({ currentIndex}: SelectedResponseListProps) => { - const { response,selectedResponse} = useResponseStore(); - - const fields = [ - { label: '이름', value: 'name', placeholder: '이름' }, - { label: '학년', value: 'grade', placeholder: '학년' }, - { label: '학번', value: 'num', placeholder: '학번' }, - { label: '전화번호', value: 'phone', placeholder: '전화번호' }, - { label: '이메일', value: 'email', placeholder: '이메일' }, - ]; +const SelectedResponseList = ({ currentIndex }: SelectedResponseListProps) => { + const { response, selectedResponse } = useResponseStore(); - return ( -
- {selectedResponse.length > 0 ? ( - selectedResponse.slice(currentIndex, currentIndex + 1).map((response) => ( -
- {fields.map(({ label, value, placeholder }) => ( - { }} - placeholder={placeholder} - errorMessage={''} - className="mb-4" - /> - ))} - -
- )) - ) : ( - response.slice(currentIndex, currentIndex + 1).map((response) => ( -
- {fields.map(({ label, value, placeholder }) => ( - { }} - placeholder={placeholder} - errorMessage={''} - className="mb-4" - /> - ))} - -
- )) - )} -
- ); + const fields = [ + { label: '이름', value: 'name', placeholder: '이름' }, + { label: '학년', value: 'grade', placeholder: '학년' }, + { label: '학번', value: 'num', placeholder: '학번' }, + { label: '전화번호', value: 'phone', placeholder: '전화번호' }, + { label: '이메일', value: 'email', placeholder: '이메일' }, + ]; + + return ( +
+ {selectedResponse.length > 0 + ? selectedResponse.slice(currentIndex, currentIndex + 1).map(response => ( +
+ {fields.map(({ label, value, placeholder }) => ( + {}} + placeholder={placeholder} + errorMessage={''} + className="mb-4" + /> + ))} + +
+ )) + : response.slice(currentIndex, currentIndex + 1).map(response => ( +
+ {fields.map(({ label, value, placeholder }) => ( + {}} + placeholder={placeholder} + errorMessage={''} + className="mb-4" + /> + ))} + +
+ ))} +
+ ); }; export default SelectedResponseList; diff --git a/src/features/event-manage/event-create/model/event.ts b/src/features/event-manage/event-create/model/event.ts deleted file mode 100644 index af19d23d..00000000 --- a/src/features/event-manage/event-create/model/event.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { BaseEvent } from '../../../../shared/types/baseEventType'; - -export interface CreateEventRequest extends BaseEvent { - hostChannelId: number; -} - - diff --git a/src/features/event-manage/event-list/model/eventList.ts b/src/features/event-manage/event-list/model/eventList.ts deleted file mode 100644 index 180e5588..00000000 --- a/src/features/event-manage/event-list/model/eventList.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { BaseEvent } from '../../../../shared/types/baseEventType'; - -export interface EventList extends BaseEvent { - id: number; - hostChannelName: string; - remainDays: string; -} diff --git a/src/features/event-manage/event-create/api/event.ts b/src/features/event/api/event.ts similarity index 74% rename from src/features/event-manage/event-create/api/event.ts rename to src/features/event/api/event.ts index 34d95400..c0c0e31a 100644 --- a/src/features/event-manage/event-create/api/event.ts +++ b/src/features/event/api/event.ts @@ -1,4 +1,4 @@ -import { axiosClient } from '../../../../shared/types/api/http-client'; +import { axiosClient } from '../../../shared/types/api/http-client'; import { CreateEventRequest } from '../model/event'; export const createEvent = async (data: CreateEventRequest) => { diff --git a/src/features/event-manage/event-create/api/host.ts b/src/features/event/api/host.ts similarity index 84% rename from src/features/event-manage/event-create/api/host.ts rename to src/features/event/api/host.ts index f4c21dc1..b1f7b2c5 100644 --- a/src/features/event-manage/event-create/api/host.ts +++ b/src/features/event/api/host.ts @@ -1,4 +1,4 @@ -import { axiosClient } from '../../../../shared/types/api/http-client'; +import { axiosClient } from '../../../shared/types/api/http-client'; import { HostCreationRequest } from '../model/hostCreation'; export const createHost = async (data: HostCreationRequest) => { diff --git a/src/features/event-manage/event-create/api/presignedUrl.ts b/src/features/event/api/presignedUrl.ts similarity index 81% rename from src/features/event-manage/event-create/api/presignedUrl.ts rename to src/features/event/api/presignedUrl.ts index b22a56db..4b1d083c 100644 --- a/src/features/event-manage/event-create/api/presignedUrl.ts +++ b/src/features/event/api/presignedUrl.ts @@ -1,4 +1,4 @@ -import { axiosClient } from '../../../../shared/types/api/http-client'; +import { axiosClient } from '../../../shared/types/api/http-client'; import { PresignedUrlRequest, PresignedUrlResponse } from '../model/presignedUrl'; const presignedUrl = async (dto: PresignedUrlRequest) => { diff --git a/src/features/event-manage/event-create/hooks/useEventHook.ts b/src/features/event/hooks/useEventHook.ts similarity index 85% rename from src/features/event-manage/event-create/hooks/useEventHook.ts rename to src/features/event/hooks/useEventHook.ts index 257f4f27..ab11d10f 100644 --- a/src/features/event-manage/event-create/hooks/useEventHook.ts +++ b/src/features/event/hooks/useEventHook.ts @@ -1,5 +1,5 @@ import { AxiosError } from 'axios'; -import { ApiResponse } from '../../../../shared/types/api/apiResponse'; +import { ApiResponse } from '../../../shared/types/api/apiResponse'; import { createEvent } from '../api/event'; import { CreateEventRequest } from '../model/event'; import { useMutation } from '@tanstack/react-query'; diff --git a/src/features/event-manage/event-create/hooks/useFunnelHook.tsx b/src/features/event/hooks/useFunnelHook.tsx similarity index 100% rename from src/features/event-manage/event-create/hooks/useFunnelHook.tsx rename to src/features/event/hooks/useFunnelHook.tsx diff --git a/src/features/event-manage/event-create/hooks/useHostHook.ts b/src/features/event/hooks/useHostHook.ts similarity index 89% rename from src/features/event-manage/event-create/hooks/useHostHook.ts rename to src/features/event/hooks/useHostHook.ts index 20abef9a..19731bbd 100644 --- a/src/features/event-manage/event-create/hooks/useHostHook.ts +++ b/src/features/event/hooks/useHostHook.ts @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; import { createHost, deleteHost } from '../api/host'; import { HostCreationRequest } from '../model/hostCreation'; -import { ApiResponse } from '../../../../shared/types/api/apiResponse'; +import { ApiResponse } from '../../../shared/types/api/apiResponse'; export const useHostCreation = () => { return useMutation, Error, HostCreationRequest>({ diff --git a/src/features/event-manage/event-create/hooks/usePresignedUrlHook.ts b/src/features/event/hooks/usePresignedUrlHook.ts similarity index 91% rename from src/features/event-manage/event-create/hooks/usePresignedUrlHook.ts rename to src/features/event/hooks/usePresignedUrlHook.ts index dcef1b10..fc0f48ef 100644 --- a/src/features/event-manage/event-create/hooks/usePresignedUrlHook.ts +++ b/src/features/event/hooks/usePresignedUrlHook.ts @@ -1,8 +1,8 @@ import { PresignedUrlRequest, PresignedUrlResponse } from '../model/presignedUrl'; -import { axiosClient } from '../../../../shared/types/api/http-client'; +import { axiosClient } from '../../../shared/types/api/http-client'; import axios from 'axios'; -import { ApiResponse } from '../../../../shared/types/api/apiResponse'; +import { ApiResponse } from '../../../shared/types/api/apiResponse'; const getPresignedUrl = async (dto: PresignedUrlRequest) => { try { diff --git a/src/features/event-manage/event-create/model/FunnelContext.tsx b/src/features/event/model/FunnelContext.tsx similarity index 100% rename from src/features/event-manage/event-create/model/FunnelContext.tsx rename to src/features/event/model/FunnelContext.tsx diff --git a/src/features/event/model/event.ts b/src/features/event/model/event.ts new file mode 100644 index 00000000..397de290 --- /dev/null +++ b/src/features/event/model/event.ts @@ -0,0 +1,11 @@ +import { BaseEvent } from '../../../shared/types/baseEventType'; + +export interface CreateEventRequest extends BaseEvent { + hostChannelId: number; +} + +export interface EventList extends BaseEvent { + id: number; + hostChannelName: string; + remainDays: string; +} diff --git a/src/features/event-manage/event-create/model/hostCreation.ts b/src/features/event/model/hostCreation.ts similarity index 100% rename from src/features/event-manage/event-create/model/hostCreation.ts rename to src/features/event/model/hostCreation.ts diff --git a/src/features/event-manage/event-create/model/presignedUrl.ts b/src/features/event/model/presignedUrl.ts similarity index 100% rename from src/features/event-manage/event-create/model/presignedUrl.ts rename to src/features/event/model/presignedUrl.ts diff --git a/src/features/event-manage/event-create/ui/DatePicker.tsx b/src/features/event/ui/DatePicker.tsx similarity index 100% rename from src/features/event-manage/event-create/ui/DatePicker.tsx rename to src/features/event/ui/DatePicker.tsx diff --git a/src/features/event-manage/event-create/ui/EventCategory.tsx b/src/features/event/ui/EventCategory.tsx similarity index 93% rename from src/features/event-manage/event-create/ui/EventCategory.tsx rename to src/features/event/ui/EventCategory.tsx index 4ee7f679..7f98c130 100644 --- a/src/features/event-manage/event-create/ui/EventCategory.tsx +++ b/src/features/event/ui/EventCategory.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; -import CategoryButton from '../../../../../public/assets/event-manage/creation/BackBtn(black).svg'; +import CategoryButton from '../../../../public/assets/event-manage/creation/BackBtn(black).svg'; import { FunnelState } from '../model/FunnelContext'; -import { CategoryType } from '../../../../shared/types/baseEventType'; +import { CategoryType } from '../../../shared/types/baseEventType'; interface Category { id: string; diff --git a/src/features/event-manage/event-create/ui/EventFunnel.tsx b/src/features/event/ui/EventFunnel.tsx similarity index 82% rename from src/features/event-manage/event-create/ui/EventFunnel.tsx rename to src/features/event/ui/EventFunnel.tsx index 7cb22b67..dc55dc47 100644 --- a/src/features/event-manage/event-create/ui/EventFunnel.tsx +++ b/src/features/event/ui/EventFunnel.tsx @@ -1,14 +1,14 @@ -import HostSelectionPage from '../../../../pages/event-manage/ui/HostSelectionPage'; -import HostCreationPage from '../../../../pages/event-manage/ui/HostCreationPage'; -import EventTitlePage from '../../../../pages/event-manage/ui/EventTitlePage'; -import EventPeriodPage from '../../../../pages/event-manage/ui/EventPeriodPage'; -import EventInfoPage from '../../../../pages/event-manage/ui/EventInfoPage'; -import EventTypePage from '../../../../pages/event-manage/ui/EventTypePage'; -import EventTagPage from '../../../../pages/event-manage/ui/EventTagPage'; -import EventOrganizerInfoPage from '../../../../pages/event-manage/ui/EventOrganizerInfoPage'; -import EventRegisterLayout from '../../../../shared/ui/backgrounds/EventRegisterLayout'; +import HostSelectionPage from '../../../pages/event/ui/host/HostSelectionPage'; +import HostCreationPage from '../../../pages/event/ui/host/HostCreationPage'; +import EventTitlePage from '../../../pages/event/ui/create-event/EventTitlePage'; +import EventPeriodPage from '../../../pages/event/ui/create-event/EventPeriodPage'; +import EventInfoPage from '../../../pages/event/ui/create-event/EventInfoPage'; +import EventTypePage from '../../../pages/event/ui/create-event/EventTypePage'; +import EventTagPage from '../../../pages/event/ui/create-event/EventTagPage'; +import EventOrganizerInfoPage from '../../../pages/event/ui/create-event/EventOrganizerInfoPage'; +import EventRegisterLayout from '../../../shared/ui/backgrounds/EventRegisterLayout'; import { useNavigate } from 'react-router-dom'; -import { EventFunnelInterface, StepNames } from '../../../../shared/types/funnelType'; +import { EventFunnelInterface, StepNames } from '../../../shared/types/funnelType'; import { useFunnelState } from '../model/FunnelContext'; import { useEventCreation } from '../hooks/useEventHook'; import { useHostCreation } from '../hooks/useHostHook'; diff --git a/src/features/event-manage/event-list/ui/EventList.tsx b/src/features/event/ui/EventList.tsx similarity index 91% rename from src/features/event-manage/event-list/ui/EventList.tsx rename to src/features/event/ui/EventList.tsx index b1f276f1..cc4f61b9 100644 --- a/src/features/event-manage/event-list/ui/EventList.tsx +++ b/src/features/event/ui/EventList.tsx @@ -1,8 +1,8 @@ import { useRef, useEffect } from 'react'; -import { useInfiniteScroll } from '../../../../shared/hooks/useInfiniteScroll'; -import { getAllEventsInfinite, getCategoryEventsInfinite } from '../../../../entities/event/api/event'; -import EventCard from '../../../../shared/ui/EventCard'; -import { BaseEvent, CategoryType, TagType } from '../../../../shared/types/baseEventType'; +import { useInfiniteScroll } from '../../../shared/hooks/useInfiniteScroll'; +import { getAllEventsInfinite, getCategoryEventsInfinite } from '../../../entities/event/api/eventDetail'; +import EventCard from '../../../shared/ui/EventCard'; +import { BaseEvent, CategoryType, TagType } from '../../../shared/types/baseEventType'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; interface EventListProps extends BaseEvent { diff --git a/src/features/event-manage/event-create/ui/EventTag.tsx b/src/features/event/ui/EventTag.tsx similarity index 96% rename from src/features/event-manage/event-create/ui/EventTag.tsx rename to src/features/event/ui/EventTag.tsx index e588dcf8..ff8d86e4 100644 --- a/src/features/event-manage/event-create/ui/EventTag.tsx +++ b/src/features/event/ui/EventTag.tsx @@ -1,6 +1,6 @@ import { ChangeEvent, KeyboardEvent, useState } from 'react'; import { FunnelState } from '../model/FunnelContext'; -import MultilineTextField from '../../../../../design-system/ui/textFields/MultilineTextField'; +import MultilineTextField from '../../../../design-system/ui/textFields/MultilineTextField'; interface EventTagProps { eventState?: FunnelState['eventState']; diff --git a/src/features/event-manage/event-create/ui/EventType.tsx b/src/features/event/ui/EventType.tsx similarity index 90% rename from src/features/event-manage/event-create/ui/EventType.tsx rename to src/features/event/ui/EventType.tsx index 963f26ea..750d9f14 100644 --- a/src/features/event-manage/event-create/ui/EventType.tsx +++ b/src/features/event/ui/EventType.tsx @@ -1,8 +1,8 @@ -import OnlineIcon from '../../../../../public/assets/event-manage/creation/OnlineIcon.svg'; -import OfflineIcon from '../../../../../public/assets/event-manage/creation/OfflineIcon.svg'; +import OnlineIcon from '../../../../public/assets/event-manage/creation/OnlineIcon.svg'; +import OfflineIcon from '../../../../public/assets/event-manage/creation/OfflineIcon.svg'; import { useFunnelState } from '../model/FunnelContext'; -import KakaoMap from '../../../../shared/ui/KakaoMap'; -import { AddressSearch } from '../../../../shared/ui/AddressSearch'; +import KakaoMap from '../../../shared/ui/KakaoMap'; +import { AddressSearch } from '../../../shared/ui/AddressSearch'; import { useState } from 'react'; interface EventTypeProps { diff --git a/src/features/event-manage/event-create/ui/FileUpload.tsx b/src/features/event/ui/FileUpload.tsx similarity index 97% rename from src/features/event-manage/event-create/ui/FileUpload.tsx rename to src/features/event/ui/FileUpload.tsx index 93f17f62..1e742b4d 100644 --- a/src/features/event-manage/event-create/ui/FileUpload.tsx +++ b/src/features/event/ui/FileUpload.tsx @@ -1,4 +1,4 @@ -import FileUploadImage from '../../../../../public/assets/event-manage/creation/FileUpload.svg'; +import FileUploadImage from '../../../../public/assets/event-manage/creation/FileUpload.svg'; import { useEffect, useRef, useState } from 'react'; import { uploadFile } from '../hooks/usePresignedUrlHook'; import { FunnelState } from '../model/FunnelContext'; diff --git a/src/features/event-manage/event-create/ui/LinkInput.tsx b/src/features/event/ui/LinkInput.tsx similarity index 94% rename from src/features/event-manage/event-create/ui/LinkInput.tsx rename to src/features/event/ui/LinkInput.tsx index e656e44b..ac42c456 100644 --- a/src/features/event-manage/event-create/ui/LinkInput.tsx +++ b/src/features/event/ui/LinkInput.tsx @@ -1,8 +1,8 @@ import { useEffect, useState } from 'react'; import { FunnelState } from '../model/FunnelContext'; -import AddButton from '../../../../../public/assets/event-manage/creation/AddBtn.svg'; -import CloseButton from '../../../../../public/assets/event-manage/creation/CloseBtn.svg'; -import Link from '../../../../../public/assets/event-manage/creation/Link.svg'; +import AddButton from '../../../../public/assets/event-manage/creation/AddBtn.svg'; +import CloseButton from '../../../../public/assets/event-manage/creation/CloseBtn.svg'; +import Link from '../../../../public/assets/event-manage/creation/Link.svg'; interface LinkInputProps { value?: Link[]; diff --git a/src/features/event-manage/event-create/ui/ShareEventModal.tsx b/src/features/event/ui/ShareEventModal.tsx similarity index 91% rename from src/features/event-manage/event-create/ui/ShareEventModal.tsx rename to src/features/event/ui/ShareEventModal.tsx index 145a11fd..ff3ce9c3 100644 --- a/src/features/event-manage/event-create/ui/ShareEventModal.tsx +++ b/src/features/event/ui/ShareEventModal.tsx @@ -1,7 +1,7 @@ -import profile from '../../../../../public/assets/banners/1.png'; -import link from '../../../../../public/assets/event-manage/details/Link.svg'; -import kakao from '../../../../../public/assets/event-manage/details/KaKao.svg'; -import { shareToKakao } from '../../../../shared/lib/kakaoShare'; +import profile from '../../../../public/assets/banners/1.png'; +import link from '../../../../public/assets/event-manage/details/Link.svg'; +import kakao from '../../../../public/assets/event-manage/details/KaKao.svg'; +import { shareToKakao } from '../../../shared/lib/kakaoShare'; interface ShareEventModalProps { closeModal: () => void; diff --git a/src/features/event-manage/event-create/ui/TextEditor.tsx b/src/features/event/ui/TextEditor.tsx similarity index 100% rename from src/features/event-manage/event-create/ui/TextEditor.tsx rename to src/features/event/ui/TextEditor.tsx diff --git a/src/features/event-manage/event-create/ui/TimePicker.tsx b/src/features/event/ui/TimePicker.tsx similarity index 100% rename from src/features/event-manage/event-create/ui/TimePicker.tsx rename to src/features/event/ui/TimePicker.tsx diff --git a/src/features/home/hooks/useEventHook.ts b/src/features/home/hooks/useEventHook.ts index da921971..d96e35f4 100644 --- a/src/features/home/hooks/useEventHook.ts +++ b/src/features/home/hooks/useEventHook.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; -import { getEventByTag } from '../../../entities/event/api/event'; -import { EventItem } from '../../../entities/event/api/event'; +import { getEventByTag } from '../../../entities/event/api/eventDetail'; import { TagType } from '../../../shared/types/baseEventType'; +import { EventItem } from '../../../entities/event/model/eventDetail'; export const useLatestEvents = () => { return useQuery({ diff --git a/src/features/home/ui/EventSliderSection.tsx b/src/features/home/ui/EventSliderSection.tsx index b6d9a399..2d43f8bd 100644 --- a/src/features/home/ui/EventSliderSection.tsx +++ b/src/features/home/ui/EventSliderSection.tsx @@ -4,7 +4,7 @@ import EventCard from '../../../shared/ui/EventCard'; import IconButton from '../../../../design-system/ui/buttons/IconButton'; import rightButton from '../../../../public/assets/main/RightButton.svg'; import leftButton from '../../../../public/assets/main/LeftButton.svg'; -import { EventItem } from '../../../entities/event/model/event'; +import { EventItem } from '../../../entities/event/model/eventDetail'; interface EventSliderSectionProps { title: string; diff --git a/src/features/payment/ui/TicketOption.tsx b/src/features/payment/ui/TicketOption.tsx index 7b7368fe..ce8ca7e0 100644 --- a/src/features/payment/ui/TicketOption.tsx +++ b/src/features/payment/ui/TicketOption.tsx @@ -1,90 +1,88 @@ -import { TOption } from "../../dashboard/model/TicketOptionStore"; -import { useTicketOptionStore } from "../../dashboard/model/TicketOptionStore"; -import Checkbox from "../../../../design-system/ui/Checkbox"; +import { TOption } from '../../dashboard/model/store/TicketOptionStore'; +import { useTicketOptionStore } from '../../dashboard/model/store/TicketOptionStore'; +import Checkbox from '../../../../design-system/ui/Checkbox'; interface TicketOptionProps { - options: TOption[]; + options: TOption[]; } const TicketOption = ({ options }: TicketOptionProps) => { - const { currentPage, selectedOptions, setOption } = useTicketOptionStore(); - const currentSelectedOptions = selectedOptions[currentPage] || {}; + const { currentPage, selectedOptions, setOption } = useTicketOptionStore(); + const currentSelectedOptions = selectedOptions[currentPage] || {}; - const handleChange = (type: string, optionName: string, value: string) => { - if (type === "text" || type === "single") { - setOption(currentPage, optionName, value); - } else if (type === "multiple") { - const prevValues = (currentSelectedOptions[optionName] as string[]) || []; - const newValues = prevValues.includes(value) - ? prevValues.filter((v) => v !== value) - : [...prevValues, value]; - setOption(currentPage, optionName, newValues); - } - }; + const handleChange = (type: string, optionName: string, value: string) => { + if (type === 'text' || type === 'single') { + setOption(currentPage, optionName, value); + } else if (type === 'multiple') { + const prevValues = (currentSelectedOptions[optionName] as string[]) || []; + const newValues = prevValues.includes(value) ? prevValues.filter(v => v !== value) : [...prevValues, value]; + setOption(currentPage, optionName, newValues); + } + }; - return ( -
- {options.map((option, index) => ( -
-

- {option.optionName} {option.required && *} -

+ return ( +
+ {options.map((option, index) => ( +
+

+ {option.optionName} {option.required && *} +

- {option.type === "text" && ( - handleChange("text", option.optionName, e.target.value)} - /> - )} + {option.type === 'text' && ( + handleChange('text', option.optionName, e.target.value)} + /> + )} - {option.type === "single" && - option.choices.map((choice) => ( - handleChange("single", option.optionName, choice)} - className="block mt-2" - /> - ))} + {option.type === 'single' && + option.choices.map(choice => ( + handleChange('single', option.optionName, choice)} + className="block mt-2" + /> + ))} - {option.type === "multiple" && - option.choices.map((choice) => ( - handleChange("multiple", option.optionName, choice)} - className="block mt-2" - /> - ))} -
+ {option.type === 'multiple' && + option.choices.map(choice => ( + handleChange('multiple', option.optionName, choice)} + className="block mt-2" + /> ))}
- ); + ))} +
+ ); }; export default TicketOption; // 임의 데이터 export const options: TOption[] = [ - { - type: 'text', - optionName: '성함을 알려주세요.', - required: true, - choices: [''] - }, - { - type: 'single', - optionName: '티셔츠 사이즈 선택해주세요.', - required: true, - choices: ['S', 'M', 'L', 'XL'] - }, - { - type: 'multiple', - optionName: '선택해주세요.', - required: false, - choices: ['1', '2', '3', '4'] - }, -] \ No newline at end of file + { + type: 'text', + optionName: '성함을 알려주세요.', + required: true, + choices: [''], + }, + { + type: 'single', + optionName: '티셔츠 사이즈 선택해주세요.', + required: true, + choices: ['S', 'M', 'L', 'XL'], + }, + { + type: 'multiple', + optionName: '선택해주세요.', + required: false, + choices: ['1', '2', '3', '4'], + }, +]; diff --git a/src/features/ticket/api/order.ts b/src/features/ticket/api/order.ts index daac6100..44c9aa41 100644 --- a/src/features/ticket/api/order.ts +++ b/src/features/ticket/api/order.ts @@ -1,33 +1,31 @@ -import { axiosClient } from "../../../shared/types/api/http-client" -import { OrderTicketRequest } from "../model/OrderCreation"; +import { axiosClient } from '../../../shared/types/api/http-client'; +import { OrderTicketRequest } from '../model/order'; export const readTicket = { // 주문 티켓 전체 조회 getAll: async (page: number = 0, size: number = 10) => { - const response = await axiosClient.get("/orders", { + const response = await axiosClient.get('/orders', { params: { page, size }, }); return response.data; }, // 주문 상세 조회 - getDetail: async(ticketId: number, eventId: number) => { - const response = await axiosClient.get('/orders/purchase-confirmation',{ - params: {ticketId, eventId} + getDetail: async (ticketId: number, eventId: number) => { + const response = await axiosClient.get('/orders/purchase-confirmation', { + params: { ticketId, eventId }, }); return response.data; - } -} + }, +}; // 티켓 구매 export const orderTickets = async (data: OrderTicketRequest) => { - const response = await axiosClient.post("/orders", data); + const response = await axiosClient.post('/orders', data); return response.data; -} +}; // 티켓 취소 export const cancelTickets = async (orderId: number) => { const response = await axiosClient.post(`/orders/cancel?orderId=${orderId}`); return response.data; -} - - +}; diff --git a/src/features/ticket/api/ticket.ts b/src/features/ticket/api/ticket.ts index e9eb563a..788eb768 100644 --- a/src/features/ticket/api/ticket.ts +++ b/src/features/ticket/api/ticket.ts @@ -1,19 +1,19 @@ -import { axiosClient } from "../../../shared/types/api/http-client"; -import { CreateTicketRequest, ReadTicketResponse } from "../model/ticketInformation"; +import { axiosClient } from '../../../shared/types/api/http-client'; +import { CreateTicketRequest, ReadTicketResponse } from '../model/ticket'; export const createTicket = async (data: CreateTicketRequest) => { - const response = await axiosClient.post('/tickets', data); - return response.data; -} + const response = await axiosClient.post('/tickets', data); + return response.data; +}; export const readTicket = async (eventId: number): Promise<{ isSuccess: boolean; result: ReadTicketResponse[] }> => { - const response = await axiosClient.get("/tickets", { - params: { eventId }, - }); - return response.data; -} + const response = await axiosClient.get('/tickets', { + params: { eventId }, + }); + return response.data; +}; export const deleteTicket = async (ticketId: number) => { - const response = await axiosClient.delete(`/tickets/${ticketId}`); - return response.data; -} \ No newline at end of file + const response = await axiosClient.delete(`/tickets/${ticketId}`); + return response.data; +}; diff --git a/src/features/ticket/hooks/useTicketHook.ts b/src/features/ticket/hooks/useTicketHook.ts index 4d3e3280..d40f9710 100644 --- a/src/features/ticket/hooks/useTicketHook.ts +++ b/src/features/ticket/hooks/useTicketHook.ts @@ -1,37 +1,37 @@ -import { useMutation, useQuery } from "@tanstack/react-query"; -import { createTicket, deleteTicket, readTicket } from "../api/ticket"; -import { CreateTicketRequest, ReadTicketResponse, TicketResponse } from "../model/ticketInformation"; +import { useMutation, useQuery } from '@tanstack/react-query'; +import { createTicket, deleteTicket, readTicket } from '../api/ticket'; +import { CreateTicketRequest, ReadTicketResponse, TicketResponse } from '../model/ticket'; export const useTickets = (eventId: number) => { - return useQuery<{ isSuccess: boolean; result: ReadTicketResponse[] }>({ - queryKey: ['tickets', eventId], - queryFn: () => readTicket(eventId), - enabled: !!eventId, - }); + return useQuery<{ isSuccess: boolean; result: ReadTicketResponse[] }>({ + queryKey: ['tickets', eventId], + queryFn: () => readTicket(eventId), + enabled: !!eventId, + }); }; export const useCreateTicket = () => { - return useMutation({ - mutationFn: createTicket, - onSuccess: () => { - alert('티켓이 성공적으로 저장되었습니다.'); - window.location.reload(); - }, - onError: () => { - alert('티켓 저장에 실패했습니다. 다시 시도해주세요.'); - }, - }); + return useMutation({ + mutationFn: createTicket, + onSuccess: () => { + alert('티켓이 성공적으로 저장되었습니다.'); + window.location.reload(); + }, + onError: () => { + alert('티켓 저장에 실패했습니다. 다시 시도해주세요.'); + }, + }); }; export const useDeleteTicket = () => { - return useMutation({ - mutationFn: deleteTicket, - onSuccess: () => { - alert("티켓이 삭제되었습니다."); - window.location.reload(); - }, - onError: () => { - alert('티켓 삭제 중 오류가 발생했습니다.'); - } - }); -}; \ No newline at end of file + return useMutation({ + mutationFn: deleteTicket, + onSuccess: () => { + alert('티켓이 삭제되었습니다.'); + window.location.reload(); + }, + onError: () => { + alert('티켓 삭제 중 오류가 발생했습니다.'); + }, + }); +}; diff --git a/src/features/ticket/model/OrderCreation.ts b/src/features/ticket/model/Order.ts similarity index 100% rename from src/features/ticket/model/OrderCreation.ts rename to src/features/ticket/model/Order.ts diff --git a/src/features/ticket/model/TicketContext.tsx b/src/features/ticket/model/TicketContext.tsx index a477ab17..770d8dcf 100644 --- a/src/features/ticket/model/TicketContext.tsx +++ b/src/features/ticket/model/TicketContext.tsx @@ -1,5 +1,5 @@ import { createContext, ReactNode, useContext, useState } from 'react'; -import { CreateTicketRequest } from './ticketInformation'; +import { CreateTicketRequest } from './ticket'; export interface TicketState { ticketState: CreateTicketRequest; @@ -11,7 +11,7 @@ const TicketContext = createContext(undefined); export const TicketProvider = ({ children }: { children: ReactNode }) => { const [ticketState, setTicketState] = useState({ - eventId: 0, + eventId: 0, ticketType: '', ticketName: '', ticketDescription: '', @@ -40,4 +40,4 @@ export const useTicketState = () => { throw new Error('useTicketState must be used within a TicketProvider'); } return context; -}; \ No newline at end of file +}; diff --git a/src/features/ticket/model/ticketInformation.ts b/src/features/ticket/model/ticket.ts similarity index 100% rename from src/features/ticket/model/ticketInformation.ts rename to src/features/ticket/model/ticket.ts diff --git a/src/features/ticket/model/TicketDatePicker.tsx b/src/features/ticket/ui/TicketDatePicker.tsx similarity index 100% rename from src/features/ticket/model/TicketDatePicker.tsx rename to src/features/ticket/ui/TicketDatePicker.tsx diff --git a/src/pages/bookmark/ui/BookmarkPage.tsx b/src/pages/bookmark/ui/BookmarkPage.tsx index be4470de..3dbdf519 100644 --- a/src/pages/bookmark/ui/BookmarkPage.tsx +++ b/src/pages/bookmark/ui/BookmarkPage.tsx @@ -1,42 +1,42 @@ -import { useNavigate } from "react-router-dom"; -import Header from "../../../../design-system/ui/Header"; +import { useNavigate } from 'react-router-dom'; +import Header from '../../../../design-system/ui/Header'; import searchIcon from '../../../../design-system/icons/Search.svg'; -import BottomBar from "../../../widgets/main/ui/BottomBar"; -import EventCard from "../../../shared/ui/EventCard"; -import { useBookmarks } from "../../../features/bookmark/model/useBookmarkHook"; +import BottomBar from '../../../widgets/main/ui/BottomBar'; +import EventCard from '../../../shared/ui/EventCard'; +import { useBookmarks } from '../../../features/bookmark/hook/useBookmarkHook'; const BookmarkPage = () => { - const navigate = useNavigate(); - const { data } = useBookmarks(); + const navigate = useNavigate(); + const { data } = useBookmarks(); - return ( -
-
navigate('/search')}> - Search Icon - - } - /> -
- {data?.map(event => ( - navigate(`/event-details/${event.id}`)} - /> - ))} -
- -
- ); -} -export default BookmarkPage; \ No newline at end of file + return ( +
+
navigate('/search')}> + Search Icon + + } + /> +
+ {data?.map(event => ( + navigate(`/event-details/${event.id}`)} + /> + ))} +
+ +
+ ); +}; +export default BookmarkPage; diff --git a/src/pages/dashboard/ui/DashbaordPage.tsx b/src/pages/dashboard/ui/DashbaordPage.tsx index 6141dd76..f9a5af0d 100644 --- a/src/pages/dashboard/ui/DashbaordPage.tsx +++ b/src/pages/dashboard/ui/DashbaordPage.tsx @@ -1,10 +1,10 @@ import DashboardLayout from '../../../shared/ui/backgrounds/DashboardLayout'; -import EventOverview from '../../../widgets/dashboard/ui/EventOverview'; -import TicketRevenue from '../../../widgets/dashboard/ui/TicketRevenue'; +import TicketRevenue from '../../../widgets/dashboard/ui/main/TicketRevenue'; import ticket from '../../../../public/assets/dashboard/main/Ticket(white).svg'; import cash from '../../../../public/assets/dashboard/main/Cash.svg'; import CheckList from '../../../features/dashboard/ui/Checklist'; import useHostDashboard from '../../../entities/host/hook/hostDashboardHook'; +import EventOverview from '../../../widgets/dashboard/ui/main/EventOverview'; const DashboardPage = () => { const { data } = useHostDashboard(); diff --git a/src/pages/dashboard/ui/EventDetailPage.tsx b/src/pages/dashboard/ui/EventDetailPage.tsx index 0a75313a..2edfc099 100644 --- a/src/pages/dashboard/ui/EventDetailPage.tsx +++ b/src/pages/dashboard/ui/EventDetailPage.tsx @@ -1,9 +1,9 @@ import { useNavigate } from 'react-router-dom'; import { useEffect, useState } from 'react'; import Button from '../../../../design-system/ui/Button'; -import FileUpload from '../../../features/event-manage/event-create/ui/FileUpload'; -import LinkInput, { Link } from '../../../features/event-manage/event-create/ui/LinkInput'; -import TextEditor from '../../../features/event-manage/event-create/ui/TextEditor'; +import FileUpload from '../../../features/event/ui/FileUpload'; +import LinkInput, { Link } from '../../../features/event/ui/LinkInput'; +import TextEditor from '../../../features/event/ui/TextEditor'; import DashboardLayout from '../../../shared/ui/backgrounds/DashboardLayout'; import useEventDetail from '../../../entities/event/hook/useEventHook'; import { useUpdateEventHook } from '../../../features/dashboard/hook/useEventHook'; diff --git a/src/pages/dashboard/ui/EventInfoPage.tsx b/src/pages/dashboard/ui/EventInfoPage.tsx index aeec62dd..92145c7e 100644 --- a/src/pages/dashboard/ui/EventInfoPage.tsx +++ b/src/pages/dashboard/ui/EventInfoPage.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import ChoiceChip from '../../../../design-system/ui/ChoiceChip'; import DefaultTextField from '../../../../design-system/ui/textFields/DefaultTextField'; -import EventDatePicker from '../../../features/event-manage/event-create/ui/DatePicker'; +import EventDatePicker from '../../../features/event/ui/DatePicker'; import DashboardLayout from '../../../shared/ui/backgrounds/DashboardLayout'; import { useNavigate } from 'react-router-dom'; import Button from '../../../../design-system/ui/Button'; diff --git a/src/pages/dashboard/ui/EventTagPage.tsx b/src/pages/dashboard/ui/EventTagPage.tsx index 95de66e6..c5c7bc74 100644 --- a/src/pages/dashboard/ui/EventTagPage.tsx +++ b/src/pages/dashboard/ui/EventTagPage.tsx @@ -1,8 +1,8 @@ import { useNavigate } from 'react-router-dom'; import DashboardLayout from '../../../shared/ui/backgrounds/DashboardLayout'; import Button from '../../../../design-system/ui/Button'; -import EventCategory from '../../../features/event-manage/event-create/ui/EventCategory'; -import EventTag from '../../../features/event-manage/event-create/ui/EventTag'; +import EventCategory from '../../../features/event/ui/EventCategory'; +import EventTag from '../../../features/event/ui/EventTag'; const EventTagPage = () => { const navigate = useNavigate(); diff --git a/src/pages/dashboard/ui/ParticipantsMangementPage.tsx b/src/pages/dashboard/ui/ParticipantsMangementPage.tsx index dda2c53b..c336efd2 100644 --- a/src/pages/dashboard/ui/ParticipantsMangementPage.tsx +++ b/src/pages/dashboard/ui/ParticipantsMangementPage.tsx @@ -4,8 +4,8 @@ import DashboardLayout from '../../../shared/ui/backgrounds/DashboardLayout'; import SearchBar from '../../../shared/ui/SearchBar'; import ButtonModal from '../../../../design-system/ui/modals/ButtonModal'; import ParticipantsFilterBar from '../../../widgets/dashboard/ui/ParticipantsFilterBar'; -import EmailModal from '../../../widgets/dashboard/ui/EmailModal'; -import SelectTicketModal from '../../../widgets/dashboard/ui/SelectTicketModal'; +import EmailModal from '../../../widgets/dashboard/ui/email/EmailModal'; +import SelectTicketModal from '../../../widgets/dashboard/ui/email/SelectTicketModal'; import { useParticipants } from '../../../features/dashboard/hook/useParticipants'; const ParticipantsManagementPage = () => { @@ -52,12 +52,10 @@ const ParticipantsManagementPage = () => { openSelectTicket={() => { setTicketModalOpen(true); }} - allParticipantEmails={participants.map((p: { email: string; }) => p.email)} + allParticipantEmails={participants.map((p: { email: string }) => p.email)} /> )} - {ticketModalOpen && ( - setTicketModalOpen(false)} participants={participants} /> - )} + {ticketModalOpen && setTicketModalOpen(false)} participants={participants} />} ); }; diff --git a/src/pages/dashboard/ui/ResponsesManagementPage.tsx b/src/pages/dashboard/ui/ResponsesManagementPage.tsx index 0ba47b9f..e93603cc 100644 --- a/src/pages/dashboard/ui/ResponsesManagementPage.tsx +++ b/src/pages/dashboard/ui/ResponsesManagementPage.tsx @@ -2,37 +2,34 @@ import { useEffect, useState } from 'react'; import DashboardLayout from '../../../shared/ui/backgrounds/DashboardLayout'; import ResponsesFilterBar from '../../../widgets/dashboard/ui/ResponsesFilterBar'; import ResponsesList from '../../../features/dashboard/ui/ResponsesList'; -import { useResponseStore } from '../../../features/dashboard/model/ResponseStore'; +import { useResponseStore } from '../../../features/dashboard/model/store/ResponseStore'; import { responsesInfo } from '../../../shared/types/responseType'; import { useLocation } from 'react-router-dom'; const ResponsesManagementPage = () => { - const [listType, setListType] = useState<'summary' | 'query' | 'individual'>('summary'); - const { response, setResponses, setSelectedResponse } = useResponseStore(); - const location = useLocation(); - const { participantName, participantEmail } = location.state || {}; - useEffect(() => { - setResponses(responsesInfo); - }, [setResponses]); - useEffect(() => { - if (participantName) { - setListType('individual'); - setSelectedResponse(participantName, participantEmail); - } - }, [participantName]); - return ( - -
-

응답 {response.length}개

-
- -
- -
-
- ); + const [listType, setListType] = useState<'summary' | 'query' | 'individual'>('summary'); + const { response, setResponses, setSelectedResponse } = useResponseStore(); + const location = useLocation(); + const { participantName, participantEmail } = location.state || {}; + useEffect(() => { + setResponses(responsesInfo); + }, [setResponses]); + useEffect(() => { + if (participantName) { + setListType('individual'); + setSelectedResponse(participantName, participantEmail); + } + }, [participantName]); + return ( + +
+

응답 {response.length}개

+
+ +
+ +
+
+ ); }; -export default ResponsesManagementPage; \ No newline at end of file +export default ResponsesManagementPage; diff --git a/src/pages/dashboard/ui/mail/EmailEditPage.tsx b/src/pages/dashboard/ui/mail/EmailEditPage.tsx index 47eeb556..3975a3e9 100644 --- a/src/pages/dashboard/ui/mail/EmailEditPage.tsx +++ b/src/pages/dashboard/ui/mail/EmailEditPage.tsx @@ -2,17 +2,17 @@ import { useState } from 'react'; import { useParams } from 'react-router-dom'; import DashboardLayout from '../../../../shared/ui/backgrounds/DashboardLayout'; import EmailInput from '../../../../features/dashboard/ui/EmailInput'; -import TimePicker from '../../../../features/event-manage/event-create/ui/TimePicker'; +import TimePicker from '../../../../features/event/ui/TimePicker'; import Button from '../../../../../design-system/ui/Button'; -import SelectTicketModal from '../../../../widgets/dashboard/ui/SelectTicketModal'; +import SelectTicketModal from '../../../../widgets/dashboard/ui/email/SelectTicketModal'; import { useParticipants } from '../../../../features/dashboard/hook/useParticipants'; -import { useEmailStore } from '../../../../features/dashboard/model/EmailStore'; +import { useEmailStore } from '../../../../features/dashboard/model/store/EmailStore'; import { useEditEmail } from '../../../../features/dashboard/hook/useEmailHook'; const EmailEditPage = () => { const [ticketModalOpen, setTicketModalOpen] = useState(false); const { participants } = useParticipants(); const { id } = useParams(); - const {mutate: editEmail} = useEditEmail(); + const { mutate: editEmail } = useEditEmail(); const { reservationEmailId, @@ -35,7 +35,7 @@ const EmailEditPage = () => { reservationDate, reservationTime, }; - editEmail({ reservationEmailId: reservationEmailId, data: emailData,}); + editEmail({ reservationEmailId: reservationEmailId, data: emailData }); }; return ( @@ -44,8 +44,8 @@ const EmailEditPage = () => { setTicketModalOpen(true)} - allParticipantEmails={participants.map((p: { email: string; }) => p.email)} - isEdited= {true} + allParticipantEmails={participants.map((p: { email: string }) => p.email)} + isEdited={true} /> {/*시간 선택 컴포넌트*/} { const [ticketModalOpen, setTicketModalOpen] = useState(false); const { participants } = useParticipants(); const { id } = useParams(); const { mutate: sendEmail } = useSendEmail(); - - const { - title, - content, - recipients, - reservationDate, - setReservationDate, - ticketId, - targetType - } = useEmailStore(); + + const { title, content, recipients, reservationDate, setReservationDate, ticketId, targetType } = useEmailStore(); const handleSend = () => { if (!title.trim()) { @@ -63,11 +55,13 @@ const EmailPage = () => {
setTicketModalOpen(true)} - allParticipantEmails={participants.map((p: { email: string; }) => p.email)} + allParticipantEmails={participants.map((p: { email: string }) => p.email)} /> {/*시간 선택 컴포넌트*/} { setReservationDate(isoString); }} + onChange={isoString => { + setReservationDate(isoString); + }} />
{isModalOpen && ( - { @@ -41,7 +41,7 @@ const TicketConfirmPage = () => { const response = await readTicket.getDetail(ticketId, eventId); setTicket(response.result || []); } catch (error) { - console.error("구매한 티켓 정보 불러오기 실패:", error); + console.error('구매한 티켓 정보 불러오기 실패:', error); } }; fetchOrderTicket(); @@ -53,12 +53,12 @@ const TicketConfirmPage = () => { for (const orderId of orderIds) { try { const response = await cancelTickets(orderId); - console.log("티켓 취소 API 응답:", response); + console.log('티켓 취소 API 응답:', response); } catch (error) { console.error(`orderId ${orderId} 취소 실패:`, error); } } - } + }; return ( <>
{ {ticket ? ( <>
- - + +

오시는 길

{ticket.eventAddress}

@@ -84,12 +97,16 @@ const TicketConfirmPage = () => {

티켓 정보를 불러오는 중...

)} {isModalOpen && ( - setIsModalOpen(false)} - onClick={() => { cancleOrderTicket(orderIds).then(() => { navigate('/menu/myticket'); }); }} + onClick={() => { + cancleOrderTicket(orderIds).then(() => { + navigate('/menu/myticket'); + }); + }} /> )} diff --git a/src/pages/dashboard/ui/ticket/TicketCreatePage.tsx b/src/pages/dashboard/ui/ticket/TicketCreatePage.tsx index b938df17..430e2a9f 100644 --- a/src/pages/dashboard/ui/ticket/TicketCreatePage.tsx +++ b/src/pages/dashboard/ui/ticket/TicketCreatePage.tsx @@ -4,8 +4,8 @@ import { TwoOptions } from '../../../../../design-system/stories/ChoiceChip.stor import ChoiceChip from '../../../../../design-system/ui/ChoiceChip'; import DefaultTextField from '../../../../../design-system/ui/textFields/DefaultTextField'; import Button from '../../../../../design-system/ui/Button'; -import TicketDatePicker from '../../../../features/ticket/model/TicketDatePicker'; -import { CreateTicketRequest } from '../../../../features/ticket/model/ticketInformation'; +import TicketDatePicker from '../../../../features/ticket/ui/TicketDatePicker'; +import { CreateTicketRequest } from '../../../../features/ticket/model/ticket'; import { useCreateTicket } from '../../../../features/ticket/hooks/useTicketHook'; import { useNavigate, useParams } from 'react-router-dom'; @@ -14,7 +14,7 @@ const TicketCreatePage = () => { const { mutate: createTicket } = useCreateTicket(); const { id } = useParams(); const eventId = Number(id); - + const [ticketData, setTicketData] = useState({ eventId: eventId, ticketType: 'FIRST_COME', @@ -35,7 +35,7 @@ const TicketCreatePage = () => { } else { mappedType = 'SELECTION'; } - setTicketData((prev) => ({ + setTicketData(prev => ({ ...prev, ticketType: mappedType, })); @@ -47,7 +47,7 @@ const TicketCreatePage = () => { if ((field === 'ticketPrice' || field === 'availableQuantity') && Number(value) < 0) { return; } - setTicketData((prev) => ({ + setTicketData(prev => ({ ...prev, [field]: field === 'ticketPrice' || field === 'availableQuantity' ? Number(value) : value, })); @@ -55,7 +55,7 @@ const TicketCreatePage = () => { // 시간 업데이트 const handleDateChange = (dates: { startDate: string; endDate: string; startTime: string; endTime: string }) => { - setTicketData((prevState) => ({ + setTicketData(prevState => ({ ...prevState, startDate: dates.startDate, endDate: dates.endDate, @@ -78,7 +78,12 @@ const TicketCreatePage = () => { // API 호출 const handleSaveClick = async () => { - if (!ticketData.ticketName || !ticketData.ticketDescription || ticketData.ticketPrice < 0 || !ticketData.availableQuantity) { + if ( + !ticketData.ticketName || + !ticketData.ticketDescription || + ticketData.ticketPrice < 0 || + !ticketData.availableQuantity + ) { alert('모든 필수 입력 항목을 작성해주세요.'); return; } @@ -128,9 +133,19 @@ const TicketCreatePage = () => { {/*가격 계산 란*/}
- +

X

- +

=

예상 수익

@@ -141,10 +156,14 @@ const TicketCreatePage = () => { {/*캘린더가 들어갈 자리*/}

판매 기간

- +
- +
@@ -155,4 +174,4 @@ const TicketCreatePage = () => { ); }; -export default TicketCreatePage; \ No newline at end of file +export default TicketCreatePage; diff --git a/src/pages/dashboard/ui/ticket/TicketListPage.tsx b/src/pages/dashboard/ui/ticket/TicketListPage.tsx index 2f8a3c34..06165a3c 100644 --- a/src/pages/dashboard/ui/ticket/TicketListPage.tsx +++ b/src/pages/dashboard/ui/ticket/TicketListPage.tsx @@ -1,6 +1,6 @@ import DashboardLayout from '../../../../shared/ui/backgrounds/DashboardLayout'; import Ticket from '../../../../../public/assets/dashboard/ticket/Ticket(horizon).svg'; -import TicketItem from '../../../../widgets/dashboard/ui/TicketItem'; +import TicketItem from '../../../../widgets/dashboard/ui/ticket/TicketItem'; import { useNavigate, useParams } from 'react-router-dom'; import HorizontalCardButton from '../../../../../design-system/ui/buttons/HorizontalCardButton'; import AddButton from '../../../../../public/assets/dashboard/ticket/AddButton.svg'; diff --git a/src/pages/event-manage/ui/EventInfoPage.tsx b/src/pages/event-manage/ui/EventInfoPage.tsx deleted file mode 100644 index fc9fe9ad..00000000 --- a/src/pages/event-manage/ui/EventInfoPage.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import FileUpload from '../../../features/event-manage/event-create/ui/FileUpload'; -import TextEditor from '../../../features/event-manage/event-create/ui/TextEditor'; -import LinkInput from '../../../features/event-manage/event-create/ui/LinkInput'; -import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext'; - -const EventInfoPage = () => { - const { setEventState } = useFunnelState(); - return ( -
- - - -
- ); -}; - -export default EventInfoPage; diff --git a/src/pages/event/ui/AllEventsPage.tsx b/src/pages/event/ui/AllEventsPage.tsx index 8063f249..79782548 100644 --- a/src/pages/event/ui/AllEventsPage.tsx +++ b/src/pages/event/ui/AllEventsPage.tsx @@ -3,7 +3,7 @@ import Header from '../../../../design-system/ui/Header'; import SearchTextField from '../../../../design-system/ui/textFields/SearchTextField'; import searchIcon from '../../../../design-system/icons/Search.svg'; import BottomBar from '../../../widgets/main/ui/BottomBar'; -import EventList from '../../../features/event-manage/event-list/ui/EventList'; +import EventList from '../../../features/event/ui/EventList'; import { useNavigate } from 'react-router-dom'; import useAuthStore from '../../../app/provider/authStore'; import { AnimatePresence } from 'framer-motion'; diff --git a/src/pages/event/ui/CategoryPage.tsx b/src/pages/event/ui/CategoryPage.tsx index b0c431a7..3dca13e9 100644 --- a/src/pages/event/ui/CategoryPage.tsx +++ b/src/pages/event/ui/CategoryPage.tsx @@ -3,7 +3,7 @@ import Header from '../../../../design-system/ui/Header'; import SearchTextField from '../../../../design-system/ui/textFields/SearchTextField'; import searchIcon from '../../../../design-system/icons/Search.svg'; import BottomBar from '../../../widgets/main/ui/BottomBar'; -import EventList from '../../../features/event-manage/event-list/ui/EventList'; +import EventList from '../../../features/event/ui/EventList'; import { useNavigate, useLocation } from 'react-router-dom'; import useAuthStore from '../../../app/provider/authStore'; import { AnimatePresence } from 'framer-motion'; diff --git a/src/pages/event/ui/EventDetailsPage.tsx b/src/pages/event/ui/EventDetailsPage.tsx index 9c6a30e2..ee9d73ec 100644 --- a/src/pages/event/ui/EventDetailsPage.tsx +++ b/src/pages/event/ui/EventDetailsPage.tsx @@ -9,14 +9,14 @@ import like from '../../../../public/assets/event-manage/details/Like.svg'; import liked from '../../../../public/assets/event-manage/details/ClickedLike.svg'; import TicketInfo from '../../../widgets/event/ui/TicketInfo'; import link from '../../../../public/assets/event-manage/details/Link.svg'; -import ShareEventModal from '../../../features/event-manage/event-create/ui/ShareEventModal'; +import ShareEventModal from '../../../features/event/ui/ShareEventModal'; import participantsImg from '../../../../public/assets/event-manage/details/People.svg'; import dateImg from '../../../../public/assets/event-manage/details/Date.svg'; import timeImg from '../../../../public/assets/event-manage/details/Time.svg'; import locationImg from '../../../../public/assets/event-manage/details/Location.svg'; import KakaoMap from '../../../shared/ui/KakaoMap'; import useEventDetail from '../../../entities/event/hook/useEventHook'; -import { useCreateBookmark, useDeleteBookmark } from '../../../features/bookmark/model/useBookmarkHook'; +import { useCreateBookmark, useDeleteBookmark } from '../../../features/bookmark/hook/useBookmarkHook'; import { formatDate, formatTime } from '../../../shared/lib/date'; const EventDetailsPage = () => { diff --git a/src/pages/event/ui/create-event/EventInfoPage.tsx b/src/pages/event/ui/create-event/EventInfoPage.tsx new file mode 100644 index 00000000..2e878d65 --- /dev/null +++ b/src/pages/event/ui/create-event/EventInfoPage.tsx @@ -0,0 +1,17 @@ +import FileUpload from '../../../../features/event/ui/FileUpload'; +import TextEditor from '../../../../features/event/ui/TextEditor'; +import LinkInput from '../../../../features/event/ui/LinkInput'; +import { useFunnelState } from '../../../../features/event/model/FunnelContext'; + +const EventInfoPage = () => { + const { setEventState } = useFunnelState(); + return ( +
+ + + +
+ ); +}; + +export default EventInfoPage; diff --git a/src/pages/event-manage/ui/EventOrganizerInfoPage.tsx b/src/pages/event/ui/create-event/EventOrganizerInfoPage.tsx similarity index 87% rename from src/pages/event-manage/ui/EventOrganizerInfoPage.tsx rename to src/pages/event/ui/create-event/EventOrganizerInfoPage.tsx index 5b329574..df8faa5c 100644 --- a/src/pages/event-manage/ui/EventOrganizerInfoPage.tsx +++ b/src/pages/event/ui/create-event/EventOrganizerInfoPage.tsx @@ -1,8 +1,8 @@ import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; -import UnderlineTextField from '../../../../design-system/ui/textFields/UnderlineTextField'; -import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext'; -import { OrganizerFormData, organizerZodValidation } from '../../../shared/lib/formValidation'; +import UnderlineTextField from '../../../../../design-system/ui/textFields/UnderlineTextField'; +import { useFunnelState } from '../../../../features/event/model/FunnelContext'; +import { OrganizerFormData, organizerZodValidation } from '../../../../shared/lib/formValidation'; interface EventOrganizerInfoPageProps { onValidationChange?: (isValid: boolean) => void; diff --git a/src/pages/event-manage/ui/EventPeriodPage.tsx b/src/pages/event/ui/create-event/EventPeriodPage.tsx similarity index 61% rename from src/pages/event-manage/ui/EventPeriodPage.tsx rename to src/pages/event/ui/create-event/EventPeriodPage.tsx index 0ed7899c..0cb5b95d 100644 --- a/src/pages/event-manage/ui/EventPeriodPage.tsx +++ b/src/pages/event/ui/create-event/EventPeriodPage.tsx @@ -1,5 +1,5 @@ -import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext'; -import EventDatePicker from '../../../features/event-manage/event-create/ui/DatePicker'; +import { useFunnelState } from '../../../../features/event/model/FunnelContext'; +import EventDatePicker from '../../../../features/event/ui/DatePicker'; const EventPeriodPage = () => { const { eventState, setEventState } = useFunnelState(); diff --git a/src/pages/event-manage/ui/EventTagPage.tsx b/src/pages/event/ui/create-event/EventTagPage.tsx similarity index 68% rename from src/pages/event-manage/ui/EventTagPage.tsx rename to src/pages/event/ui/create-event/EventTagPage.tsx index 4d6554cb..88c6401a 100644 --- a/src/pages/event-manage/ui/EventTagPage.tsx +++ b/src/pages/event/ui/create-event/EventTagPage.tsx @@ -1,7 +1,7 @@ -import SuccessIcon from '../../../../public/assets/event-manage/creation/SuccessBox.svg'; -import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext'; -import EventCategory from '../../../features/event-manage/event-create/ui/EventCategory'; -import EventTag from '../../../features/event-manage/event-create/ui/EventTag'; +import SuccessIcon from '../../../../../public/assets/event-manage/creation/SuccessBox.svg'; +import { useFunnelState } from '../../../../features/event/model/FunnelContext'; +import EventCategory from '../../../../features/event/ui/EventCategory'; +import EventTag from '../../../../features/event/ui/EventTag'; const EventTagPage = () => { const { eventState, setEventState } = useFunnelState(); diff --git a/src/pages/event-manage/ui/EventTitlePage.tsx b/src/pages/event/ui/create-event/EventTitlePage.tsx similarity index 83% rename from src/pages/event-manage/ui/EventTitlePage.tsx rename to src/pages/event/ui/create-event/EventTitlePage.tsx index 5bfd816d..2c779777 100644 --- a/src/pages/event-manage/ui/EventTitlePage.tsx +++ b/src/pages/event/ui/create-event/EventTitlePage.tsx @@ -1,8 +1,8 @@ import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; -import UnderlineTextField from '../../../../design-system/ui/textFields/UnderlineTextField'; -import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext'; -import { EventTitleFormData, eventTitleZodValidation } from '../../../shared/lib/formValidation'; +import UnderlineTextField from '../../../../../design-system/ui/textFields/UnderlineTextField'; +import { useFunnelState } from '../../../../features/event/model/FunnelContext'; +import { EventTitleFormData, eventTitleZodValidation } from '../../../../shared/lib/formValidation'; interface EventTitlePageProps { onValidationChange?: (isValid: boolean) => void; diff --git a/src/pages/event-manage/ui/EventTypePage.tsx b/src/pages/event/ui/create-event/EventTypePage.tsx similarity index 68% rename from src/pages/event-manage/ui/EventTypePage.tsx rename to src/pages/event/ui/create-event/EventTypePage.tsx index d3afcafa..f41062a7 100644 --- a/src/pages/event-manage/ui/EventTypePage.tsx +++ b/src/pages/event/ui/create-event/EventTypePage.tsx @@ -1,4 +1,4 @@ -import EventType from '../../../features/event-manage/event-create/ui/EventType'; +import EventType from '../../../../features/event/ui/EventType'; const EventTypePage = () => { return ( diff --git a/src/pages/event-manage/ui/FunnelPage.tsx b/src/pages/event/ui/create-event/FunnelPage.tsx similarity index 84% rename from src/pages/event-manage/ui/FunnelPage.tsx rename to src/pages/event/ui/create-event/FunnelPage.tsx index dfeeb5ee..8999a6fc 100644 --- a/src/pages/event-manage/ui/FunnelPage.tsx +++ b/src/pages/event/ui/create-event/FunnelPage.tsx @@ -1,8 +1,8 @@ import { useEffect, useState } from 'react'; -import { useFunnel } from '../../../features/event-manage/event-create/hooks/useFunnelHook'; -import EventFunnel from '../../../features/event-manage/event-create/ui/EventFunnel'; +import { useFunnel } from '../../../../features/event/hooks/useFunnelHook'; +import EventFunnel from '../../../../features/event/ui/EventFunnel'; import { useLocation, useNavigate } from 'react-router-dom'; -import { FunnelProvider } from '../../../features/event-manage/event-create/model/FunnelContext'; +import { FunnelProvider } from '../../../../features/event/model/FunnelContext'; const FunnelPage = () => { const { Funnel, Step, setStep, currentStep, steps } = useFunnel(0); diff --git a/src/pages/event-manage/ui/HostCreationPage.tsx b/src/pages/event/ui/host/HostCreationPage.tsx similarity index 80% rename from src/pages/event-manage/ui/HostCreationPage.tsx rename to src/pages/event/ui/host/HostCreationPage.tsx index 5a42b484..307434fc 100644 --- a/src/pages/event-manage/ui/HostCreationPage.tsx +++ b/src/pages/event/ui/host/HostCreationPage.tsx @@ -1,12 +1,12 @@ -import basicProfile from '../../../../public/assets/event-manage/creation/BasicProfile.svg'; -import addImage from '../../../../public/assets/event-manage/creation/AddImage.svg'; -import DefaultTextField from '../../../../design-system/ui/textFields/DefaultTextField'; -import MultilineTextField from '../../../../design-system/ui/textFields/MultilineTextField'; +import basicProfile from '../../../../../public/assets/event-manage/creation/BasicProfile.svg'; +import addImage from '../../../../../public/assets/event-manage/creation/AddImage.svg'; +import DefaultTextField from '../../../../../design-system/ui/textFields/DefaultTextField'; +import MultilineTextField from '../../../../../design-system/ui/textFields/MultilineTextField'; import { useEffect } from 'react'; -import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext'; +import { useFunnelState } from '../../../../features/event/model/FunnelContext'; import { useForm } from 'react-hook-form'; -import { hostCreationZodValidation } from '../../../shared/lib/formValidation'; -import { HostCreationFormData } from '../../../shared/lib/formValidation'; +import { hostCreationZodValidation } from '../../../../shared/lib/formValidation'; +import { HostCreationFormData } from '../../../../shared/lib/formValidation'; interface HostCreationPageProps { onValidationChange?: (isValid: boolean) => void; diff --git a/src/pages/event-manage/ui/HostSelectionPage.tsx b/src/pages/event/ui/host/HostSelectionPage.tsx similarity index 85% rename from src/pages/event-manage/ui/HostSelectionPage.tsx rename to src/pages/event/ui/host/HostSelectionPage.tsx index 629f6e49..f9b89a4d 100644 --- a/src/pages/event-manage/ui/HostSelectionPage.tsx +++ b/src/pages/event/ui/host/HostSelectionPage.tsx @@ -1,10 +1,10 @@ import { useEffect, useState } from 'react'; -import AddButton from '../../../../public/assets/event-manage/creation/AddBtn.svg'; -import { useFunnelState } from '../../../features/event-manage/event-create/model/FunnelContext'; -import useHostChannelList from '../../../entities/host/hook/useHostChannelListHook'; -import IconButton from '../../../../design-system/ui/buttons/IconButton'; -import CloseButton from '../../../../public/assets/event-manage/creation/CloseBtn.svg'; -import { useHostDeletion } from '../../../features/event-manage/event-create/hooks/useHostHook'; +import AddButton from '../../../../../public/assets/event-manage/creation/AddBtn.svg'; +import { useFunnelState } from '../../../../features/event/model/FunnelContext'; +import useHostChannelList from '../../../../entities/host/hook/useHostChannelListHook'; +import IconButton from '../../../../../design-system/ui/buttons/IconButton'; +import CloseButton from '../../../../../public/assets/event-manage/creation/CloseBtn.svg'; +import { useHostDeletion } from '../../../../features/event/hooks/useHostHook'; interface HostSelectionPageProps { onNext: (nextStep: string) => void; diff --git a/src/pages/search/ui/SearchPage.tsx b/src/pages/search/ui/SearchPage.tsx index ab206680..5588de57 100644 --- a/src/pages/search/ui/SearchPage.tsx +++ b/src/pages/search/ui/SearchPage.tsx @@ -9,8 +9,8 @@ import thirdPage from '../../../../public/assets/banners/3.png'; import EventCard from '../../../shared/ui/EventCard'; import ProfileCircle from '../../../../design-system/ui/Profile'; import useEventList from '../../../entities/event/hook/useEventListHook'; -import type { EventList } from '../../../features/event-manage/event-list/model/eventList'; import useHostChannelList from '../../../entities/host/hook/useHostChannelListHook'; +import { EventList } from '../../../features/event/model/event'; const SearchPage = () => { const [keyword, setKeyword] = useState(''); diff --git a/src/shared/hooks/useInfiniteScroll.ts b/src/shared/hooks/useInfiniteScroll.ts index 020ecfe0..a637725a 100644 --- a/src/shared/hooks/useInfiniteScroll.ts +++ b/src/shared/hooks/useInfiniteScroll.ts @@ -1,5 +1,5 @@ import { useInfiniteQuery } from '@tanstack/react-query'; -import { PaginationParams, EventFilters } from '../../entities/event/model/event'; +import { PaginationParams, EventFilters } from '../../entities/event/model/eventDetail'; interface UseInfiniteScrollProps { queryKey: string[]; diff --git a/src/shared/types/dashboardType.ts b/src/shared/types/dashboardType.ts index 66f31ea8..c8d3f3ee 100644 --- a/src/shared/types/dashboardType.ts +++ b/src/shared/types/dashboardType.ts @@ -17,25 +17,6 @@ import clickedSentEmail from '../../../public/assets/dashboard/menu/SentMail(pin import participants from '../../../public/assets/dashboard/menu/Participants(black).svg'; import clickedParticipants from '../../../public/assets/dashboard/menu/Participants(pink).svg'; -export interface menuListsData { - text: string; - icon: string; - clickedIcon: string; - path: string; -} - -export interface dashboardData { - eventName: string; - eventStartDate: string; - eventStartTime: string; - eventEndDate: string; - eventEndTime: string; - totalTicketCnt: number; - totalPrice: number; - ticket: boolean; - ticketOption: boolean; -} - export const getMenuLists = (id: string | number) => [ { text: '대시보드', icon: dashboard, clickedIcon: clickedDashboard, path: `/dashboard/${id}` }, { text: '이벤트 기본 정보', icon: eventInfo, clickedIcon: clickedEventInfo, path: `/dashboard/${id}/eventInfo` }, diff --git a/src/shared/types/eventCardType.ts b/src/shared/types/eventCardType.ts deleted file mode 100644 index 61d21729..00000000 --- a/src/shared/types/eventCardType.ts +++ /dev/null @@ -1,137 +0,0 @@ -import firstPage from '../../../public/assets/banners/1.png'; -import secondPage from '../../../public/assets/banners/2.png'; -import thirdPage from '../../../public/assets/banners/3.png'; - -export interface trendingEventsData { - id: number; - img: string; - eventTitle: string; - dDay: string; - host: string; - eventDate: string; - location: string; - hashtags: string[]; -} - -export const latestEvents = [ - { - img: firstPage, - eventTitle: '1인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - { - img: secondPage, - eventTitle: '2인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - { - img: thirdPage, - eventTitle: '3인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, -]; - -export const trendingEvents = [ - { - id: 1, - img: firstPage, - eventTitle: 'Tech Conference 2025', - dDay: 'D-3', - host: 'Tech World', - eventDate: '2025-01-20', - location: 'Seoul, Korea', - hashtags: ['#Tech', '#Innovation', '#Conference'], - }, - { - id: 1, - img: secondPage, - eventTitle: 'Startup Meetup', - dDay: 'D-2', - host: 'Startup Hub', - eventDate: '2025-01-27', - location: 'Busan, Korea', - hashtags: ['#Startup', '#Networking', '#Innovation'], - }, - { - id: 2, - img: thirdPage, - eventTitle: 'AI Summit 2025', - dDay: 'D-5', - host: 'AI Korea', - eventDate: '2025-01-22', - location: 'Daegu, Korea', - hashtags: ['#AI', '#MachineLearning', '#Tech'], - }, - { - id: 2, - img: firstPage, - eventTitle: 'Developer Festival', - dDay: 'D-7', - host: 'Dev Korea', - eventDate: '2025-02-01', - location: 'Incheon, Korea', - hashtags: ['#Developer', '#Coding', '#Festival'], - }, - { - id: 3, - img: secondPage, - eventTitle: 'Developer Festival', - dDay: 'D-7', - host: 'Dev Korea', - eventDate: '2025-02-01', - location: 'Incheon, Korea', - hashtags: ['#Developer', '#Coding', '#Festival'], - }, - { - id: 4, - img: thirdPage, - eventTitle: 'Developer Festival', - dDay: 'D-7', - host: 'Dev Korea', - eventDate: '2025-02-01', - location: 'Incheon, Korea', - hashtags: ['#Developer', '#Coding', '#Festival'], - }, -]; - -export const closingSoonEvents = [ - { - img: firstPage, - eventTitle: '1커뮤니티 네트워킹 - Dev MeetUp 2024', - dDay: 'D-6', - host: 'Dev 커뮤니티', - eventDate: '2025년 1월 12일', - location: '판교 스타트업 캠퍼스', - hashtags: ['#네트워킹', '#개발자', '#스타트업', '#기술교류'], - }, - { - img: secondPage, - eventTitle: '2커뮤니티 네트워킹 - Dev MeetUp 2024', - dDay: 'D-6', - host: 'Dev 커뮤니티', - eventDate: '2025년 1월 12일', - location: '판교 스타트업 캠퍼스', - hashtags: ['#네트워킹', '#개발자', '#스타트업', '#기술교류'], - }, - { - img: thirdPage, - eventTitle: '3커뮤니티 네트워킹 - Dev MeetUp 2024', - dDay: 'D-6', - host: 'Dev 커뮤니티', - eventDate: '2025년 1월 12일', - location: '판교 스타트업 캠퍼스', - hashtags: ['#네트워킹', '#개발자', '#스타트업', '#기술교류'], - }, -]; diff --git a/src/shared/types/filterDataType.ts b/src/shared/types/filterDataType.ts deleted file mode 100644 index 3b8e7014..00000000 --- a/src/shared/types/filterDataType.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { trendingEventsData } from '../../shared/types/eventCardType'; -import { hostInfoData } from '../../shared/types/hostInfoType'; -import firstPage from '../../../public/assets/banners/1.png'; -import secondPage from '../../../public/assets/banners/2.png'; -import thirdPage from '../../../public/assets/banners/3.png'; -import { hostInfo } from '../../shared/types/hostInfoType'; - -export interface FilterDataType { - Events: trendingEventsData[]; - Host: hostInfoData[]; -} - -export const FilterMockData: FilterDataType = { - Events: [ - { - id: 1, - img: firstPage, - eventTitle: '1인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - { - id: 2, - img: secondPage, - eventTitle: '2인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - { - id: 3, - img: thirdPage, - eventTitle: '3인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - { - id: 4, - img: firstPage, - eventTitle: '1인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - { - id: 5, - img: secondPage, - eventTitle: '2인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - { - id: 6, - img: thirdPage, - eventTitle: '3인프콘 2024 - INFCON 2024', - dDay: 'D-1', - host: '인프런', - eventDate: '2025년 1월 13일', - location: '올림픽 공원', - hashtags: ['#IT', '#개발자', '#컨퍼런스', '#교육'], - }, - ], - Host: hostInfo, -}; diff --git a/src/shared/types/funnelType.ts b/src/shared/types/funnelType.ts index 35539c4f..08fee7f1 100644 --- a/src/shared/types/funnelType.ts +++ b/src/shared/types/funnelType.ts @@ -1,4 +1,4 @@ -import { FunnelProps, StepProps } from '../../features/event-manage/event-create/hooks/useFunnelHook'; +import { FunnelProps, StepProps } from '../../features/event/hooks/useFunnelHook'; export enum StepNames { HostSelection = 'HostSelection', diff --git a/src/shared/types/hostInfoType.ts b/src/shared/types/hostInfoType.ts deleted file mode 100644 index b526b744..00000000 --- a/src/shared/types/hostInfoType.ts +++ /dev/null @@ -1,76 +0,0 @@ -import phone from '../../../public/assets/event-manage/details/Phone.svg'; -import email from '../../../public/assets/event-manage/details/Email.svg'; - -export interface hostInfoData { - id: number; - nickname?: string; - name: string; - description: string; - phoneImg: string; - phone: string; - emailImg?: string; - email?: string; -} - -export const hostInfo: hostInfoData[] = [ - { - id: 1, - nickname: '예진', - name: '고예진', - description: '먹는거에 진심인 사람들이 모여 숨겨진 맛집을 찾아다니는 모임입니다.', - phoneImg: phone, - phone: '010-1234-5678', - emailImg: email, - email: 'qwer@naver.com', - }, - { - id: 2, - nickname: '유진', - name: '백유진', - description: '여행을 좋아하는 사람들이 모여 새로운 모험을 떠나는 그룹입니다.', - phoneImg: phone, - phone: '010-1234-5678', - emailImg: email, - email: 'qwer@naver.com', - }, - { - id: 3, - nickname: '히은', - name: '조히은', - description: '책을 좋아하는 사람들이 함께 모여 독서를 즐기는 커뮤니티입니다.', - phoneImg: phone, - phone: '010-1234-5678', - emailImg: email, - email: 'qwer@naver.com', - }, - { - id: 4, - nickname: '정준', - name: '민정준', - description: '먹는거에 진심인 사람들이 모여 숨겨진 맛집을 찾아다니는 모임입니다.', - phoneImg: phone, - phone: '010-1234-5678', - emailImg: email, - email: 'qwer@naver.com', - }, - { - id: 5, - nickname: '유진', - name: '백유진', - description: '여행을 좋아하는 사람들이 모여 새로운 모험을 떠나는 그룹입니다.', - phoneImg: phone, - phone: '010-1234-5678', - emailImg: email, - email: 'qwer@naver.com', - }, - { - id: 6, - nickname: '히은', - name: '조히은', - description: '책을 좋아하는 사람들이 함께 모여 독서를 즐기는 커뮤니티입니다.', - phoneImg: phone, - phone: '010-1234-5678', - emailImg: email, - email: 'qwer@naver.com', - }, -]; diff --git a/src/shared/types/mailInfoType.ts b/src/shared/types/mailInfoType.ts deleted file mode 100644 index 682b6d79..00000000 --- a/src/shared/types/mailInfoType.ts +++ /dev/null @@ -1,58 +0,0 @@ -export interface mailInfoData { - id: number; - receiver: string; - title: string; - date: string; - content: string; -} - -export const mailInfo: mailInfoData[] = [ - { - id: 1, - receiver: '전체', - title: '행사 당일 체크인 관련 공지', - date: '2025-03-24T15:00', - content: - '행사 당일 선착순 입장입니다.\n구매하신 티켓을 내 티켓 페이지에 해당 이벤트 정보를 누르면 QR코드를 확인할 수 있습니다.\n입장은 정시에 시작되며 재입장은 불가합니다.\n\n행사 당일 행사장 내에 주차는 불가하며 인근 유로 주차장이나 대중교통을 이용하시길 바랍니다.', - }, - { - id: 2, - receiver: '일반', - title: '행사 당일 체크인 관련 공지', - date: '2025-05-24T12:15', - content: - '행사 당일 선착순 입장입니다.\n구매하신 티켓을 내 티켓 페이지에 해당 이벤트 정보를 누르면 QR코드를 확인할 수 있습니다.\n입장은 정시에 시작되며 재입장은 불가합니다.\n\n행사 당일 행사장 내에 주차는 불가하며 인근 유로 주차장이나 대중교통을 이용하시길 바랍니다.', - }, - { - id: 3, - receiver: '무료', - title: '행사 당일 체크인 관련 공지', - date: '2025-02-11T10:30', - content: - '행사 당일 선착순 입장입니다.\n구매하신 티켓을 내 티켓 페이지에 해당 이벤트 정보를 누르면 QR코드를 확인할 수 있습니다.\n입장은 정시에 시작되며 재입장은 불가합니다.\n\n행사 당일 행사장 내에 주차는 불가하며 인근 유로 주차장이나 대중교통을 이용하시길 바랍니다.', - }, - { - id: 4, - receiver: '일반', - title: '행사 당일 체크인 관련 공지', - date: '2025-01-24T15:45', - content: - '행사 당일 선착순 입장입니다.\n구매하신 티켓을 내 티켓 페이지에 해당 이벤트 정보를 누르면 QR코드를 확인할 수 있습니다.\n입장은 정시에 시작되며 재입장은 불가합니다.\n\n행사 당일 행사장 내에 주차는 불가하며 인근 유로 주차장이나 대중교통을 이용하시길 바랍니다.', - }, - { - id: 5, - receiver: '무료', - title: '행사 당일 체크인 관련 공지', - date: '2025-07-27T09:30', - content: - '행사 당일 선착순 입장입니다.\n구매하신 티켓을 내 티켓 페이지에 해당 이벤트 정보를 누르면 QR코드를 확인할 수 있습니다.\n입장은 정시에 시작되며 재입장은 불가합니다.\n\n행사 당일 행사장 내에 주차는 불가하며 인근 유로 주차장이나 대중교통을 이용하시길 바랍니다.', - }, - { - id: 6, - receiver: '전체', - title: '행사 당일 체크인 관련 공지', - date: '2025-01-14T11:10', - content: - '행사 당일 선착순 입장입니다.\n구매하신 티켓을 내 티켓 페이지에 해당 이벤트 정보를 누르면 QR코드를 확인할 수 있습니다.\n입장은 정시에 시작되며 재입장은 불가합니다.\n\n행사 당일 행사장 내에 주차는 불가하며 인근 유로 주차장이나 대중교통을 이용하시길 바랍니다.', - }, -]; diff --git a/src/shared/types/ticketType.ts b/src/shared/types/ticketType.ts deleted file mode 100644 index 89f7e8cb..00000000 --- a/src/shared/types/ticketType.ts +++ /dev/null @@ -1,51 +0,0 @@ -export interface TicketType { - eventId: number; - ticketType: string; - ticketName: string; - ticketDescription: string; - ticketPrice: number; - availableQuantity: number; - startDate: Date; - endDate: Date; - startTime: string; - endTime: string; -} //일단 스웨거보고 작성 - -export const TicketMockData: TicketType[] = [ - { - eventId: 1, - ticketType: '일반', - ticketName: 'VIP 티켓', - ticketDescription: 'VIP 전용 좌석과 웰컴 패키지가 포함된 티켓입니다.', - ticketPrice: 150000, - availableQuantity: 50, - startDate: new Date('2024-03-01'), - endDate: new Date('2024-03-10'), - startTime: '18:00', - endTime: '22:00', - }, - { - eventId: 2, - ticketType: '무료', - ticketName: '일반 티켓', - ticketDescription: '일반 입장권으로, 자유롭게 행사 참여가 가능합니다.', - ticketPrice: 50000, - availableQuantity: 200, - startDate: new Date('2024-03-01'), - endDate: new Date('2024-03-10'), - startTime: '10:00', - endTime: '20:00', - }, - { - eventId: 3, - ticketType: '할인 티켓', - ticketName: '학생 할인 티켓', - ticketDescription: '학생증 제시 시 할인 적용된 티켓입니다.', - ticketPrice: 30000, - availableQuantity: 100, - startDate: new Date('2024-03-05'), - endDate: new Date('2024-03-10'), - startTime: '12:00', - endTime: '18:00', - }, -]; diff --git a/src/shared/ui/backgrounds/DashboardLayout.tsx b/src/shared/ui/backgrounds/DashboardLayout.tsx index fa2f84b2..fd83ef71 100644 --- a/src/shared/ui/backgrounds/DashboardLayout.tsx +++ b/src/shared/ui/backgrounds/DashboardLayout.tsx @@ -2,7 +2,7 @@ import { useNavigate } from 'react-router-dom'; import Header from '../../../../design-system/ui/Header'; import dashboardMenu from '../../../../public/assets/dashboard/DashboardMenu.svg'; import { useState } from 'react'; -import SideBar from '../../../widgets/dashboard/ui/SideBar'; +import SideBar from '../../../widgets/dashboard/ui/main/SideBar'; interface DashboardLayoutProps { pinkBg?: boolean; diff --git a/src/shared/ui/backgrounds/TicketOptionLayout.tsx b/src/shared/ui/backgrounds/TicketOptionLayout.tsx index 8bc8fd08..32f3507c 100644 --- a/src/shared/ui/backgrounds/TicketOptionLayout.tsx +++ b/src/shared/ui/backgrounds/TicketOptionLayout.tsx @@ -1,95 +1,90 @@ -import { useNavigate } from "react-router-dom"; -import Header from "../../../../design-system/ui/Header"; -import ticket from "../../../../public/assets/dashboard/ticket/Ticket(horizon).svg"; -import Button from "../../../../design-system/ui/Button"; -import active from "../../../../public/assets/payment/Active.svg"; -import inactive from "../../../../public/assets/payment/Inactive.svg"; -import { useTicketOptionStore } from "../../../features/dashboard/model/TicketOptionStore"; +import { useNavigate } from 'react-router-dom'; +import Header from '../../../../design-system/ui/Header'; +import ticket from '../../../../public/assets/dashboard/ticket/Ticket(horizon).svg'; +import Button from '../../../../design-system/ui/Button'; +import active from '../../../../public/assets/payment/Active.svg'; +import inactive from '../../../../public/assets/payment/Inactive.svg'; +import { useTicketOptionStore } from '../../../features/dashboard/model/store/TicketOptionStore'; interface TicketOptionLayoutProps { - children: React.ReactNode; - ticketAmount: number; + children: React.ReactNode; + ticketAmount: number; } const TicketOptionLayout = ({ children, ticketAmount }: TicketOptionLayoutProps) => { - const navigate = useNavigate(); - const {currentPage, setCurrentPage} = useTicketOptionStore(); - const centerContent = `티켓 옵션 선택 (${currentPage}/${ticketAmount})`; + const navigate = useNavigate(); + const { currentPage, setCurrentPage } = useTicketOptionStore(); + const centerContent = `티켓 옵션 선택 (${currentPage}/${ticketAmount})`; - //페이지 - const pageIndicator = Array(ticketAmount).fill(" . "); - pageIndicator[currentPage - 1] = " - "; - - //버튼 텍스트 - const isLastPage = currentPage === ticketAmount; - const buttonText = isLastPage ? "결제하기" : "다음 티켓 옵션 선택하기"; - const handleNextPage = () => { - if (isLastPage) { - {/* 데이터 전송 추가 */} - } else { - setCurrentPage(currentPage + 1); - {/* 데이터 전송 추가 */} - } - }; - return ( -
- {/* 헤더 영역 */} -
-
navigate(-1)} - centerContent={centerContent} - color="white" - /> - {ticketAmount > 1 && ( -
- {Array.from({ length: ticketAmount }, (_, index) => ( - - ))} -
- )} -
- {/* 티켓 정보 영역 */} -
-
-
- ticket logo -
-

콘서트 티켓

-
-
-
-
-

티켓에 대한 설명.티켓에 대한 설명.티켓에 대한 설명.티켓에 대한 설명.티켓에 대티켓에 대한 설명.티켓에 대한 설명.티켓에 대한 설명.티켓에 대한 설명.한 설명.

-
+ //버튼 텍스트 + const isLastPage = currentPage === ticketAmount; + const buttonText = isLastPage ? '결제하기' : '다음 티켓 옵션 선택하기'; + const handleNextPage = () => { + if (isLastPage) { + { + /* 데이터 전송 추가 */ + } + } else { + setCurrentPage(currentPage + 1); + { + /* 데이터 전송 추가 */ + } + } + }; + return ( +
+ {/* 헤더 영역 */} +
+
navigate(-1)} + centerContent={centerContent} + color="white" + /> + {ticketAmount > 1 && ( +
+ {Array.from({ length: ticketAmount }, (_, index) => ( + + ))} +
+ )} +
+ {/* 티켓 정보 영역 */} +
+
+
+ ticket logo +
+

콘서트 티켓

+
+
+
+

+ 티켓에 대한 설명.티켓에 대한 설명.티켓에 대한 설명.티켓에 대한 설명.티켓에 대티켓에 대한 설명.티켓에 대한 + 설명.티켓에 대한 설명.티켓에 대한 설명.한 설명. +

+
+
-
-

추가 옵션

-

- 구매하는 티켓에 추가적으로 선택할 수 있는 옵션들이 있습니다. -

-
+
+

추가 옵션

+

+ 구매하는 티켓에 추가적으로 선택할 수 있는 옵션들이 있습니다. +

+
- {/* 내용 영역 */} -
- {children} -
-
-
-
+ {/* 내용 영역 */} +
+ {children} +
+
+
- ); +
+
+ ); }; export default TicketOptionLayout; diff --git a/src/widgets/dashboard/ui/EmailDeleteModal.tsx b/src/widgets/dashboard/ui/email/EmailDeleteModal.tsx similarity index 75% rename from src/widgets/dashboard/ui/EmailDeleteModal.tsx rename to src/widgets/dashboard/ui/email/EmailDeleteModal.tsx index 905f761e..d4650714 100644 --- a/src/widgets/dashboard/ui/EmailDeleteModal.tsx +++ b/src/widgets/dashboard/ui/email/EmailDeleteModal.tsx @@ -1,5 +1,5 @@ -import TertiaryButton from '../../../../design-system/ui/buttons/TertiaryButton'; -import notice from '../../../../public/assets/dashboard/mail/Notice.svg'; +import TertiaryButton from '../../../../../design-system/ui/buttons/TertiaryButton'; +import notice from '../../../../../public/assets/dashboard/mail/Notice.svg'; interface EmailDeleteMoalProps { mainText: string; @@ -9,7 +9,13 @@ interface EmailDeleteMoalProps { onClick?: () => void; } -const EmailDeleteMoal = ({ onClose, mainText, approveButtonText, rejectButtonText, onClick }: EmailDeleteMoalProps) => { +const EmailDeleteModal = ({ + onClose, + mainText, + approveButtonText, + rejectButtonText, + onClick, +}: EmailDeleteMoalProps) => { return (
@@ -29,4 +35,4 @@ const EmailDeleteMoal = ({ onClose, mainText, approveButtonText, rejectButtonTex
); }; -export default EmailDeleteMoal; +export default EmailDeleteModal; diff --git a/src/widgets/dashboard/ui/EmailModal.tsx b/src/widgets/dashboard/ui/email/EmailModal.tsx similarity index 72% rename from src/widgets/dashboard/ui/EmailModal.tsx rename to src/widgets/dashboard/ui/email/EmailModal.tsx index 9966a3c9..72796135 100644 --- a/src/widgets/dashboard/ui/EmailModal.tsx +++ b/src/widgets/dashboard/ui/email/EmailModal.tsx @@ -1,10 +1,10 @@ import { useParams } from 'react-router-dom'; -import TertiaryButton from '../../../../design-system/ui/buttons/TertiaryButton'; -import { useEmailStore } from '../../../features/dashboard/model/EmailStore'; -import EmailInput from '../../../features/dashboard/ui/EmailInput'; -import { useSendEmail } from '../../../features/dashboard/hook/useEmailHook'; -import TimePicker from '../../../features/event-manage/event-create/ui/TimePicker'; -import { EmailRequest } from '../../../features/dashboard/model/emailInformation'; +import TertiaryButton from '../../../../../design-system/ui/buttons/TertiaryButton'; +import { useEmailStore } from '../../../../features/dashboard/model/store/EmailStore'; +import EmailInput from '../../../../features/dashboard/ui/EmailInput'; +import { useSendEmail } from '../../../../features/dashboard/hook/useEmailHook'; +import TimePicker from '../../../../features/event/ui/TimePicker'; +import { EmailRequest } from '../../../../features/dashboard/model/email'; interface EmailModalProps { onClose: () => void; @@ -15,15 +15,7 @@ const EmailModal = ({ onClose, openSelectTicket, allParticipantEmails }: EmailMo const { id } = useParams(); const { mutate: sendEmail } = useSendEmail(); - const { - title, - content, - recipients, - reservationDate, - setReservationDate, - targetType, - ticketId - } = useEmailStore(); + const { title, content, recipients, reservationDate, setReservationDate, targetType, ticketId } = useEmailStore(); const handleSend = () => { if (!title.trim()) { @@ -49,7 +41,7 @@ const EmailModal = ({ onClose, openSelectTicket, allParticipantEmails }: EmailMo content, recipients, reservationDate, - targetType + targetType, }; if (targetType === 'TICKET') { emailData.ticketId = ticketId; @@ -66,7 +58,9 @@ const EmailModal = ({ onClose, openSelectTicket, allParticipantEmails }: EmailMo allParticipantEmails={allParticipantEmails} /> { setReservationDate(isoString); }} + onChange={isoString => { + setReservationDate(isoString); + }} />
diff --git a/src/widgets/dashboard/ui/SelectTicketModal.tsx b/src/widgets/dashboard/ui/email/SelectTicketModal.tsx similarity index 76% rename from src/widgets/dashboard/ui/SelectTicketModal.tsx rename to src/widgets/dashboard/ui/email/SelectTicketModal.tsx index 79d40212..682aae7b 100644 --- a/src/widgets/dashboard/ui/SelectTicketModal.tsx +++ b/src/widgets/dashboard/ui/email/SelectTicketModal.tsx @@ -1,9 +1,9 @@ import { useParams } from 'react-router-dom'; -import TextButton from '../../../../design-system/ui/buttons/TextButton'; -import SelectTicketInfo from './SelectTicketInfo'; -import { useTickets } from '../../../features/ticket/hooks/useTicketHook'; -import { useEmailStore } from '../../../features/dashboard/model/EmailStore'; -import { usePurchaserEmails } from '../../../features/dashboard/hook/useEmailHook'; +import TextButton from '../../../../../design-system/ui/buttons/TextButton'; +import SelectTicketInfo from '../ticket/SelectTicketInfo'; +import { useTickets } from '../../../../features/ticket/hooks/useTicketHook'; +import { useEmailStore } from '../../../../features/dashboard/model/store/EmailStore'; +import { usePurchaserEmails } from '../../../../features/dashboard/hook/useEmailHook'; interface SelectTicketModalProps { onClose: () => void; @@ -16,13 +16,13 @@ const SelectTicketModal = ({ onClose, openEmailModal }: SelectTicketModalProps) const { data, isLoading } = useTickets(eventId); const tickets = data?.result ?? []; const { setRecipients, setTargetType, setTicketId } = useEmailStore(); - const { mutate:readEmail } = usePurchaserEmails(); + const { mutate: readEmail } = usePurchaserEmails(); const handleClick = (ticketId: number) => { readEmail( { eventId, ticketId }, { - onSuccess: (emails) => { + onSuccess: emails => { setRecipients(emails.email); setTargetType('TICKET'); setTicketId(ticketId); @@ -48,7 +48,7 @@ const SelectTicketModal = ({ onClose, openEmailModal }: SelectTicketModalProps) {isLoading ? (
로딩 중...
) : ( - tickets.map((ticket) => ( + tickets.map(ticket => ( [{mail.targetName}]

{mail.title}

-

{formatDate(mail.reservationDate)} {formatTime(mail.reservationDate)}

+

+ {formatDate(mail.reservationDate)} {formatTime(mail.reservationDate)} +

} @@ -49,20 +51,8 @@ const SentMailCard = ({ mail, isPending = false, onClickDelete }: SentMailCardPr

{mail.content}

{isPending && (
- - + +
)}
diff --git a/src/widgets/dashboard/ui/EventOverview.tsx b/src/widgets/dashboard/ui/main/EventOverview.tsx similarity index 87% rename from src/widgets/dashboard/ui/EventOverview.tsx rename to src/widgets/dashboard/ui/main/EventOverview.tsx index 14c8cfb7..9c245be6 100644 --- a/src/widgets/dashboard/ui/EventOverview.tsx +++ b/src/widgets/dashboard/ui/main/EventOverview.tsx @@ -1,5 +1,5 @@ -import { HostDashboardResponse } from '../../../entities/host/model/hostDashboard'; -import { formatDate, formatTime } from '../../../shared/lib/date'; +import { HostDashboardResponse } from '../../../../entities/host/model/hostDashboard'; +import { formatDate, formatTime } from '../../../../shared/lib/date'; const EventOverview = ({ eventInfo }: { eventInfo?: HostDashboardResponse }) => { return ( diff --git a/src/widgets/dashboard/ui/SideBar.tsx b/src/widgets/dashboard/ui/main/SideBar.tsx similarity index 86% rename from src/widgets/dashboard/ui/SideBar.tsx rename to src/widgets/dashboard/ui/main/SideBar.tsx index 21e068ac..f24d7626 100644 --- a/src/widgets/dashboard/ui/SideBar.tsx +++ b/src/widgets/dashboard/ui/main/SideBar.tsx @@ -1,9 +1,9 @@ import { useState } from 'react'; -import Header from '../../../../design-system/ui/Header'; -import menuBar from '../../../../public/assets/dashboard/menu/MenuBar.svg'; +import menuBar from '../../../../../public/assets/dashboard/menu/MenuBar.svg'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; -import HorizontalCardButton from '../../../../design-system/ui/buttons/HorizontalCardButton'; -import { getMenuLists } from '../../../shared/types/dashboardType'; +import { getMenuLists } from '../../../../shared/types/dashboardType'; +import Header from '../../../../../design-system/ui/Header'; +import HorizontalCardButton from '../../../../../design-system/ui/buttons/HorizontalCardButton'; const SideBar = ({ onClose }: { onClose: () => void }) => { const navigate = useNavigate(); diff --git a/src/widgets/dashboard/ui/TicketRevenue.tsx b/src/widgets/dashboard/ui/main/TicketRevenue.tsx similarity index 100% rename from src/widgets/dashboard/ui/TicketRevenue.tsx rename to src/widgets/dashboard/ui/main/TicketRevenue.tsx diff --git a/src/widgets/dashboard/ui/TicketConfirmPage/PurchaseBanner.tsx b/src/widgets/dashboard/ui/ticket/PurchaseBanner.tsx similarity index 94% rename from src/widgets/dashboard/ui/TicketConfirmPage/PurchaseBanner.tsx rename to src/widgets/dashboard/ui/ticket/PurchaseBanner.tsx index 651a810e..adf9be42 100644 --- a/src/widgets/dashboard/ui/TicketConfirmPage/PurchaseBanner.tsx +++ b/src/widgets/dashboard/ui/ticket/PurchaseBanner.tsx @@ -10,7 +10,7 @@ interface PurchaseBannerPrpos { quantity: number; setIsModalOpen: React.Dispatch>; } -const PurchaseBanner = ({ title,startDate, startTime, ticketName, quantity, setIsModalOpen }: PurchaseBannerPrpos) => { +const PurchaseBanner = ({ title, startDate, startTime, ticketName, quantity, setIsModalOpen }: PurchaseBannerPrpos) => { const navigate = useNavigate(); //@TODO:api연동하면서 props 변경 diff --git a/src/widgets/dashboard/ui/SelectTicketInfo.tsx b/src/widgets/dashboard/ui/ticket/SelectTicketInfo.tsx similarity index 57% rename from src/widgets/dashboard/ui/SelectTicketInfo.tsx rename to src/widgets/dashboard/ui/ticket/SelectTicketInfo.tsx index c569ce4b..f26e0045 100644 --- a/src/widgets/dashboard/ui/SelectTicketInfo.tsx +++ b/src/widgets/dashboard/ui/ticket/SelectTicketInfo.tsx @@ -1,13 +1,13 @@ -import TextButton from '../../../../design-system/ui/buttons/TextButton'; -import ticket from '../../../../public/assets/dashboard/participants-management/Ticket.svg'; -import { ReadTicketResponse } from '../../../features/ticket/model/ticketInformation'; +import TextButton from '../../../../../design-system/ui/buttons/TextButton'; +import ticket from '../../../../../public/assets/dashboard/participants-management/Ticket.svg'; +import { ReadTicketResponse } from '../../../../features/ticket/model/ticket'; interface SelectTicketInfoProps { tickets: ReadTicketResponse; onClick: () => void; } -const SelectTicketInfo = ({ tickets,onClick}: SelectTicketInfoProps) => { +const SelectTicketInfo = ({ tickets, onClick }: SelectTicketInfoProps) => { return (
@@ -16,11 +16,7 @@ const SelectTicketInfo = ({ tickets,onClick}: SelectTicketInfoProps) => {

{tickets.ticketPrice}원

- +
); diff --git a/src/widgets/dashboard/ui/TicketItem.tsx b/src/widgets/dashboard/ui/ticket/TicketItem.tsx similarity index 76% rename from src/widgets/dashboard/ui/TicketItem.tsx rename to src/widgets/dashboard/ui/ticket/TicketItem.tsx index 750057d9..879c2699 100644 --- a/src/widgets/dashboard/ui/TicketItem.tsx +++ b/src/widgets/dashboard/ui/ticket/TicketItem.tsx @@ -1,13 +1,13 @@ -import AvailableTicket from '../../../../public/assets/dashboard/ticket/Ticket(gray).svg'; -import PersonIcon from '../../../../public/assets/dashboard/ticket/PersonIcon.svg'; -import { motion } from "framer-motion"; +import AvailableTicket from '../../../../../public/assets/dashboard/ticket/Ticket(gray).svg'; +import PersonIcon from '../../../../../public/assets/dashboard/ticket/PersonIcon.svg'; +import { motion } from 'framer-motion'; import { useState } from 'react'; -import { ReadTicketResponse } from '../../../features/ticket/model/ticketInformation'; -import { useDeleteTicket } from '../../../features/ticket/hooks/useTicketHook'; +import { ReadTicketResponse } from '../../../../features/ticket/model/ticket'; +import { useDeleteTicket } from '../../../../features/ticket/hooks/useTicketHook'; const TicketItem = ({ ticket }: { ticket: ReadTicketResponse }) => { const [isDragging, setIsDragging] = useState(false); - const { mutate: handleDelete} = useDeleteTicket(); + const { mutate: handleDelete } = useDeleteTicket(); return (
{ }} >
-

{ticket.ticketPrice > 0 ? "일반" : "무료"}

+

{ticket.ticketPrice > 0 ? '일반' : '무료'}

{ticket.ticketName}

@@ -48,7 +48,6 @@ const TicketItem = ({ ticket }: { ticket: ReadTicketResponse }) => { > 삭제 -
); }; diff --git a/src/widgets/event/ui/TicketInfo.tsx b/src/widgets/event/ui/TicketInfo.tsx index b9fa9157..3a025495 100644 --- a/src/widgets/event/ui/TicketInfo.tsx +++ b/src/widgets/event/ui/TicketInfo.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import TertiaryButton from '../../../../design-system/ui/buttons/TertiaryButton'; import TextButton from '../../../../design-system/ui/buttons/TextButton'; -import { OrderTicketRequest } from '../../../features/ticket/model/OrderCreation'; +import { OrderTicketRequest } from '../../../features/ticket/model/order'; import { orderTickets } from '../../../features/ticket/api/order'; import { useNavigate } from 'react-router-dom'; import { useTickets } from '../../../features/ticket/hooks/useTicketHook'; @@ -46,18 +46,17 @@ const TicketInfo = ({ eventId }: { eventId: number }) => { const response = await orderTickets(requestData); - console.log("API 응답:", response); + console.log('API 응답:', response); if (response.isSuccess && Array.isArray(response.result)) { const orderIds = response.result; navigate('/payment/ticket-confirm', { state: { orderIds, ticketId, eventId } }); } else { - alert("주문 정보를 불러올 수 없습니다."); + alert('주문 정보를 불러올 수 없습니다.'); } - } catch (error) { - alert("티켓 구매 중 오류가 발생했습니다."); + alert('티켓 구매 중 오류가 발생했습니다.'); } }; if (isLoading) return
Loading...
; @@ -93,7 +92,14 @@ const TicketInfo = ({ eventId }: { eventId: number }) => { className="flex justify-center items-center bg-white w-6 h-6 md:w-7 md:h-7" />
- orderTicket(ticket.ticketId, eventId, quantity[ticket.ticketId])} /> + orderTicket(ticket.ticketId, eventId, quantity[ticket.ticketId])} + />
diff --git a/yarn.lock b/yarn.lock index 30161929..271963e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -978,17 +978,17 @@ resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.69.0.tgz#c434505987ade936dc53e6e27aa1406b0295516f" integrity sha512-Kn410jq6vs1P8Nm+ZsRj9H+U3C0kjuEkYLxbiCyn3MDEiYor1j2DGVULqAz62SLZtUZ/e9Xt6xMXiJ3NJ65WyQ== -"@tanstack/query-devtools@5.74.7": - version "5.74.7" - resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.74.7.tgz#c9b022b386ac86e6395228b5d6912e6444b3b971" - integrity sha512-nSNlfuGdnHf4yB0S+BoNYOE1o3oAH093weAYZolIHfS2stulyA/gWfSk/9H4ZFk5mAAHb5vNqAeJOmbdcGPEQw== +"@tanstack/query-devtools@5.76.0": + version "5.76.0" + resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.76.0.tgz#ba43754ed8d23a265ed72f17de618fa9f9c7649d" + integrity sha512-1p92nqOBPYVqVDU0Ua5nzHenC6EGZNrLnB2OZphYw8CNA1exuvI97FVgIKON7Uug3uQqvH/QY8suUKpQo8qHNQ== -"@tanstack/react-query-devtools@^5.75.7": - version "5.75.7" - resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.75.7.tgz#3d50ff93d2aff0de236f53aaca7bbed1ae82908d" - integrity sha512-VUzHvxcUAz7oSeX/TlVyDgNxajLAF+b12Z3OfSxCrAdWynELfWohwzCn1iT2NEjnGTb3X3ryzQxeWuWMyMwCmQ== +"@tanstack/react-query-devtools@^5.76.1": + version "5.76.1" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.76.1.tgz#20157a5880df5fd4d4fe8fd4fca2c8663d8dfa3e" + integrity sha512-LFVWgk/VtXPkerNLfYIeuGHh0Aim/k9PFGA+JxLdRaUiroQ4j4eoEqBrUpQ1Pd/KXoG4AB9vVE/M6PUQ9vwxBQ== dependencies: - "@tanstack/query-devtools" "5.74.7" + "@tanstack/query-devtools" "5.76.0" "@tanstack/react-query@^5.61.3": version "5.69.0"