From 625fff4ddc5f916a68d25c0868c62c8291b65c3f Mon Sep 17 00:00:00 2001 From: happppi <102276917+hhbb0081@users.noreply.github.com> Date: Tue, 4 Jun 2024 18:15:04 +0900 Subject: [PATCH 1/3] =?UTF-8?q?Feat:=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20UI=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/images/ic_nodata.png | Bin 0 -> 3097 bytes src/components/molecules/noData/NoData.css | 21 ++++++++++++++++++++ src/components/molecules/noData/NoData.tsx | 22 +++++++++++++++++++++ src/components/molecules/noData/index.ts | 1 + 4 files changed, 44 insertions(+) create mode 100644 src/assets/images/ic_nodata.png create mode 100644 src/components/molecules/noData/NoData.css create mode 100644 src/components/molecules/noData/NoData.tsx create mode 100644 src/components/molecules/noData/index.ts diff --git a/src/assets/images/ic_nodata.png b/src/assets/images/ic_nodata.png new file mode 100644 index 0000000000000000000000000000000000000000..ce69f7b6ea3c4a338a884cc18ed441241de7c47d GIT binary patch literal 3097 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 YWDaSbT+5J% { + return( +
+ no_data + {title} +
+ ) +} \ No newline at end of file diff --git a/src/components/molecules/noData/index.ts b/src/components/molecules/noData/index.ts new file mode 100644 index 0000000..9ba64d7 --- /dev/null +++ b/src/components/molecules/noData/index.ts @@ -0,0 +1 @@ +export { NoData } from "./NoData"; From 143714117a920efde0392bf17260ac342aff6060 Mon Sep 17 00:00:00 2001 From: happppi <102276917+hhbb0081@users.noreply.github.com> Date: Tue, 4 Jun 2024 18:16:05 +0900 Subject: [PATCH 2/3] =?UTF-8?q?Feat:=20=EC=9D=BC=EC=A0=95=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20skeleton=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../molecules/scheduleBox/ScheduleBox.css | 101 ++++++++++++++++++ .../scheduleBox/SkeletonScheduleBox.tsx | 13 +++ src/features/home/SetHome.tsx | 3 +- .../home/components/HomeDateWrapper.tsx | 20 +++- 4 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 src/components/molecules/scheduleBox/SkeletonScheduleBox.tsx diff --git a/src/components/molecules/scheduleBox/ScheduleBox.css b/src/components/molecules/scheduleBox/ScheduleBox.css index c109928..3e3570f 100644 --- a/src/components/molecules/scheduleBox/ScheduleBox.css +++ b/src/components/molecules/scheduleBox/ScheduleBox.css @@ -29,4 +29,105 @@ .scheduleBox__attend { display: flex; justify-content: flex-end; +} + +/* SkeletonScheduleBox */ + +@keyframes loading { + 0% { + transform: translateX(0); + } + 50%, + 100% { + transform: translateX(460px); + } +} + +.skeleton-item { + width: 100%; + margin: 1rem 0; + /* height: 54%; */ + /* height: 100%; */ +} + + +.skeleton-info { + width: 100%; + /* height: 100%; */ + margin: 0 auto; + padding: 0.5rem 1rem; + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + background-color: #404040; + border-radius: 50px; +} + + +.skeleton-name { + width: 15%; + height: 25px; + background-color: #5E5E5E; + border-radius: 10px; + position: relative; + overflow: hidden; +} + +.skeleton-name::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 30px; + height: 100%; + background: linear-gradient(to right, #5E5E5E, #666666, #5E5E5E); + animation: loading 2s infinite linear; +} + +.skeleton-email { + width: 40%; + height: 25px; + background-color: #5E5E5E; + border-radius: 10px; + position: relative; + overflow: hidden; +} + + +.skeleton-email::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 30px; + height: 100%; + background: linear-gradient(to right, #5E5E5E, #666666, #5E5E5E); + animation: loading 2s infinite linear; +} + +.skeleton-attend { + width: 15%; + height: 25px; + background-color: #5E5E5E; + border-radius: 10px; + position: relative; + overflow: hidden; +} + +.skeleton-attend::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 30px; + height: 100%; + background: linear-gradient(to right, #5E5E5E, #666666, #5E5E5E); + animation: loading 2s infinite linear; +} + + +.element { + overflow: hidden; + position: relative; } \ No newline at end of file diff --git a/src/components/molecules/scheduleBox/SkeletonScheduleBox.tsx b/src/components/molecules/scheduleBox/SkeletonScheduleBox.tsx new file mode 100644 index 0000000..b7f4cc0 --- /dev/null +++ b/src/components/molecules/scheduleBox/SkeletonScheduleBox.tsx @@ -0,0 +1,13 @@ +import "./ScheduleBox.css"; + +export const SkeletonScheduleBox = () => { + return ( +
+
+
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/features/home/SetHome.tsx b/src/features/home/SetHome.tsx index 8d80a38..b0a80e3 100644 --- a/src/features/home/SetHome.tsx +++ b/src/features/home/SetHome.tsx @@ -22,13 +22,14 @@ const SetHome = () => { return ( -
+
- {dateList && dateList?.map((date: ScheduleContent) => ( + {isLoading ? ( + <> + + + + + ) : ( + dateList && dateList.length > 0 ? (dateList?.map((date: ScheduleContent) => ( + ))) : ( + ))} ) From 1f235c8687a9a170f18b2b4c68aa1f4b7e376187 Mon Sep 17 00:00:00 2001 From: happppi <102276917+hhbb0081@users.noreply.github.com> Date: Tue, 4 Jun 2024 18:17:08 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Feat:=20=EC=9D=BC=EC=A0=95=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20custom=20hook=20(useScheduleMutation)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/schdule.ts | 14 +++ src/app/globals.css | 1 + src/assets/images/ic_clock.png | Bin 0 -> 1793 bytes src/components/atoms/calendar/Calendar.tsx | 11 +- src/constants/images.ts | 2 + .../home/calendar/SetCalendarRegister.tsx | 48 +++++++- .../home/calendar/components/Calendar.css | 8 +- .../calendar/components/CalendarRegister.tsx | 105 +++++++----------- src/features/home/components/Home.css | 3 +- src/hook/schedule/useScheduleMutation.ts | 11 ++ src/types/schedule/types.ts | 17 ++- 11 files changed, 145 insertions(+), 75 deletions(-) create mode 100644 src/apis/schdule.ts create mode 100644 src/assets/images/ic_clock.png create mode 100644 src/hook/schedule/useScheduleMutation.ts diff --git a/src/apis/schdule.ts b/src/apis/schdule.ts new file mode 100644 index 0000000..39b4d0b --- /dev/null +++ b/src/apis/schdule.ts @@ -0,0 +1,14 @@ +import { ScheduleData } from "@/types/schedule"; +import { http } from "./http"; + +export const scheduleRegister = ( + data: ScheduleData +) => { + try { + const response = http.patch("/itemgroup.update", data); + return response; + } catch (error) { + console.log(error); + throw error; + } +}; \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index eebbd81..216c3dc 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -8,6 +8,7 @@ html, body { max-width: 100vw; + height: calc(100% - 6.5rem); background-color: #2B2B2B; } diff --git a/src/assets/images/ic_clock.png b/src/assets/images/ic_clock.png new file mode 100644 index 0000000000000000000000000000000000000000..444e48c534609d7bd96f68bd63362386d1ce6bb0 GIT binary patch literal 1793 zcmV+c2mbhpP)q7sdOQDb6ERKy1YL_+!^2|jQq$R)N@I<#C%Xt| zFE9q|0$vAp14ZlF5U?0n0h|Mz4UF_)`!V3VA%xd^Xj2WXJ3iUP)0t8qRyV1iSBuWp zKj!Cj^;-2G>IYr;dtbevskl*x)L(T$WTI8?v>JUcGtM&;9ehu#zp#%Xkt1-l`alQg zlj;p>FI~4+9>=M-+PMebr4HBS^ceNQ4h}b~r_|!GJ5DF4_jkdmznfs3>B}7LQ!lJ3 zt}6U4xBT_{7yB6w>TgPnkE$zbjHfEcmFkWXoDs(TW?w$9WkS{2s;XC-X> zDTFXtH?ct>gm93Uw`j*2buAnj0^dqh`T+P{L)-?5KW54|z>yp9^+bio2a;iF7$Jlm zz>|qfUj-=CrNk6eJ05D1*np9mU)HKi3g8QwM*mMY;HgAe0erat&P!a}3;e55N`u7~ z;83D`bpf27xUfBhFx@Pt!6Ae&1w5O$bVfl;MYrRPW+}}HUPzR!DuB-TFO|ekF2AtoN{Sxd;lr1QLPbMx{w|Dg<^={xn;N(I0Y{TJ1*+>DTCc976 z++dFYGQ^0S5bs>cP{rKzx3ln7rhJigq$;xc3s_I4k3h}A0>`?V-;OY>< zXjNZ5VtJx$cR~7Me;k?KLilzF;q3}``^7oH@rm*+sGrU}t?PRA zV%#2|jsK{>RQsA#`-S@bM10fgNi!8vn~Obv4!646_l&zRe^$?}J(>zoA5FwJI=jMc zi3(HdvN_~k3)JPUr`?X*;K=IefkfLOVB^4;Hiyedi^1;s=wGYrriQ_UdfdRM)(mxl zX&K+xOq~KCgdpkc=>p*T0r71D*AnG-?fCtFl^C~{#}jvJQazz@sx?DhYFbP+ZcfOh z{w&cz_5K0#?;FNNR|+?kHCk+bd;IbN^6v}khD;25vQK|js zh^1OjJ{P>|#Z?WLiKAau*VG(K6^^UScYCcWlx!IvGA(A9!67>-uNs7Lwl5P--)oOD z{gjiV)W4TF(I`k7q*!{X`S<(`Hmmhyw_7)%tS6`*Hfs7CJJ4hla&7AH)K%|MkFMMK zknt#7C+snPUY}W`@8#-G?CyNh?e^R4JCNC6_b0@jFeXUOvj^?I@$2+lVNit=}+lLYxHN1zrPQ j0-gh&2_d}GB)<;<_)SmNv#B`P00000NkvXXu0mjfaPMI= literal 0 HcmV?d00001 diff --git a/src/components/atoms/calendar/Calendar.tsx b/src/components/atoms/calendar/Calendar.tsx index 9a27dd6..c2a579e 100644 --- a/src/components/atoms/calendar/Calendar.tsx +++ b/src/components/atoms/calendar/Calendar.tsx @@ -18,7 +18,7 @@ const Calendar = dynamic(() => import('react-calendar'), { ssr: false }); // 지 export interface HomeCalendarProps { mark?: string[]; setCalendarOpen?: any; - value: Date; + value?: Date; onChange: (date: Date) => void; } @@ -32,17 +32,18 @@ export function HomeCalendar({ const handleDateChange = (selectedDate: any) => { if (selectedDate instanceof Date) { onChange(selectedDate); + setCalendarOpen && setCalendarOpen(false); } }; const handleDate = (e: React.MouseEvent): void => { const newValue = new Date(); - if (e.currentTarget.id === "next") { + if (e.currentTarget.id === "next" && value) { // 다음달 - onChange(moment(newValue.setMonth(value.getMonth() + 1, 1)).toDate()) - } else if (e.currentTarget.id === "prev") { + onChange(moment(newValue.setMonth(value?.getMonth() + 1, 1)).toDate()) + } else if (e.currentTarget.id === "prev" && value) { // 저번달 - onChange(moment(newValue.setMonth(value.getMonth() - 1, 1)).toDate()) + onChange(moment(newValue.setMonth(value?.getMonth() - 1, 1)).toDate()) } }; diff --git a/src/constants/images.ts b/src/constants/images.ts index 49f061e..9b5ffbb 100644 --- a/src/constants/images.ts +++ b/src/constants/images.ts @@ -14,6 +14,7 @@ export const ICONS = { down: require("@/assets/images/ic_down.png"), search: require("@/assets/images/ic_search.png"), calendar: require("@/assets/images/ic_calendar.png"), + clock: require("@/assets/images/ic_clock.png"), exchange: require("@/assets/images/ic_exchange.png"), memberProfileNone: require("@/assets/images/ic_member_profile_none.png"), manager: require("@/assets/images/ic_manager.png"), @@ -23,6 +24,7 @@ export const ICONS = { arrowRight: require("@/assets/images/ic_arrow_right.png"), back: require("@/assets/images/ic_back.png"), filter: require("@/assets/images/ic_filter.png"), + nodata: require("@/assets/images/ic_nodata.png"), floatingPlus: require("@/assets/images/Plus.png"), floatingLock: require("@/assets/images/ic_lock.png"), diff --git a/src/features/home/calendar/SetCalendarRegister.tsx b/src/features/home/calendar/SetCalendarRegister.tsx index 1f62a46..f5a76fd 100644 --- a/src/features/home/calendar/SetCalendarRegister.tsx +++ b/src/features/home/calendar/SetCalendarRegister.tsx @@ -1,14 +1,54 @@ import { Button } from "@/components/atoms/button"; import { Wrapper } from "@/components/organisms/Wrapper"; +import { useScheduleMutation } from "@/hook/schedule/useScheduleMutation"; +import { ScheduleData } from "@/types/schedule"; +import { usePathname } from "next/navigation"; +import { useForm } from "react-hook-form"; import CalendarRegister from "./components/CalendarRegister"; import { CALENDAR_BTN } from "./constants/const"; const SetCalendarRegister = () => { + const path = usePathname(); + + // 일정 등록 입력 폼 관리 + const { + register, + formState: {errors}, + handleSubmit, + setValue, + } = useForm({ + mode: "onSubmit", + defaultValues: { + scheduleName: "", + scheduleDate: "", + scheduleTime: "", + schedulePlace: "", + scheduleContent: "", + }, + }); + + const { mutate } = useScheduleMutation({ + clubId: +path.split("/")[1], + userId: 6 + }); + + const onsubmit = (data: ScheduleData) => { + console.log(data); + mutate(data); + }; + return ( - - - - +
+ + + + +
) }; diff --git a/src/features/home/calendar/components/Calendar.css b/src/features/home/calendar/components/Calendar.css index 487a149..4f97151 100644 --- a/src/features/home/calendar/components/Calendar.css +++ b/src/features/home/calendar/components/Calendar.css @@ -176,6 +176,12 @@ color: #fff; } +.calendarRegister__time { + display: flex; + align-items: center; + justify-content: space-between; +} + .calendarRegister__dateInput { position: relative; cursor: pointer; @@ -209,7 +215,7 @@ .calendarRegister__background__calendar { position: absolute; left: 20vw; - top: calc(7.5rem + 32px); + top: calc(11rem); } /* CalendarPeriod */ diff --git a/src/features/home/calendar/components/CalendarRegister.tsx b/src/features/home/calendar/components/CalendarRegister.tsx index be477ad..41d477f 100644 --- a/src/features/home/calendar/components/CalendarRegister.tsx +++ b/src/features/home/calendar/components/CalendarRegister.tsx @@ -1,49 +1,30 @@ import moment from "moment"; import Image from "next/image"; import { useRouter } from "next/navigation"; -import { useState } from "react"; -import { useForm } from "react-hook-form"; +import { useEffect, useState } from "react"; import { HomeCalendar } from "@/components/atoms/calendar"; import { RegisterBox } from "@/components/molecules/registerBox"; import { ICONS } from "@/constants/images"; -// import DatePicker from "@types/react-datepicker"; -// import "react-datepicker/dist/react-datepicker.css"; +import DatePicker from "react-datepicker"; +import "react-datepicker/dist/react-datepicker.css"; import "./Calendar.css"; -interface scheduleProps { - scheduleName?: string; - date?: string; - time?: string; - location?: string; - content?: string; -}; - -const CalendarRegister = () => { +const CalendarRegister = ({ register, setValue }: any) => { const router = useRouter(); const [calendarOpen, setCalendarOpen] = useState(false); // calendar open const [timeOpen, setTimeOpen] = useState(false); - const [value, onChange] = useState(new Date()); - const { - register, - formState: {errors}, - watch, - reset, - handleSubmit, - getValues, - setError, - setFocus - } = useForm({ - mode: "onSubmit", - defaultValues: { - scheduleName: "", - date: "", - time: "", - location: "", - content: "", - }, - }); + const [value, onChange] = useState(undefined); + const [startDate, setStartDate] = useState(null); + + useEffect(() => { + setValue("scheduleDate", moment(value).format("YYYY-MM-DD")) + }, [value]); + + useEffect(() => { + setValue("scheduleTime", moment(startDate).format("HH:mm")) + }, [startDate]) return (
@@ -62,10 +43,10 @@ const CalendarRegister = () => { setCalendarOpen((prev) => !prev)} className="calendarRegister__dateInput" - {...register("date")} + {...register("scheduleDate")} readOnly /> { - - calendar setTimeOpen((prev) => !prev)} - /> +
+ setStartDate(date)} + // locale={ ko } + showTimeSelect + showTimeSelectOnly + timeIntervals={15} + // minTime={setHours(setMinutes(new Date(), 30), 9)} + // maxTime={setHours(setMinutes(new Date(), 0), 17)} + timeCaption="Time" + dateFormat="hh:mm aa" + placeholderText="시간을 선택해주세요" + className="calendarRegister__dateInput" + /> + + calendar setTimeOpen((prev) => !prev)} + /> +
- {timeOpen && ( -
- - {/* setStartDate(date)} // 내가 선택한 날짜가 맨 위에 표시 됨 - showTimeSelect // 시간 나오게 하기 - timeFormat="HH:mm" //시간 포맷 - timeIntervals={15} // 15분 단위로 선택 가능한 box가 나옴 - timeCaption="time" - dateFormat="MMMM d, yyyy h:mm aa" - /> */} - -
- )}
{ {