From 4c5cc8ab2924afd872ba1edc5474ffb73872844c Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 14:46:27 +0900 Subject: [PATCH 1/9] =?UTF-8?q?chore:=20=EB=A6=AC=EC=95=A1=ED=8A=B8=20?= =?UTF-8?q?=ED=9B=85=20=ED=8F=BC=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 1 + yarn.lock | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/frontend/package.json b/frontend/package.json index 154fc67c..010df8d3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,6 +25,7 @@ "nanoid": "^5.0.8", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.53.2", "react-router-dom": "^6.27.0", "socket.io-client": "^4.8.1", "styled-components": "^6.1.13", diff --git a/yarn.lock b/yarn.lock index f1704702..10a5bdff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6665,6 +6665,7 @@ __metadata: nanoid: "npm:^5.0.8" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" + react-hook-form: "npm:^7.53.2" react-router-dom: "npm:^6.27.0" socket.io-client: "npm:^4.8.1" styled-components: "npm:^6.1.13" @@ -9612,6 +9613,15 @@ __metadata: languageName: node linkType: hard +"react-hook-form@npm:^7.53.2": + version: 7.53.2 + resolution: "react-hook-form@npm:7.53.2" + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + checksum: 10c0/18336d8e8798a70dcd0af703a0becca2d5dbf82a7b7a3ca334ae0e1f26410490bc3ef2ea51adcf790bb1e7006ed7a763fd00d664e398f71225b23529a7ccf0bf + languageName: node + linkType: hard + "react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" From 1a265bb5053132ccdb5437d80163faf3e44ea1e7 Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 14:47:17 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EB=B0=A9=EC=86=A1=20=EC=A0=9C?= =?UTF-8?q?=EB=AA=A9=20=ED=95=84=EB=93=9C=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F?= =?UTF-8?q?=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/host/Form/LiveTitleField.tsx | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 frontend/src/components/host/Form/LiveTitleField.tsx diff --git a/frontend/src/components/host/Form/LiveTitleField.tsx b/frontend/src/components/host/Form/LiveTitleField.tsx new file mode 100644 index 00000000..0b93eee7 --- /dev/null +++ b/frontend/src/components/host/Form/LiveTitleField.tsx @@ -0,0 +1,27 @@ +import { Controller, useFormContext } from 'react-hook-form'; +import { Bold, CharCount, FormCell, Input, Label, Required } from './style'; +import { FormValues } from './types'; + +export default function LiveTitleField() { + const { control } = useFormContext(); + + return ( + + + ( + <> + + + {field.value?.length || 0}/100 + + + )} + /> + + ); +} From f6601fec5db894f83d2249bbaf3d6663fedeecc0 Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 14:48:08 +0900 Subject: [PATCH 3/9] =?UTF-8?q?chore:=20=ED=8F=BC=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/host/Form/style.tsx | 177 ++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 frontend/src/components/host/Form/style.tsx diff --git a/frontend/src/components/host/Form/style.tsx b/frontend/src/components/host/Form/style.tsx new file mode 100644 index 00000000..0362992c --- /dev/null +++ b/frontend/src/components/host/Form/style.tsx @@ -0,0 +1,177 @@ +import styled from 'styled-components'; + +export const Flex = styled.div` + display: flex; + gap: 20px; + + input { + flex: 1; + } +`; + +export const FormCell = styled.div` + display: flex; + flex-direction: column; + gap: 10px; +`; + +export const Label = styled.label` + font-size: 14px; + color: #525662; + margin-bottom: 8px; +`; + +export const Required = styled.em` + color: #e63a3e; + margin-left: 4px; +`; + +export const CharCount = styled.span` + font-size: 12px; + color: #9da5b6; + margin-top: 4px; + align-self: flex-end; +`; + +export const Bold = styled.span` + font-weight: bold; + color: #000; +`; + +export const Input = styled.input` + padding: 10px; + border: 1px solid #dddddd; + border-radius: 4px; + font-size: 14px; + outline: none; + &:focus { + border-color: #4e41db; + } +`; + +export const ImageUpload = styled.div` + display: flex; + flex-direction: column; + gap: 10px; + width: 300px; +`; + +export const FileInputLabel = styled.label` + cursor: pointer; + width: 100%; +`; + +export const FileInput = styled.input` + display: none; +`; + +export const PreviewImage = styled.img` + width: 100%; + max-width: 300px; + border-radius: 4px; + border: 1px solid #dddddd; +`; + +export const PlaceholderImage = styled.div` + width: 100%; + height: 180px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + border: 1px dashed #dddddd; + border-radius: 4px; + background-color: #f5f6f8; +`; + +export const UploadIcon = styled.svg` + width: 24px; + height: 24px; + margin-bottom: 8px; +`; + +export const UploadText = styled.span` + font-family: 'NanumGothic', sans-serif; + font-size: 12px; + color: #9da5b6; +`; + +export const Button = styled.button` + padding: 12px; + background-color: rgba(78, 65, 219, 0.1); + color: rgba(78, 65, 219, 0.8); + border: none; + border-radius: 7px; + font-size: 16px; + cursor: pointer; + &:hover { + background-color: rgba(78, 65, 219, 0.2); + } +`; + +export const TagContainer = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; +`; + +export const TagChipContainer = styled.span` + display: inline-flex; + align-items: center; + padding: 4px 12px; + background-color: #f3f4f6; + border-radius: 9999px; + font-size: 14px; + transition: background-color 0.2s ease; + + &:hover { + background-color: #e5e7eb; + } +`; + +export const RemoveButton = styled.button` + margin-left: 8px; + color: #6b7280; + font-size: 16px; + cursor: pointer; + transition: color 0.2s ease; + background: none; + border: none; + padding: 0 4px; + line-height: 1; + + &:hover { + color: #374151; + } + + &:focus { + outline: none; + } +`; + +export const ImageContainer = styled.div` + position: relative; +`; + +export const ImageActionButtons = styled.div` + display: flex; + gap: 8px; + margin-top: 8px; +`; + +export const ImageButton = styled.button` + flex: 1; + padding: 8px; + background-color: #f3f4f6; + border: none; + border-radius: 4px; + color: #4e41db; + font-size: 14px; + cursor: pointer; + text-align: center; + transition: background-color 0.2s ease; + + &:hover { + background-color: #e5e7eb; + } +`; From a7a16b85d92ce2e7c3e4e4950d454bde8c20463e Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 15:13:19 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20=ED=8F=BC=20=EC=9D=B8=ED=92=8B=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=ED=9B=85=ED=8F=BC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/host/Form/CategoryField.tsx | 18 ++++ .../components/host/Form/HostNameField.tsx | 22 +++++ .../src/components/host/Form/ImageField.tsx | 84 +++++++++++++++++++ .../src/components/host/Form/NoticeField.tsx | 18 ++++ .../src/components/host/Form/TagField.tsx | 81 ++++++++++++++++++ frontend/src/components/host/Form/index.ts | 8 ++ frontend/src/components/host/Form/types.ts | 9 ++ 7 files changed, 240 insertions(+) create mode 100644 frontend/src/components/host/Form/CategoryField.tsx create mode 100644 frontend/src/components/host/Form/HostNameField.tsx create mode 100644 frontend/src/components/host/Form/ImageField.tsx create mode 100644 frontend/src/components/host/Form/NoticeField.tsx create mode 100644 frontend/src/components/host/Form/TagField.tsx create mode 100644 frontend/src/components/host/Form/index.ts create mode 100644 frontend/src/components/host/Form/types.ts diff --git a/frontend/src/components/host/Form/CategoryField.tsx b/frontend/src/components/host/Form/CategoryField.tsx new file mode 100644 index 00000000..d1a7985c --- /dev/null +++ b/frontend/src/components/host/Form/CategoryField.tsx @@ -0,0 +1,18 @@ +import { Controller, useFormContext } from 'react-hook-form'; +import { FormValues } from './types'; +import { FormCell, Input, Label } from './style'; + +export default function CategoryField() { + const { control } = useFormContext(); + + return ( + + + } + /> + + ); +} diff --git a/frontend/src/components/host/Form/HostNameField.tsx b/frontend/src/components/host/Form/HostNameField.tsx new file mode 100644 index 00000000..0cb18674 --- /dev/null +++ b/frontend/src/components/host/Form/HostNameField.tsx @@ -0,0 +1,22 @@ +import { Controller, useFormContext } from 'react-hook-form'; +import { FormCell, Input, Label, Required } from './style'; +import { FormValues } from './types'; + +export default function HostNameField() { + const { control } = useFormContext(); + + return ( + + + ( + + )} + /> + + ); +} diff --git a/frontend/src/components/host/Form/ImageField.tsx b/frontend/src/components/host/Form/ImageField.tsx new file mode 100644 index 00000000..384aae90 --- /dev/null +++ b/frontend/src/components/host/Form/ImageField.tsx @@ -0,0 +1,84 @@ +import { useCallback, useRef } from 'react'; +import { useFormContext, useWatch } from 'react-hook-form'; +import { FormValues } from './types'; +import { convertToBase64 } from '@utils/convertToBase64'; +import { + FileInput, + FileInputLabel, + FormCell, + ImageActionButtons, + ImageButton, + ImageContainer, + ImageUpload, + Label, + PlaceholderImage, + PreviewImage, + UploadIcon, + UploadText +} from './style'; + +export default function ImageField() { + const fileInputRef = useRef(null); + const { control, setValue } = useFormContext(); + const previewImage = useWatch({ + control, + name: 'previewImage', + defaultValue: null + }); + + const handleImageChange = useCallback( + async (e: React.ChangeEvent): Promise => { + const files = e.target.files; + if (!files) return; + + const base64 = await convertToBase64(files[0]); + setValue('previewImage', base64); + }, + [setValue] + ); + + const handleImageDelete = useCallback(() => { + setValue('previewImage', null); + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + }, [setValue]); + + return ( + + + + {previewImage ? ( + + + + + 수정 + + + 삭제 + + + + ) : ( + + + + + + + 업로드 (1280x720) + + + )} + + + + ); +} diff --git a/frontend/src/components/host/Form/NoticeField.tsx b/frontend/src/components/host/Form/NoticeField.tsx new file mode 100644 index 00000000..83ce6cf1 --- /dev/null +++ b/frontend/src/components/host/Form/NoticeField.tsx @@ -0,0 +1,18 @@ +import { Controller, useFormContext } from 'react-hook-form'; +import { FormValues } from './types'; +import { FormCell, Input, Label } from './style'; + +export default function NoticeField() { + const { control } = useFormContext(); + + return ( + + + } + /> + + ); +} diff --git a/frontend/src/components/host/Form/TagField.tsx b/frontend/src/components/host/Form/TagField.tsx new file mode 100644 index 00000000..41c523e1 --- /dev/null +++ b/frontend/src/components/host/Form/TagField.tsx @@ -0,0 +1,81 @@ +import { Controller, useFormContext } from 'react-hook-form'; +import { FormValues } from './types'; +import { + Button, + Flex, + FormCell, + Input, + Label, + RemoveButton, + TagChipContainer, + TagContainer, + UploadText +} from './style'; +import { KeyboardEvent } from 'react'; + +export default function TagField() { + const { control, setValue, getValues } = useFormContext(); + + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Enter') { + e.preventDefault(); + onAddTag(); + } + }; + + const onAddTag = () => { + const currentTag = getValues('tag').trim(); + if (currentTag) { + const currentTags = getValues('tags'); + setValue('tags', [...currentTags, currentTag]); + setValue('tag', ''); + } + }; + + const onRemoveTag = (indexToRemove: number) => { + const currentTags = getValues('tags'); + setValue( + 'tags', + currentTags.filter((_, index) => index !== indexToRemove) + ); + }; + + return ( + + + + } + /> + + + ( + <>{field.value.length > 0 && } + )} + /> + 공백 및 특수 문자 없이 15자까지 입력할 수 있습니다. + + ); +} + +const TagChip = ({ tag, onRemove }: { tag: string; onRemove: () => void }) => ( + + {tag} + × + +); + +const TagList = ({ tags, onRemoveTag }: { tags: string[]; onRemoveTag: (index: number) => void }) => ( + + {tags.map((tag, index) => ( + onRemoveTag(index)} /> + ))} + +); diff --git a/frontend/src/components/host/Form/index.ts b/frontend/src/components/host/Form/index.ts new file mode 100644 index 00000000..49bbe831 --- /dev/null +++ b/frontend/src/components/host/Form/index.ts @@ -0,0 +1,8 @@ +export { default as LiveTitleField } from './LiveTitleField'; +export { default as CategoryField } from './CategoryField'; +export { default as TagField } from './TagField'; +export { default as NoticeField } from './NoticeField'; +export { default as ImageField } from './ImageField'; +export { default as HostNameField } from './HostNameField'; + +export type { FormValues } from './types'; diff --git a/frontend/src/components/host/Form/types.ts b/frontend/src/components/host/Form/types.ts new file mode 100644 index 00000000..245f6dc6 --- /dev/null +++ b/frontend/src/components/host/Form/types.ts @@ -0,0 +1,9 @@ +export interface FormValues { + liveTitle: string; + category: string; + tag: string; + tags: string[]; + notice: string; + hostName: string; + previewImage: string | null; +} From d20e15d4937e15a9784988cb2f3c59b2728e1e14 Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 15:13:41 +0900 Subject: [PATCH 5/9] =?UTF-8?q?fix:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20api=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/updateHost.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/apis/updateHost.ts b/frontend/src/apis/updateHost.ts index 65cfcd40..58954e5c 100644 --- a/frontend/src/apis/updateHost.ts +++ b/frontend/src/apis/updateHost.ts @@ -4,6 +4,8 @@ import { fetchInstance } from '.'; export interface HostInfo { userId: string; liveTitle: string; + hostName: string; + notice: string; defaultThumbnailImageUrl: string; category: string; tags: string[]; From bc073ed4a8b3b0bbf82f8e0161dd3797f0228063 Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 15:14:04 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20=ED=9B=85=ED=8F=BC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=EC=9C=BC=EB=A1=9C=20=EB=A0=8C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/host/SettingForm.tsx | 334 ++----------------- 1 file changed, 30 insertions(+), 304 deletions(-) diff --git a/frontend/src/components/host/SettingForm.tsx b/frontend/src/components/host/SettingForm.tsx index 30612835..d6ce3aca 100644 --- a/frontend/src/components/host/SettingForm.tsx +++ b/frontend/src/components/host/SettingForm.tsx @@ -1,147 +1,49 @@ +import { useForm, FormProvider } from 'react-hook-form'; import styled from 'styled-components'; -import { ChangeEvent, useRef, useState } from 'react'; import useUpdateHost from '@apis/queries/host/useUpdateHost'; import { getStoredId } from '@utils/id'; -import { convertToBase64 } from '@utils/convertToBase64'; +import { CategoryField, FormValues, HostNameField, ImageField, LiveTitleField, NoticeField, TagField } from './Form'; +import { Button } from './Form/style'; export default function SettingForm() { - const fileInputRef = useRef(null); const { mutate: updateHost } = useUpdateHost(); + const methods = useForm({ + defaultValues: { + liveTitle: '', + category: '', + tag: '', + tags: [], + notice: '', + previewImage: null + } + }); - const [liveTitle, setLiveTitle] = useState(''); - const [category, setCategory] = useState(''); - const [tag, setTag] = useState(''); - const [tags, setTags] = useState([]); - const [notice, setNotice] = useState(''); - const [previewImage, setPreviewImage] = useState(null); - - const onRemoveTag = (indexToRemove: number) => { - setTags((prev) => prev.filter((_, index) => index !== indexToRemove)); - }; - - const handleImageChange = async (e: ChangeEvent): Promise => { - const files = e.target.files; - if (!files) return; - - const base64 = await convertToBase64(files[0]); - setPreviewImage(base64); - }; - - const handleUpdate = () => { + const onSubmit = ({ liveTitle, category, previewImage, tags, hostName, notice }: FormValues) => { updateHost({ userId: getStoredId(), liveTitle, category, + hostName, + notice, defaultThumbnailImageUrl: previewImage || '', tags }); }; - const handleImageDelete = () => { - setPreviewImage(null); - - if (fileInputRef.current) { - fileInputRef.current.value = ''; - } - }; - return ( - - - - - setLiveTitle(e.target.value)} - placeholder="방송 제목을 입력해주세요." - maxLength={100} - /> - - {liveTitle.length} - /100 - - - - - setCategory(e.target.value)} - placeholder="카테고리 검색" - /> - - - - - setTag(e.target.value)} placeholder="태그 추가하기" /> - - - {tags.length > 0 && ( - - {tags.map((tag, index) => ( - - {tag} - onRemoveTag(index)}>× - - ))} - - )} - 공백 및 특수 문자 없이 15자까지 입력할 수 있습니다. - - - - setNotice(e.target.value)} placeholder="공지 추가하기" /> - - - - - - {previewImage ? ( - - - - - 수정 - - - 삭제 - - - - ) : ( - - - - - - - 업로드 (1280x720) - - - )} - - - - - - - + + + + + + + + + + + + + ); } @@ -152,184 +54,8 @@ const Container = styled.div` box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); `; -const Flex = styled.div` - display: flex; - gap: 20px; - - input { - flex: 1; - } -`; - -const FormArea = styled.div` +const FormArea = styled.form` display: flex; flex-direction: column; gap: 20px; `; - -const FormCell = styled.div` - display: flex; - flex-direction: column; - gap: 10px; -`; - -const Label = styled.label` - font-size: 14px; - color: #525662; - margin-bottom: 8px; -`; - -const Required = styled.em` - color: #e63a3e; - margin-left: 4px; -`; - -const Input = styled.input` - padding: 10px; - border: 1px solid #dddddd; - border-radius: 4px; - font-size: 14px; - outline: none; - &:focus { - border-color: #4e41db; - } -`; - -const CharCount = styled.span` - font-size: 12px; - color: #9da5b6; - margin-top: 4px; - align-self: flex-end; -`; - -const Bold = styled.span` - font-weight: bold; - color: #000; -`; - -const ImageUpload = styled.div` - display: flex; - flex-direction: column; - gap: 10px; - width: 300px; -`; - -const FileInputLabel = styled.label` - cursor: pointer; - width: 100%; -`; - -const FileInput = styled.input` - display: none; -`; - -const PreviewImage = styled.img` - width: 100%; - max-width: 300px; - border-radius: 4px; - border: 1px solid #dddddd; -`; - -const PlaceholderImage = styled.div` - width: 100%; - height: 180px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - border: 1px dashed #dddddd; - border-radius: 4px; - background-color: #f5f6f8; -`; - -const UploadIcon = styled.svg` - width: 24px; - height: 24px; - margin-bottom: 8px; -`; - -const UploadText = styled.span` - font-family: 'NanumGothic', sans-serif; - font-size: 12px; - color: #9da5b6; -`; - -const Button = styled.button` - padding: 12px; - background-color: rgba(78, 65, 219, 0.1); - color: rgba(78, 65, 219, 0.8); - border: none; - border-radius: 7px; - font-size: 16px; - cursor: pointer; - &:hover { - background-color: rgba(78, 65, 219, 0.2); - } -`; - -const TagContainer = styled.div` - display: flex; - flex-wrap: wrap; - gap: 8px; -`; - -const TagChip = styled.span` - display: inline-flex; - align-items: center; - padding: 4px 12px; - background-color: #f3f4f6; - border-radius: 9999px; - font-size: 14px; - transition: background-color 0.2s ease; - - &:hover { - background-color: #e5e7eb; - } -`; - -const RemoveButton = styled.button` - margin-left: 8px; - color: #6b7280; - font-size: 16px; - cursor: pointer; - transition: color 0.2s ease; - background: none; - border: none; - padding: 0 4px; - line-height: 1; - - &:hover { - color: #374151; - } - - &:focus { - outline: none; - } -`; - -const ImageContainer = styled.div` - position: relative; -`; - -const ImageActionButtons = styled.div` - display: flex; - gap: 8px; - margin-top: 8px; -`; - -const ImageButton = styled.button` - flex: 1; - padding: 8px; - background-color: #f3f4f6; - border: none; - border-radius: 4px; - color: #4e41db; - font-size: 14px; - cursor: pointer; - text-align: center; - transition: background-color 0.2s ease; - - &:hover { - background-color: #e5e7eb; - } -`; From 4dce3b0782e6b313d7c0206a0686dd65049ddce2 Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 15:56:17 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20=ED=95=9C=EA=B8=80=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=8B=9C=20=EB=91=90=20=EB=B2=88=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EB=90=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/host/Form/TagField.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/host/Form/TagField.tsx b/frontend/src/components/host/Form/TagField.tsx index 41c523e1..b42ed842 100644 --- a/frontend/src/components/host/Form/TagField.tsx +++ b/frontend/src/components/host/Form/TagField.tsx @@ -17,7 +17,7 @@ export default function TagField() { const { control, setValue, getValues } = useFormContext(); const onKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Enter') { + if (e.key === 'Enter' && !e.nativeEvent.isComposing) { e.preventDefault(); onAddTag(); } From 6093bb8292c501b1a49906fcd1c694124f264dda Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 16:40:37 +0900 Subject: [PATCH 8/9] =?UTF-8?q?fix:=20=ED=98=B8=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=8F=BC=20=ED=83=80=EC=9E=85=20=ED=8F=B4=EB=8D=94=EB=A1=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/apis/queries/host/useUpdateHost.ts | 3 ++- frontend/src/apis/updateHost.ts | 11 +---------- frontend/src/components/host/Form/index.ts | 2 -- frontend/src/components/host/Form/types.ts | 9 --------- frontend/src/components/host/SettingForm.tsx | 3 ++- frontend/src/type/hostInfo.ts | 19 +++++++++++++++++++ 6 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 frontend/src/components/host/Form/types.ts create mode 100644 frontend/src/type/hostInfo.ts diff --git a/frontend/src/apis/queries/host/useUpdateHost.ts b/frontend/src/apis/queries/host/useUpdateHost.ts index 8a1f52b9..794bf297 100644 --- a/frontend/src/apis/queries/host/useUpdateHost.ts +++ b/frontend/src/apis/queries/host/useUpdateHost.ts @@ -1,5 +1,6 @@ -import { HostInfo, updateHost } from '@apis/updateHost'; +import { updateHost } from '@apis/updateHost'; import { useMutation, UseMutationResult } from '@tanstack/react-query'; +import { HostInfo } from '@type/hostInfo'; type Params = { onSuccess?: (data: HostInfo) => void; diff --git a/frontend/src/apis/updateHost.ts b/frontend/src/apis/updateHost.ts index 58954e5c..4bb4c350 100644 --- a/frontend/src/apis/updateHost.ts +++ b/frontend/src/apis/updateHost.ts @@ -1,15 +1,6 @@ import { AxiosResponse } from 'axios'; import { fetchInstance } from '.'; - -export interface HostInfo { - userId: string; - liveTitle: string; - hostName: string; - notice: string; - defaultThumbnailImageUrl: string; - category: string; - tags: string[]; -} +import { HostInfo } from '@type/hostInfo'; export const updateHost = async (hostInfo: HostInfo): Promise => { const response: AxiosResponse = await fetchInstance().post('/host/update', hostInfo); diff --git a/frontend/src/components/host/Form/index.ts b/frontend/src/components/host/Form/index.ts index 49bbe831..2fa4a02a 100644 --- a/frontend/src/components/host/Form/index.ts +++ b/frontend/src/components/host/Form/index.ts @@ -4,5 +4,3 @@ export { default as TagField } from './TagField'; export { default as NoticeField } from './NoticeField'; export { default as ImageField } from './ImageField'; export { default as HostNameField } from './HostNameField'; - -export type { FormValues } from './types'; diff --git a/frontend/src/components/host/Form/types.ts b/frontend/src/components/host/Form/types.ts deleted file mode 100644 index 245f6dc6..00000000 --- a/frontend/src/components/host/Form/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface FormValues { - liveTitle: string; - category: string; - tag: string; - tags: string[]; - notice: string; - hostName: string; - previewImage: string | null; -} diff --git a/frontend/src/components/host/SettingForm.tsx b/frontend/src/components/host/SettingForm.tsx index d6ce3aca..24b4eba2 100644 --- a/frontend/src/components/host/SettingForm.tsx +++ b/frontend/src/components/host/SettingForm.tsx @@ -2,8 +2,9 @@ import { useForm, FormProvider } from 'react-hook-form'; import styled from 'styled-components'; import useUpdateHost from '@apis/queries/host/useUpdateHost'; import { getStoredId } from '@utils/id'; -import { CategoryField, FormValues, HostNameField, ImageField, LiveTitleField, NoticeField, TagField } from './Form'; +import { CategoryField, HostNameField, ImageField, LiveTitleField, NoticeField, TagField } from './Form'; import { Button } from './Form/style'; +import { FormValues } from '@type/hostInfo'; export default function SettingForm() { const { mutate: updateHost } = useUpdateHost(); diff --git a/frontend/src/type/hostInfo.ts b/frontend/src/type/hostInfo.ts new file mode 100644 index 00000000..6581042f --- /dev/null +++ b/frontend/src/type/hostInfo.ts @@ -0,0 +1,19 @@ +export interface HostInfo { + userId: string; + liveTitle: string; + hostName: string; + notice: string; + defaultThumbnailImageUrl: string; + category: string; + tags: string[]; +} + +export interface FormValues { + liveTitle: string; + category: string; + tag: string; + tags: string[]; + notice: string; + hostName: string; + previewImage: string | null; +} From 0f1c5a5713298d6606076ae93ac04585aae98614 Mon Sep 17 00:00:00 2001 From: jisu-kim Date: Thu, 21 Nov 2024 16:46:07 +0900 Subject: [PATCH 9/9] =?UTF-8?q?fix:=20=ED=83=80=EC=9E=85=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/host/Form/CategoryField.tsx | 2 +- frontend/src/components/host/Form/HostNameField.tsx | 2 +- frontend/src/components/host/Form/ImageField.tsx | 2 +- frontend/src/components/host/Form/LiveTitleField.tsx | 2 +- frontend/src/components/host/Form/NoticeField.tsx | 2 +- frontend/src/components/host/Form/TagField.tsx | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/host/Form/CategoryField.tsx b/frontend/src/components/host/Form/CategoryField.tsx index d1a7985c..19b543a4 100644 --- a/frontend/src/components/host/Form/CategoryField.tsx +++ b/frontend/src/components/host/Form/CategoryField.tsx @@ -1,6 +1,6 @@ import { Controller, useFormContext } from 'react-hook-form'; -import { FormValues } from './types'; import { FormCell, Input, Label } from './style'; +import { FormValues } from '@type/hostInfo'; export default function CategoryField() { const { control } = useFormContext(); diff --git a/frontend/src/components/host/Form/HostNameField.tsx b/frontend/src/components/host/Form/HostNameField.tsx index 0cb18674..fbc73542 100644 --- a/frontend/src/components/host/Form/HostNameField.tsx +++ b/frontend/src/components/host/Form/HostNameField.tsx @@ -1,6 +1,6 @@ import { Controller, useFormContext } from 'react-hook-form'; import { FormCell, Input, Label, Required } from './style'; -import { FormValues } from './types'; +import { FormValues } from '@type/hostInfo'; export default function HostNameField() { const { control } = useFormContext(); diff --git a/frontend/src/components/host/Form/ImageField.tsx b/frontend/src/components/host/Form/ImageField.tsx index 384aae90..75034d57 100644 --- a/frontend/src/components/host/Form/ImageField.tsx +++ b/frontend/src/components/host/Form/ImageField.tsx @@ -1,6 +1,6 @@ import { useCallback, useRef } from 'react'; import { useFormContext, useWatch } from 'react-hook-form'; -import { FormValues } from './types'; +import { FormValues } from '@type/hostInfo'; import { convertToBase64 } from '@utils/convertToBase64'; import { FileInput, diff --git a/frontend/src/components/host/Form/LiveTitleField.tsx b/frontend/src/components/host/Form/LiveTitleField.tsx index 0b93eee7..240b6a75 100644 --- a/frontend/src/components/host/Form/LiveTitleField.tsx +++ b/frontend/src/components/host/Form/LiveTitleField.tsx @@ -1,6 +1,6 @@ import { Controller, useFormContext } from 'react-hook-form'; import { Bold, CharCount, FormCell, Input, Label, Required } from './style'; -import { FormValues } from './types'; +import { FormValues } from '@type/hostInfo'; export default function LiveTitleField() { const { control } = useFormContext(); diff --git a/frontend/src/components/host/Form/NoticeField.tsx b/frontend/src/components/host/Form/NoticeField.tsx index 83ce6cf1..9d86bb49 100644 --- a/frontend/src/components/host/Form/NoticeField.tsx +++ b/frontend/src/components/host/Form/NoticeField.tsx @@ -1,5 +1,5 @@ import { Controller, useFormContext } from 'react-hook-form'; -import { FormValues } from './types'; +import { FormValues } from '@type/hostInfo'; import { FormCell, Input, Label } from './style'; export default function NoticeField() { diff --git a/frontend/src/components/host/Form/TagField.tsx b/frontend/src/components/host/Form/TagField.tsx index b42ed842..d4799f0b 100644 --- a/frontend/src/components/host/Form/TagField.tsx +++ b/frontend/src/components/host/Form/TagField.tsx @@ -1,5 +1,5 @@ import { Controller, useFormContext } from 'react-hook-form'; -import { FormValues } from './types'; +import { FormValues } from '@type/hostInfo'; import { Button, Flex, @@ -36,7 +36,7 @@ export default function TagField() { const currentTags = getValues('tags'); setValue( 'tags', - currentTags.filter((_, index) => index !== indexToRemove) + currentTags.filter((_: string, index: number) => index !== indexToRemove) ); };