From 88ca959ce3af455eb45c227d65a9c8b287efc114 Mon Sep 17 00:00:00 2001 From: giho Date: Mon, 15 Jul 2024 02:03:45 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20organisms=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Content/ChannelContainer.hook.tsx | 11 ++ .../Organisms/Content/ChannelContainer.tsx | 31 ++-- .../Organisms/Content/ChannelItem.tsx | 14 +- .../Organisms/Content/ChannelItem.type.tsx | 5 + .../Modal/CreateChannelModal.hook.tsx | 133 ++++++++++++++++ .../Organisms/Modal/CreateChannelModal.tsx | 143 ++++-------------- .../Organisms/Modal/CreateMusicModal.hook.tsx | 42 +++++ .../Organisms/Modal/CreateMusicModal.tsx | 41 ++--- .../Modal/DeleteChannelModal.hook.tsx | 27 ++++ .../Organisms/Modal/DeleteChannelModal.tsx | 22 ++- .../Organisms/Modal/DeleteMusicModal.hook.tsx | 24 +++ .../Organisms/Modal/DeleteMusicModal.tsx | 23 +-- .../Organisms/Modal/EditMusicModal.hook.tsx | 47 ++++++ .../Modal/EditMusicModal.hook.type.tsx | 5 + .../Organisms/Modal/EditMusicModal.tsx | 50 ++---- src/types/music.ts | 2 +- tsconfig.json | 7 +- webpack.config.js | 13 ++ 18 files changed, 399 insertions(+), 241 deletions(-) create mode 100644 src/components/Organisms/Content/ChannelContainer.hook.tsx create mode 100644 src/components/Organisms/Content/ChannelItem.type.tsx create mode 100644 src/components/Organisms/Modal/CreateChannelModal.hook.tsx create mode 100644 src/components/Organisms/Modal/CreateMusicModal.hook.tsx create mode 100644 src/components/Organisms/Modal/DeleteChannelModal.hook.tsx create mode 100644 src/components/Organisms/Modal/DeleteMusicModal.hook.tsx create mode 100644 src/components/Organisms/Modal/EditMusicModal.hook.tsx create mode 100644 src/components/Organisms/Modal/EditMusicModal.hook.type.tsx diff --git a/src/components/Organisms/Content/ChannelContainer.hook.tsx b/src/components/Organisms/Content/ChannelContainer.hook.tsx new file mode 100644 index 0000000..17679bb --- /dev/null +++ b/src/components/Organisms/Content/ChannelContainer.hook.tsx @@ -0,0 +1,11 @@ +import useGetAllChannels from '@/apis/hooks/useGetAllChannels'; + +export default function useChannelContainer() { + const { data: channels, isLoading, isError } = useGetAllChannels(); + + return { + channels, + isLoading, + isError, + }; +} diff --git a/src/components/Organisms/Content/ChannelContainer.tsx b/src/components/Organisms/Content/ChannelContainer.tsx index 6bdd789..6c92692 100644 --- a/src/components/Organisms/Content/ChannelContainer.tsx +++ b/src/components/Organisms/Content/ChannelContainer.tsx @@ -1,32 +1,29 @@ +// libraries import styled from 'styled-components'; + +// hooks +import useChannelContainer from './ChannelContainer.hook'; + +// components import ChannelItem from './ChannelItem'; -import { useEffect, useState } from 'react'; -import { Channel } from '../../../types/channel'; import MainTitle from '../../Atoms/Text/MainTitle'; -import useGetAllChannels from '../../../apis/hooks/useGetAllChannels'; export default function ChannelContainer() { - const [channels, setChannels] = useState(null); - const { data } = useGetAllChannels(); + // logics + const { channels, isLoading, isError } = useChannelContainer(); - useEffect(() => { - if (data) { - setChannels(data); - } - }, [data]); - - if (!channels) { + // view + if (isLoading) { return
Loading...
; } + if (isError) { + return
Error...
; + } return ( Channel List - - {channels.map((channel) => ( - - ))} - + {channels?.map((channel) => )} ); } diff --git a/src/components/Organisms/Content/ChannelItem.tsx b/src/components/Organisms/Content/ChannelItem.tsx index 02db08a..ae32c9b 100644 --- a/src/components/Organisms/Content/ChannelItem.tsx +++ b/src/components/Organisms/Content/ChannelItem.tsx @@ -1,14 +1,16 @@ +// libraries import styled from 'styled-components'; -import { Channel } from '../../../types/channel'; + +// components import { Link } from 'react-router-dom'; +import TagContainer from '../../Molecules/Content/TagContainer'; + +// types +import { ChannelItemProps } from './ChannelItem.type'; +// images import mockImage from '../../../images/dummyImage.png'; import personSvg from '../../../images/svg/person.svg'; -import TagContainer from '../../Molecules/Content/TagContainer'; - -interface ChannelItemProps { - channel: Channel; -} export default function ChannelItem({ channel }: ChannelItemProps) { return ( diff --git a/src/components/Organisms/Content/ChannelItem.type.tsx b/src/components/Organisms/Content/ChannelItem.type.tsx new file mode 100644 index 0000000..b128a14 --- /dev/null +++ b/src/components/Organisms/Content/ChannelItem.type.tsx @@ -0,0 +1,5 @@ +import { Channel } from '@/types/channel'; + +export interface ChannelItemProps { + channel: Channel; +} diff --git a/src/components/Organisms/Modal/CreateChannelModal.hook.tsx b/src/components/Organisms/Modal/CreateChannelModal.hook.tsx new file mode 100644 index 0000000..23c92e0 --- /dev/null +++ b/src/components/Organisms/Modal/CreateChannelModal.hook.tsx @@ -0,0 +1,133 @@ +// hooks +import { useRef, useState } from 'react'; +import { useUserStore } from '@/store/useUserStore'; +import useCreateChannel from '@/apis/hooks/useCreateChannel'; +import useModalStore from '@/store/useModalStore'; + +// types +import { ModalType } from '@/types/enum'; + +export default function useCreateChannelModal() { + const { type, closeModal } = useModalStore(); + + if (type !== ModalType.CREATE_CHANNEL) return null; + + const { user } = useUserStore(); + const [channelData, setChannelData] = useState({ + name: '', + tags: [] as string[], + description: '', + image: '', + }); + const [tagValue, setTagValue] = useState(''); + const [previewChannelImageUrl, setPreviewChannelImageUrl] = useState(null); + const fileInputRef = useRef(null); + const [profileImageFile, setProfileImageFile] = useState(null); + const uploadCreateChannel = useCreateChannel(); + + const handleChannelImageClick = (e: React.MouseEvent) => { + e.preventDefault(); + if (fileInputRef.current) { + fileInputRef.current.click(); + } + }; + + const handleFileChange = (e: React.ChangeEvent) => { + // 이전 파일 제거 + setPreviewChannelImageUrl(null); + setProfileImageFile(null); + + if (!e.target.files) return; + const file = e.target.files?.[0]; + setProfileImageFile(file); + + // 파일 미리보기 + const fileUrl = URL.createObjectURL(file); + setPreviewChannelImageUrl(fileUrl); + }; + + const handleAddTagKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + e.preventDefault(); + if (tagValue.trim() === '') { + return console.log('태그를 입력하세요.'); + } + if (tagValue.length > 10) { + return console.log('태그는 10자 이내로 입력하세요.'); + } + if (channelData.tags.length > 5) { + return console.log('태그는 5개까지만 입력할 수 있습니다.'); + } + if (channelData.tags.includes(tagValue)) { + return console.log('이미 입력된 태그입니다.'); + } + + setChannelData({ + ...channelData, + tags: [...channelData.tags, tagValue], + }); + setTagValue(''); + } + }; + + const handleDeleteTag = (tag: string) => { + setChannelData({ + ...channelData, + tags: channelData.tags.filter((t) => t !== tag), + }); + }; + + const handleChangeChannelData = (e: React.ChangeEvent) => { + setChannelData({ + ...channelData, + [e.target.name]: e.target.value, + }); + }; + + const handleChangeTagValue = (e: React.ChangeEvent) => { + setTagValue(e.target.value); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + createChannel(); + closeModal(); + setChannelData({ + name: '', + tags: [], + description: '', + image: '', + }); + }; + + const createChannel = async () => { + const newChannel = new FormData(); + if (channelData) { + newChannel.append('name', channelData.name); + // FormData의 경우 배열을 받을 수 없기 때문에 JSON.stringify를 사용하여 문자열로 변환하여 전송 + // 이후 서버에서 JSON.parse를 통해 배열로 변환하고 사용 + newChannel.append('tags', JSON.stringify(channelData.tags)); + newChannel.append('description', channelData.description); + newChannel.append('ownerId', user?.id || ''); + } + if (profileImageFile) { + newChannel.append('image', profileImageFile); + } + uploadCreateChannel.mutate({ channel: newChannel }); + }; + + return { + channelData, + tagValue, + previewChannelImageUrl, + fileInputRef, + handleChangeChannelData, + handleChangeTagValue, + handleChannelImageClick, + handleFileChange, + handleAddTagKeyDown, + handleDeleteTag, + handleSubmit, + closeModal, + }; +} diff --git a/src/components/Organisms/Modal/CreateChannelModal.tsx b/src/components/Organisms/Modal/CreateChannelModal.tsx index 5147ccd..e05fd24 100644 --- a/src/components/Organisms/Modal/CreateChannelModal.tsx +++ b/src/components/Organisms/Modal/CreateChannelModal.tsx @@ -1,6 +1,12 @@ +// libraries +import styled from 'styled-components'; + +// hooks +import useCreateChannelModal from './CreateChannelModal.hook'; + +// components import Dimmed from '../../Atoms/Modal/Dimmed'; import Button from '../../Atoms/Modal/Button'; -import { useRef, useState } from 'react'; import { Wrapper, Form, @@ -13,121 +19,30 @@ import { TagContainer, Tag, } from '../../Atoms/Modal/StyledComponents'; -import { useUserStore } from '../../../store/useUserStore'; -import useModalStore from '../../../store/useModalStore'; -import { ModalType } from '../../../types/enum'; -import styled from 'styled-components'; -import useCreateChannel from '../../../apis/hooks/useCreateChannel'; export default function CreateChannelModal() { - const { type, closeModal } = useModalStore(); - - if (type !== ModalType.CREATE_CHANNEL) return null; - - const { user } = useUserStore(); - const [channelData, setChannelData] = useState({ - name: '', - tags: [] as string[], - description: '', - image: '', - }); - const [tagValue, setTagValue] = useState(''); - const [previewChannelImageUrl, setPreviewChannelImageUrl] = useState(null); - const fileInputRef = useRef(null); - const [profileImageFile, setProfileImageFile] = useState(null); - const uploadCreateChannel = useCreateChannel(); - - const handleChannelImageClick = (e: React.MouseEvent) => { - e.preventDefault(); - if (fileInputRef.current) { - fileInputRef.current.click(); - } - }; - - const handleFileChange = (e: React.ChangeEvent) => { - // 이전 파일 제거 - setPreviewChannelImageUrl(null); - setProfileImageFile(null); - - if (!e.target.files) return; - const file = e.target.files?.[0]; - setProfileImageFile(file); - - // 파일 미리보기 - const fileUrl = URL.createObjectURL(file); - setPreviewChannelImageUrl(fileUrl); - }; - - const handleAddTagKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - e.preventDefault(); - if (tagValue.trim() === '') { - return console.log('태그를 입력하세요.'); - } - if (tagValue.length > 10) { - return console.log('태그는 10자 이내로 입력하세요.'); - } - if (channelData.tags.length > 5) { - return console.log('태그는 5개까지만 입력할 수 있습니다.'); - } - if (channelData.tags.includes(tagValue)) { - return console.log('이미 입력된 태그입니다.'); - } - - setChannelData({ - ...channelData, - tags: [...channelData.tags, tagValue], - }); - setTagValue(''); - } - }; - - const handleDeleteTag = (tag: string) => { - setChannelData({ - ...channelData, - tags: channelData.tags.filter((t) => t !== tag), - }); - }; - - const handleChangeChannelData = (e: React.ChangeEvent) => { - setChannelData({ - ...channelData, - [e.target.name]: e.target.value, - }); - }; - - const handleChangeTagValue = (e: React.ChangeEvent) => { - setTagValue(e.target.value); - }; - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - createChannel(); - closeModal(); - setChannelData({ - name: '', - tags: [], - description: '', - image: '', - }); - }; - - const createChannel = async () => { - const newChannel = new FormData(); - if (channelData) { - newChannel.append('name', channelData.name); - // FormData의 경우 배열을 받을 수 없기 때문에 JSON.stringify를 사용하여 문자열로 변환하여 전송 - // 이후 서버에서 JSON.parse를 통해 배열로 변환하고 사용 - newChannel.append('tags', JSON.stringify(channelData.tags)); - newChannel.append('description', channelData.description); - newChannel.append('ownerId', user?.id || ''); - } - if (profileImageFile) { - newChannel.append('image', profileImageFile); - } - uploadCreateChannel.mutate({ channel: newChannel }); - }; - + // logics + const hookData = useCreateChannelModal(); + + // useCreateChannelModal hook에서 null을 반환할 수 있으므로 null 체크 + if (!hookData) return null; + + const { + channelData, + tagValue, + previewChannelImageUrl, + fileInputRef, + handleChannelImageClick, + handleFileChange, + handleChangeChannelData, + handleChangeTagValue, + handleAddTagKeyDown, + handleDeleteTag, + handleSubmit, + closeModal, + } = hookData; + + // view return ( diff --git a/src/components/Organisms/Modal/CreateMusicModal.hook.tsx b/src/components/Organisms/Modal/CreateMusicModal.hook.tsx new file mode 100644 index 0000000..3008e0e --- /dev/null +++ b/src/components/Organisms/Modal/CreateMusicModal.hook.tsx @@ -0,0 +1,42 @@ +// hooks +import { useState } from 'react'; +import useCreateMusic from '@/apis/hooks/useCreateMusic'; +import useModalStore from '@/store/useModalStore'; + +// types +import { ModalType } from '@/types/enum'; + +export default function useCreateMusicModal() { + const { type, closeModal, props } = useModalStore(); + + if (type !== ModalType.CREATE_MUSIC) return null; + + const upLoadMusicMutation = useCreateMusic(); + const modalProps = props as { channelId: string }; + const [musicData, setMusicData] = useState({ + title: '', + artist: '', + url: '', + }); + + const handleChange = (e: React.ChangeEvent) => { + setMusicData({ + ...musicData, + [e.target.name]: e.target.value, + }); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const music = { + channelId: modalProps.channelId, + title: musicData.title, + artist: musicData.artist, + url: musicData.url, + }; + upLoadMusicMutation.mutate({ music }); + closeModal(); + }; + + return { musicData, handleChange, handleSubmit, closeModal }; +} diff --git a/src/components/Organisms/Modal/CreateMusicModal.tsx b/src/components/Organisms/Modal/CreateMusicModal.tsx index 08df1e5..3d58b26 100644 --- a/src/components/Organisms/Modal/CreateMusicModal.tsx +++ b/src/components/Organisms/Modal/CreateMusicModal.tsx @@ -1,5 +1,8 @@ +// hooks +import useCreateMusicModal from './CreateMusicModal.hook'; + +// components import Button from '../../Atoms/Modal/Button'; -import { useState } from 'react'; import Dimmed from '../../Atoms/Modal/Dimmed'; import { FormField, @@ -11,42 +14,16 @@ import { Description, ButtonWrapper, } from '../../Atoms/Modal/StyledComponents'; -import useModalStore from '../../../store/useModalStore'; -import { ModalType } from '../../../types/enum'; -import useCreateMusic from '../../../apis/hooks/useCreateMusic'; export default function CreateMusicModal() { - const { type, closeModal, props } = useModalStore(); - - if (type !== ModalType.CREATE_MUSIC) return null; - - const upLoadMusicMutation = useCreateMusic(); - const modalProps = props as { channelId: string }; - const [musicData, setMusicData] = useState({ - title: '', - artist: '', - url: '', - }); + // logics + const Logics = useCreateMusicModal(); - const handleChange = (e: React.ChangeEvent) => { - setMusicData({ - ...musicData, - [e.target.name]: e.target.value, - }); - }; + if (!Logics) return null; - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - const music = { - channelId: modalProps.channelId, - title: musicData.title, - artist: musicData.artist, - url: musicData.url, - }; - upLoadMusicMutation.mutate({ music }); - closeModal(); - }; + const { musicData, handleChange, handleSubmit, closeModal } = Logics; + // view return ( diff --git a/src/components/Organisms/Modal/DeleteChannelModal.hook.tsx b/src/components/Organisms/Modal/DeleteChannelModal.hook.tsx new file mode 100644 index 0000000..9ca236f --- /dev/null +++ b/src/components/Organisms/Modal/DeleteChannelModal.hook.tsx @@ -0,0 +1,27 @@ +// hooks +import useDeleteChannel from '@/apis/hooks/useDeleteChannel'; +import useModalStore from '@/store/useModalStore'; + +// types +import { ModalType } from '@/types/enum'; + +export default function useDeleteChannelModal() { + const { type, closeModal, props } = useModalStore(); + + if (type !== ModalType.DELETE_CHANNEL) return null; + + const modalProps = props as { channelId: string; channelName: string }; + const upLoadDeleteChannelMutation = useDeleteChannel(); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + upLoadDeleteChannelMutation.mutate({ channelId: modalProps.channelId }); + closeModal(); + }; + + return { + handleSubmit, + closeModal, + modalProps, + }; +} diff --git a/src/components/Organisms/Modal/DeleteChannelModal.tsx b/src/components/Organisms/Modal/DeleteChannelModal.tsx index ffe6a41..e7393a7 100644 --- a/src/components/Organisms/Modal/DeleteChannelModal.tsx +++ b/src/components/Organisms/Modal/DeleteChannelModal.tsx @@ -1,24 +1,20 @@ +// hooks +import useDeleteChannelModal from './DeleteChannelModal.hook'; + +// components import Dimmed from '../../Atoms/Modal/Dimmed'; import { ButtonWrapper, Description, Form, Title, Wrapper } from '../../Atoms/Modal/StyledComponents'; import Button from '../../Atoms/Modal/Button'; -import useModalStore from '../../../store/useModalStore'; -import { ModalType } from '../../../types/enum'; -import useDeleteChannel from '../../../apis/hooks/useDeleteChannel'; export default function DeleteChannelModal() { - const { type, closeModal, props } = useModalStore(); - - if (type !== ModalType.DELETE_CHANNEL) return null; + // logics + const logics = useDeleteChannelModal(); - const modalProps = props as { channelId: string; channelName: string }; - const upLoadDeleteChannelMutation = useDeleteChannel(); + if (!logics) return null; - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - upLoadDeleteChannelMutation.mutate({ channelId: modalProps.channelId }); - closeModal(); - }; + const { handleSubmit, closeModal, modalProps } = logics; + // view return ( diff --git a/src/components/Organisms/Modal/DeleteMusicModal.hook.tsx b/src/components/Organisms/Modal/DeleteMusicModal.hook.tsx new file mode 100644 index 0000000..e408d4b --- /dev/null +++ b/src/components/Organisms/Modal/DeleteMusicModal.hook.tsx @@ -0,0 +1,24 @@ +// hooks +import useDeleteMusic from '@/apis/hooks/useDeleteMusic'; +import useModalStore from '@/store/useModalStore'; + +// types +import { ModalType } from '@/types/enum'; +import { Music } from '@/types/music'; + +export default function useDeleteMusicModal() { + const { type, closeModal, props } = useModalStore(); + + if (type !== ModalType.DELETE_MUSIC) return null; + + const modalProps = props as { music: Music }; + + const upLoadDeleteMusicMutation = useDeleteMusic(); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + upLoadDeleteMusicMutation.mutate(modalProps.music.id); + closeModal(); + }; + return { handleSubmit, closeModal, modalProps }; +} diff --git a/src/components/Organisms/Modal/DeleteMusicModal.tsx b/src/components/Organisms/Modal/DeleteMusicModal.tsx index debc39d..bf46dc8 100644 --- a/src/components/Organisms/Modal/DeleteMusicModal.tsx +++ b/src/components/Organisms/Modal/DeleteMusicModal.tsx @@ -1,27 +1,18 @@ import Dimmed from '../../Atoms/Modal/Dimmed'; import { ButtonWrapper, Description, Form, Title, Wrapper } from '../../Atoms/Modal/StyledComponents'; import Button from '../../Atoms/Modal/Button'; -import useModalStore from '../../../store/useModalStore'; -import { Music } from '@prisma/client'; -import { ModalType } from '../../../types/enum'; -import useDeleteMusic from '../../../apis/hooks/useDeleteMusic'; -export default function DeleteMusicModal() { - const { type, closeModal, props } = useModalStore(); - - if (type !== ModalType.DELETE_MUSIC) return null; +import useDeleteMusicModal from './DeleteMusicModal.hook'; - const modalProps = props as { music: Music }; +export default function DeleteMusicModal() { + // logics + const logics = useDeleteMusicModal(); - const upLoadDeleteMusicMutation = useDeleteMusic(); + if (!logics) return null; - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - // Call API to delete music - upLoadDeleteMusicMutation.mutate(modalProps.music.id); - closeModal(); - }; + const { handleSubmit, closeModal, modalProps } = logics; + // view return ( diff --git a/src/components/Organisms/Modal/EditMusicModal.hook.tsx b/src/components/Organisms/Modal/EditMusicModal.hook.tsx new file mode 100644 index 0000000..863a185 --- /dev/null +++ b/src/components/Organisms/Modal/EditMusicModal.hook.tsx @@ -0,0 +1,47 @@ +// hooks +import { useState } from 'react'; +import { useParams } from 'react-router-dom'; +import useUpdateMusic from '@/apis/hooks/useUpdateMusic'; +import useModalStore from '@/store/useModalStore'; + +// types +import { ModalType } from '@/types/enum'; +import { EditMusicModalProps } from './EditMusicModal.hook.type'; + +export default function useEditMusicModal() { + const { type, closeModal, props } = useModalStore(); + + if (type !== ModalType.EDIT_MUSIC) return null; + + const modalProps = props as EditMusicModalProps; + + const upLoadUpdateMusicMutation = useUpdateMusic(); + const { channelId } = useParams<{ channelId: string }>(); + const [musicData, setMusicData] = useState({ + title: modalProps.music.title, + artist: modalProps.music.artist, + url: modalProps.music.url, + }); + + const handleChange = (e: React.ChangeEvent) => { + setMusicData({ + ...musicData, + [e.target.name]: e.target.value, + }); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + // Call API to update music + const edittedMusic = { + channelId: channelId, + title: musicData.title, + artist: musicData.artist, + url: musicData.url, + }; + upLoadUpdateMusicMutation.mutate({ musicId: modalProps.music.id, music: edittedMusic }); + closeModal(); + }; + + return { musicData, handleChange, handleSubmit, closeModal }; +} diff --git a/src/components/Organisms/Modal/EditMusicModal.hook.type.tsx b/src/components/Organisms/Modal/EditMusicModal.hook.type.tsx new file mode 100644 index 0000000..25c3500 --- /dev/null +++ b/src/components/Organisms/Modal/EditMusicModal.hook.type.tsx @@ -0,0 +1,5 @@ +import { Music } from '@/types/music'; + +export interface EditMusicModalProps { + music: Music; +} diff --git a/src/components/Organisms/Modal/EditMusicModal.tsx b/src/components/Organisms/Modal/EditMusicModal.tsx index 2948e53..2b10265 100644 --- a/src/components/Organisms/Modal/EditMusicModal.tsx +++ b/src/components/Organisms/Modal/EditMusicModal.tsx @@ -1,52 +1,20 @@ -import { useState } from 'react'; -import useModalStore from '../../../store/useModalStore'; +// hooks +import useEditMusicModal from './EditMusicModal.hook'; + +// components import Button from '../../Atoms/Modal/Button'; import Dimmed from '../../Atoms/Modal/Dimmed'; import { ButtonWrapper, Form, FormField, Input, Label, Title, Wrapper } from '../../Atoms/Modal/StyledComponents'; -import { useParams } from 'react-router-dom'; -import { Music } from '@prisma/client'; -import { ModalType } from '../../../types/enum'; -import useUpdateMusic from '../../../apis/hooks/useUpdateMusic'; - -interface EditMusicModalProps { - music: Music; -} export default function EditMusicModal() { - const { type, closeModal, props } = useModalStore(); - - if (type !== ModalType.EDIT_MUSIC) return null; - - const modalProps = props as EditMusicModalProps; - - const upLoadUpdateMusicMutation = useUpdateMusic(); - const { channelId } = useParams<{ channelId: string }>(); - const [musicData, setMusicData] = useState({ - title: modalProps.music.title, - artist: modalProps.music.artist, - url: modalProps.music.url, - }); + // logics + const logics = useEditMusicModal(); - const handleChange = (e: React.ChangeEvent) => { - setMusicData({ - ...musicData, - [e.target.name]: e.target.value, - }); - }; + if (!logics) return null; - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - // Call API to update music - const edittedMusic = { - channelId: channelId, - title: musicData.title, - artist: musicData.artist, - url: musicData.url, - }; - upLoadUpdateMusicMutation.mutate({ musicId: modalProps.music.id, music: edittedMusic }); - closeModal(); - }; + const { musicData, handleChange, handleSubmit, closeModal } = logics; + // view return ( diff --git a/src/types/music.ts b/src/types/music.ts index ae2448d..49c8f78 100644 --- a/src/types/music.ts +++ b/src/types/music.ts @@ -1,5 +1,5 @@ export interface Music { - id: number; + id: string; title: string; artist: string; url: string; diff --git a/tsconfig.json b/tsconfig.json index 1cf3c13..e6a12b1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,7 +25,12 @@ "@/styles/*": ["src/styles/*"], "@/types/*": ["src/types/*"], "@/utils/*": ["src/utils/*"] - } + }, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "incremental": true }, "include": ["src", "src/styles", "utils", "custom.d.ts"] } diff --git a/webpack.config.js b/webpack.config.js index e473d05..b66102a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -36,6 +36,19 @@ module.exports = { }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'], + alias: { + '@': path.resolve(__dirname, 'src'), + '@/apis': path.resolve(__dirname, 'src/apis'), + '@/components': path.resolve(__dirname, 'src/components'), + '@/images': path.resolve(__dirname, 'src/images'), + '@/mocks': path.resolve(__dirname, 'src/mocks'), + '@/pages': path.resolve(__dirname, 'src/pages'), + '@/router': path.resolve(__dirname, 'src/router'), + '@/store': path.resolve(__dirname, 'src/store'), + '@/styles': path.resolve(__dirname, 'src/styles'), + '@/types': path.resolve(__dirname, 'src/types'), + '@/utils': path.resolve(__dirname, 'src/utils'), + }, }, plugins: [ new HtmlWebpackPlugin({