From b26fb3749cbed273d346362338a1a011e6b96252 Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Mon, 28 Oct 2024 04:52:25 +0900 Subject: [PATCH 01/25] =?UTF-8?q?feat:=20=EA=B3=B5=EB=8F=99=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=EC=9E=A5=20=EA=B8=B0=EB=B3=B8=20=ED=8B=80=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/make/index.tsx | 5 + src/components/form/FormController/index.tsx | 2 +- .../form/Presentation/CoLeader/index.tsx | 141 ++++++++++++++++++ src/components/form/Presentation/index.tsx | 18 ++- src/types/form.ts | 1 + 5 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 src/components/form/Presentation/CoLeader/index.tsx diff --git a/pages/make/index.tsx b/pages/make/index.tsx index ec3853cd..c4dc1986 100644 --- a/pages/make/index.tsx +++ b/pages/make/index.tsx @@ -22,6 +22,11 @@ const MakePage = () => { const formMethods = useForm({ mode: 'onChange', resolver: zodResolver(schema), + defaultValues: { + detail: { + coLeader: [], + }, + }, }); const { isValid } = formMethods.formState; const { mutateAsync: mutateCreateMeeting, isLoading: isSubmitting } = useMutation({ diff --git a/src/components/form/FormController/index.tsx b/src/components/form/FormController/index.tsx index 13ebda13..70151c31 100644 --- a/src/components/form/FormController/index.tsx +++ b/src/components/form/FormController/index.tsx @@ -5,7 +5,7 @@ import { Option } from '../Select/OptionItem'; interface FormControllerProps { name: string; render: ControllerProps['render']; - defaultValue?: boolean | string | number | Option | Option[]; + defaultValue?: boolean | string | number | Option | Option[] | string[]; } function FormController({ name, render, defaultValue }: FormControllerProps) { diff --git a/src/components/form/Presentation/CoLeader/index.tsx b/src/components/form/Presentation/CoLeader/index.tsx new file mode 100644 index 00000000..13b7bf2b --- /dev/null +++ b/src/components/form/Presentation/CoLeader/index.tsx @@ -0,0 +1,141 @@ +import { styled } from 'stitches.config'; +import React, { useState } from 'react'; + +interface CoLeaderFieldProps { + value: string[]; + onChange: (coLeaders: string[]) => void; + error: string | undefined; +} + +const CoLeader = ({ value: coLeaders = [], onChange, error }: CoLeaderFieldProps) => { + //const [coLeaders, setCoLeaders] = useState([]); + const [newLeader, setNewLeader] = useState(''); + + const handleAddLeader = () => { + if (newLeader && coLeaders.length < 3) { + onChange([...coLeaders, newLeader]); + setNewLeader(''); + } + }; + + const handleDeleteLeader = (index: number) => { + const updatedLeaders = coLeaders.filter((_, i) => i !== index); + onChange(updatedLeaders); + }; + + return ( + + + {coLeaders.map((leader, idx) => ( + + πŸ‘€ + {leader} + handleDeleteLeader(idx)}>Γ— + + ))} + {coLeaders.length < 3 && ( + + setNewLeader(e.target.value)} + /> + + μΆ”κ°€ + + + )} + + + {error && {error}} + + ); +}; + +export default CoLeader; + +const Container = styled('div', { + border: '1px solid $gray700', + padding: '16px', + borderRadius: '8px', + backgroundColor: '$gray800', +}); + +const LeadersContainer = styled('div', { + display: 'flex', + alignItems: 'center', + gap: '12px', +}); + +const Leader = styled('div', { + display: 'flex', + alignItems: 'center', + backgroundColor: '$gray600', + borderRadius: '4px', + padding: '4px 8px', + color: '$white', + position: 'relative', +}); + +const LeaderAvatar = styled('span', { + fontSize: '20px', + marginRight: '6px', +}); + +const LeaderName = styled('span', { + fontSize: '14px', + color: '$white', +}); + +const DeleteButton = styled('button', { + background: 'none', + border: 'none', + color: '$red500', + fontSize: '14px', + cursor: 'pointer', + position: 'absolute', + top: '0', + right: '0', + padding: '2px 4px', +}); + +const AddLeader = styled('div', { + display: 'flex', + alignItems: 'center', + gap: '8px', +}); + +const AddInput = styled('input', { + width: '120px', + padding: '4px 8px', + borderRadius: '4px', + border: '1px solid $gray700', + backgroundColor: '$gray900', + color: '$white', + outline: 'none', + + '&::placeholder': { + color: '$gray500', + }, +}); + +const AddButton = styled('button', { + type: 'button', //이거 μ—†μœΌλ©΄ 제좜 처리됨!! + padding: '4px 8px', + backgroundColor: '$green500', + color: '$white', + border: 'none', + borderRadius: '4px', + cursor: 'pointer', + + '&:hover': { + backgroundColor: '$green400', + }, +}); + +const ErrorMessage = styled('div', { + color: '$red500', + fontSize: '12px', + marginTop: '8px', +}); diff --git a/src/components/form/Presentation/index.tsx b/src/components/form/Presentation/index.tsx index f90eab35..fb3dc7e9 100644 --- a/src/components/form/Presentation/index.tsx +++ b/src/components/form/Presentation/index.tsx @@ -26,6 +26,7 @@ import { useDialog } from '@sopt-makers/ui'; import sopt_schedule_tooltip from 'public/assets/images/sopt_schedule_tooltip.png'; import BubblePointIcon from 'public/assets/svg/bubble_point.svg'; import JoinablePartsField from '@components/form/Presentation/JoinablePartsField'; +import CoLeader from './CoLeader'; interface PresentationProps { submitButtonLabel: React.ReactNode; @@ -484,10 +485,25 @@ function Presentation({ {/* λͺ¨μ§‘ 정보 끝 */} - {/* μΆ”κ°€ 정보 - λͺ¨μž„μž₯ μ†Œκ°œ */} + {/* μΆ”κ°€ 정보 - 곡동 λͺ¨μž„μž₯ */}
4. μΆ”κ°€ 정보 + + + 곡동 λͺ¨μž„μž₯은 총 3λͺ…κΉŒμ§€ 등둝 κ°€λŠ₯ν•΄μš”. ν”Œλ ˆμ΄κ·ΈλΌμš΄λ“œμ—μ„œμ˜ λͺ¨μž„ 관리/νŽΈμ§‘μ€ λͺ¨μž„ κ°œμ„€μžλ§Œ κ°€λŠ₯ν•΄μš”. + + + { + return ; + }} + > +
+ + {/* μΆ”κ°€ 정보 - λͺ¨μž„μž₯ μ†Œκ°œ */} +
diff --git a/src/types/form.ts b/src/types/form.ts index bc7f164d..ff9633fa 100644 --- a/src/types/form.ts +++ b/src/types/form.ts @@ -77,6 +77,7 @@ export const schema = z.object({ ) .min(1, { message: 'λŒ€μƒ 파트λ₯Ό μ„ νƒν•΄μ£Όμ„Έμš”.' }), note: z.string().max(1000, { message: '1000자 κΉŒμ§€ μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€.' }).optional().nullable(), + coLeader: z.array(z.string()).optional(), }), }); From 73ad3a28256db1ee777680c16f2bbe5a38eb0efa Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Mon, 28 Oct 2024 05:04:21 +0900 Subject: [PATCH 02/25] =?UTF-8?q?feat:=20button=EC=97=90=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=A7=80=EC=A0=95=ED=95=B4=EC=A4=98=EC=84=9C=20?= =?UTF-8?q?=EC=9B=90=EC=B9=98=20=EC=95=8A=EB=8A=94=20submit=20=EC=95=88?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=B0=A9=EC=A7=80=ED=95=98?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/form/Presentation/CoLeader/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/form/Presentation/CoLeader/index.tsx b/src/components/form/Presentation/CoLeader/index.tsx index 13b7bf2b..f947df8c 100644 --- a/src/components/form/Presentation/CoLeader/index.tsx +++ b/src/components/form/Presentation/CoLeader/index.tsx @@ -30,7 +30,9 @@ const CoLeader = ({ value: coLeaders = [], onChange, error }: CoLeaderFieldProps πŸ‘€ {leader} - handleDeleteLeader(idx)}>Γ— + handleDeleteLeader(idx)}> + Γ— + ))} {coLeaders.length < 3 && ( From f8906a7252b8efec6c3ad2dee686eeece2c767ee Mon Sep 17 00:00:00 2001 From: ocahs9 Date: Tue, 29 Oct 2024 01:52:03 +0900 Subject: [PATCH 03/25] =?UTF-8?q?feat:=20=EB=A9=98=EC=85=98=EC=9D=84=20?= =?UTF-8?q?=ED=8F=AC=ED=95=A8=ED=95=9C=20input=20=ED=8B=80=20=EC=99=84?= =?UTF-8?q?=EC=84=B1(=EC=99=84=EC=A0=84=ED=9E=88=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EB=98=91=EA=B0=99=EC=9D=B4=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=9D=80=20x)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react-mentions/src/SuggestionsOverlay.js | 1 + pages/_app.tsx | 59 ++-- .../form/Presentation/CoLeader/index.tsx | 180 ++++++++-- .../SearchMention/SearchMentionContext.tsx | 28 ++ src/components/form/SearchMention/index.tsx | 322 ++++++++++++++++++ src/types/form.ts | 2 +- 6 files changed, 526 insertions(+), 66 deletions(-) create mode 100644 src/components/form/SearchMention/SearchMentionContext.tsx create mode 100644 src/components/form/SearchMention/index.tsx diff --git a/packages/react-mentions/src/SuggestionsOverlay.js b/packages/react-mentions/src/SuggestionsOverlay.js index 6c85ced9..687e709d 100644 --- a/packages/react-mentions/src/SuggestionsOverlay.js +++ b/packages/react-mentions/src/SuggestionsOverlay.js @@ -78,6 +78,7 @@ function SuggestionsOverlay({ return suggestionsToRender } + //μ—¬κΈ°μ„œ μ—”ν„°λ₯Ό λˆŒλ €μ„ λ•Œ ν•΄λ‹Ή κ°’ μ„€μ •λ˜λ„λ‘ λ§Œλ“€μˆ˜λŠ” μ—†μ„κΉŒ? const renderSuggestion = (result, queryInfo, index) => { const isFocused = index === focusIndex const { childIndex, query } = queryInfo diff --git a/pages/_app.tsx b/pages/_app.tsx index b77ca31d..c70b223d 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -20,6 +20,7 @@ import '@sopt-makers/ui/dist/index.css'; import { DialogProvider, ToastProvider } from '@sopt-makers/ui'; import { MentionProvider } from '@components/feed/Mention/MentionContext'; import { globalStyles } from 'styles/globals'; +import { SearchMentionProvider } from '@components/form/SearchMention/SearchMentionContext'; // λ¦¬μ•‘νŠΈ ν•˜μ΄λ“œλ ˆμ΄μ…˜ μ—λŸ¬λ₯Ό ν”Όν•˜κΈ° μœ„ν•΄ μ‚¬μš©. λ Œλ”λ§μ— κ΄€μ—¬ν•˜μ§€ μ•ŠλŠ” μ½”λ“œμ—¬μ„œ if 문으둜 λΆ„κΈ°μ²˜λ¦¬ if (typeof window !== 'undefined') { @@ -97,40 +98,42 @@ function MyApp({ Component, pageProps }: AppProps) { }, []); return ( - - - -