From 6bbffbcb507dcbddea51745b33a8f5610e000526 Mon Sep 17 00:00:00 2001 From: geonhee-min Date: Mon, 8 Dec 2025 16:57:09 +0900 Subject: [PATCH] =?UTF-8?q?issue=20#60=20-=20=EC=9D=BC=EC=A0=95=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95:?= =?UTF-8?q?=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=EC=BB=AC=EB=9F=AC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20-=20=EC=9D=BC=EC=A0=95=20=EC=8B=9C=EC=9E=91/?= =?UTF-8?q?=EC=A2=85=EB=A3=8C=EC=9D=BC=20=EC=84=A4=EC=A0=95=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=20=EC=9D=BC=EC=A0=95=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20-=20=EC=9D=BC=EC=A0=95=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91/=EC=A2=85=EB=A3=8C=20=EC=8B=9C=EA=B0=84=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 21 +- src/components/ui/calendar.tsx | 2 +- src/components/ui/scroll-area.tsx | 2 +- src/const/ColorPalette.ts | 71 ++-- src/const/schedule/ScheduleDay.ts | 9 + src/const/schedule/ScheduleStatus.ts | 7 +- src/const/schedule/ScheduleType.ts | 10 +- src/data/form/createSchedule.schema.ts | 2 + src/hooks/use-palette.ts | 20 +- src/hooks/use-record.ts | 13 + src/index.css | 16 +- src/ui/component/calendar/CustomCalendar.tsx | 9 +- src/ui/component/popover/SchedulePopover.tsx | 129 -------- .../{ => schedule}/ColorPickPopover.tsx | 3 +- .../popover/schedule/DatePickPopover.tsx | 129 ++++++++ .../popover/schedule/SchedulePopover.tsx | 303 ++++++++++++++++++ .../popover/schedule/TimePickPopover.tsx | 135 ++++++++ .../popover/schedule/TypePickPopover.tsx | 31 ++ src/ui/page/home/TempPage.tsx | 25 ++ 19 files changed, 717 insertions(+), 220 deletions(-) create mode 100644 src/const/schedule/ScheduleDay.ts create mode 100644 src/hooks/use-record.ts delete mode 100644 src/ui/component/popover/SchedulePopover.tsx rename src/ui/component/popover/{ => schedule}/ColorPickPopover.tsx (90%) create mode 100644 src/ui/component/popover/schedule/DatePickPopover.tsx create mode 100644 src/ui/component/popover/schedule/SchedulePopover.tsx create mode 100644 src/ui/component/popover/schedule/TimePickPopover.tsx create mode 100644 src/ui/component/popover/schedule/TypePickPopover.tsx create mode 100644 src/ui/page/home/TempPage.tsx diff --git a/src/App.tsx b/src/App.tsx index 5d79990..f229a25 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,30 +7,16 @@ import { PageRouting } from './const/PageRouting'; import LoginPage from './ui/page/account/login/LoginPage'; import ResetPasswordPage from './ui/page/account/resetPassword/ResetPasswordPage'; import { HomePage } from './ui/page/home/HomePage'; -import type { AuthData } from './data/AuthData'; -import { useEffect } from 'react'; import { ScheduleMainPage } from './ui/page/schedule/ScheduleMainPage'; -import { BaseNetwork } from './network/BaseNetwork'; +import { TempPage } from './ui/page/home/TempPage'; function App() { - const { authData, login } = useAuthStore(); - const baseNetwork = new BaseNetwork(); - useEffect(() => { - const autoLogin = localStorage.getItem('autoLogin') === 'true'; - if (autoLogin) { - try { - (async () => { - await baseNetwork.refreshToken(); - })(); - } catch (err) { - localStorage.setItem('autoLogin', 'false'); - } - } - }, []); + const { authData } = useAuthStore(); return ( + } path={"/"} /> {/* 자동로그인용 대기 화면 */} }> { !authData @@ -39,7 +25,6 @@ function App() { } path={PageRouting["SIGN_UP"].path} /> } path={PageRouting["RESET_PASSWORD"].path} /> } path="*" /> - } path={"/"} /> {/* 자동로그인용 대기 화면 */} : <> } path="*" /> diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx index 225d827..d3fa42c 100644 --- a/src/components/ui/calendar.tsx +++ b/src/components/ui/calendar.tsx @@ -58,7 +58,7 @@ function Calendar({ return ''; }, formatMonthDropdown: (date) => - date.toLocaleString("", { month: "short" }), + date.toLocaleString("default", { month: "short" }), ...formatters, }} classNames={{ diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx index 8e4fa13..199594e 100644 --- a/src/components/ui/scroll-area.tsx +++ b/src/components/ui/scroll-area.tsx @@ -13,7 +13,7 @@ function ScrollArea({ return ( div>div:last-child]:hidden", className)} {...props} > = { Black: { index: 0, - style: '#000000', - main: true + style: '#000000' }, White: { index: 1, - style: '#FFFFFF', - main: true + style: '#FFFFFF' }, - PeachCream: { + SerenityBlue: { index: 2, - style: '#FFDAB9', - main: false + style: '#92A8D1' }, CoralPink: { index: 3, - style: '#F08080', - main: true + style: '#F08080' }, MintIcing: { index: 4, - style: '#C1E1C1', - main: false + style: '#C1E1C1' }, Vanilla: { index: 5, - style: '#FFFACD', - main: true + style: '#FFFACD' }, Wheat: { index: 6, - style: '#F5DEB3', - main: false + style: '#F5DEB3' }, AliceBlue: { index: 7, - style: '#F0F8FF', - main: true + style: '#F0F8FF' }, Lavender: { index: 8, - style: '#E6E6FA', - main: false + style: '#E6E6FA' }, - LightAqua: { + SageGreen: { index: 9, - style: '#A8E6CF', - main: true + style: '#b2ac88' }, CloudWhite: { index: 10, - style: '#F0F8FF', - main: false + style: '#F2F2ED' }, LightGray: { index: 11, - style: '#D3D3D3', - main: true + style: '#D3D3D3' }, LightKhakki: { index: 12, - style: '#F0F8E6', - main: false + style: '#F0F8E6' }, DustyRose: { index: 13, - style: '#D8BFD8', - main: true + style: '#D8BFD8' }, CreamBeige: { index: 14, - style: '#FAF0E6', - main: true, + style: '#FAF0E6' }, Oatmeal: { index: 15, - style: '#FDF5E6', - main: false + style: '#FDF5E6' }, CharcoalLight: { index: 16, - style: '#A9A9A9', - main: true + style: '#A9A9A9' }, - Custom: { + PeachCream: { index: 17, - style: 'transparent', - main: false - }, + style: '#FFDAB9' + }, + LavenderBlue: { + index: 18, + style :'#CCCCFF' + }, + SeaFoamGreen: { + index: 19, + style: '#93E9BE' + } } \ No newline at end of file diff --git a/src/const/schedule/ScheduleDay.ts b/src/const/schedule/ScheduleDay.ts new file mode 100644 index 0000000..5c14fc0 --- /dev/null +++ b/src/const/schedule/ScheduleDay.ts @@ -0,0 +1,9 @@ +export const ScheduleDay: Record = { + 1: '일', + 2: '월', + 3: '화', + 4: '수', + 5: '목', + 6: '금', + 7: '토' +} \ No newline at end of file diff --git a/src/const/schedule/ScheduleStatus.ts b/src/const/schedule/ScheduleStatus.ts index e48ec75..7958ef4 100644 --- a/src/const/schedule/ScheduleStatus.ts +++ b/src/const/schedule/ScheduleStatus.ts @@ -1 +1,6 @@ -export type ScheduleStatus = 'yet' | 'completed'; \ No newline at end of file +export type ScheduleStatus = 'yet' | 'completed'; + +export const ScheduleStatusLabel: Record = { + 'yet': '미완료', + 'completed': '완료' +}; \ No newline at end of file diff --git a/src/const/schedule/ScheduleType.ts b/src/const/schedule/ScheduleType.ts index 5874a39..3f59ae9 100644 --- a/src/const/schedule/ScheduleType.ts +++ b/src/const/schedule/ScheduleType.ts @@ -1 +1,9 @@ -export type ScheduleType = 'once' | 'daily' | 'weekly' | 'aweekly' | 'monthly' | 'annual'; +export type ScheduleType = 'once' | 'daily' | 'weekly' | 'monthly' | 'annual'; + +export const ScheduleTypeLabel: Record = { + 'once': '한 번만', + 'daily': '매일', + 'weekly': '매주', + 'monthly': '매월', + 'annual': '매년' +}; \ No newline at end of file diff --git a/src/data/form/createSchedule.schema.ts b/src/data/form/createSchedule.schema.ts index 3df7dfa..ebee498 100644 --- a/src/data/form/createSchedule.schema.ts +++ b/src/data/form/createSchedule.schema.ts @@ -19,4 +19,6 @@ export const CreateScheduleSchema = z.object({ .string() , endTime: z .string() + , dayList: z + .string() }); \ No newline at end of file diff --git a/src/hooks/use-palette.ts b/src/hooks/use-palette.ts index a94f704..670556f 100644 --- a/src/hooks/use-palette.ts +++ b/src/hooks/use-palette.ts @@ -10,12 +10,10 @@ export function usePalette() { const getMainPaletteList = () => { const paletteKeys = Object.keys(ColorPalette); let paletteList: ColorPaletteType[] = []; - paletteKeys.forEach((paletteKey) => { + paletteKeys.slice(0, 10).forEach((paletteKey) => { const key = paletteKey as keyof typeof ColorPalette; const palette: ColorPaletteType = ColorPalette[key]; - if (palette.main) { - paletteList.push(palette); - } + paletteList.push(palette); }); paletteList = paletteList.sort((a, b) => a.index - b.index); @@ -26,12 +24,11 @@ export function usePalette() { const getExtraPaletteList = () => { const paletteKeys = Object.keys(ColorPalette); let paletteList: ColorPaletteType[] = []; - paletteKeys.forEach((paletteKey) => { + paletteKeys.slice(10).forEach((paletteKey) => { const key = paletteKey as keyof typeof ColorPalette; const palette: ColorPaletteType = ColorPalette[key]; - if (!palette.main) { - paletteList.push(palette); - } + paletteList.push(palette); + }); paletteList = paletteList.sort((a, b) => a.index - b.index); return paletteList; @@ -43,12 +40,6 @@ export function usePalette() { return ColorPalette[key]; } - const getCustomColor = (style: string) => { - return { - style: `#${style}`, - main: false - } as ColorPaletteType; - } const getStyle = (palette: ColorPaletteType) => { return palette.style; @@ -61,7 +52,6 @@ export function usePalette() { getExtraPaletteList, getAllPaletteList, getPaletteByKey, - getCustomColor, getStyle } } \ No newline at end of file diff --git a/src/hooks/use-record.ts b/src/hooks/use-record.ts new file mode 100644 index 0000000..7f1582a --- /dev/null +++ b/src/hooks/use-record.ts @@ -0,0 +1,13 @@ +import { useMemo } from "react"; + +export function useRecord(record: Record) { + const keys = useMemo(() => { + return Object.keys(record); + }, [record]); + + const values = useMemo(() => { + return Object.values(record); + }, [record]); + + return { keys, values }; +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index b2f3297..1ea1679 100644 --- a/src/index.css +++ b/src/index.css @@ -134,19 +134,19 @@ input[type="number"]::-webkit-outer-spin-button { margin: 0; } -.rdp-day { - aspect-ratio: unset; -} - /* Firefox */ input[type="number"] { -moz-appearance: textfield; } -.rdp-week:not(:first-child) { - @apply border-t; +.custom-rdp-day { + aspect-ratio: unset!; } -.rdp-day:not(:first-child) { - @apply border-l; +.custom-rdp-week:not(:first-child) { + @apply border-t!; +} + +.custom-rdp-day:not(:first-child) { + @apply border-l!; } \ No newline at end of file diff --git a/src/ui/component/calendar/CustomCalendar.tsx b/src/ui/component/calendar/CustomCalendar.tsx index 779075e..f572bed 100644 --- a/src/ui/component/calendar/CustomCalendar.tsx +++ b/src/ui/component/calendar/CustomCalendar.tsx @@ -5,7 +5,7 @@ import { getDefaultClassNames } from "react-day-picker"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { ScrollArea } from "@/components/ui/scroll-area"; import { isSameDay, getWeeksInMonth, getWeekOfMonth } from "date-fns"; -import { SchedulePopover } from "../popover/SchedulePopover"; +import { SchedulePopover } from "../popover/schedule/SchedulePopover"; interface CustomCalendarProps { data?: any; @@ -127,11 +127,13 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => { ), week: cn( defaultClassNames.week, - `w-full` + `w-full`, + 'custom-rdp-week' ), day: cn( defaultClassNames.day, - `w-[calc(100%/7)] rounded-none` + `w-[calc(100%/7)] rounded-none`, + 'custom-rdp-day' ), day_button: cn( defaultClassNames.day_button, @@ -181,6 +183,7 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => { /> diff --git a/src/ui/component/popover/SchedulePopover.tsx b/src/ui/component/popover/SchedulePopover.tsx deleted file mode 100644 index 4e32c45..0000000 --- a/src/ui/component/popover/SchedulePopover.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; -import { ScrollArea } from '@/components/ui/scroll-area'; -import { Sheet, SheetContent, SheetHeader } from '@/components/ui/sheet'; -import { cn } from '@/lib/utils'; -import { useEffect, useState } from 'react'; -import { usePalette } from '@/hooks/use-palette'; -import { type ColorPaletteType } from '@/const/ColorPalette'; -import { ColorPickPopover } from './ColorPickPopover'; -import { Input } from '@/components/ui/input'; -import { Controller, useForm } from 'react-hook-form'; -import * as z from 'zod'; -import { CreateScheduleSchema } from '@/data/form/createSchedule.schema'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { Field, FieldError } from '@/components/ui/field'; -import { ArrowLeft, PenSquare, X } from 'lucide-react'; - -interface ScheduleSheetProps { - date: Date | undefined; - popoverSide: 'left' | 'right'; - popoverAlign: 'start' | 'end'; -} - -export const SchedulePopover = ({ date, popoverSide, popoverAlign }: ScheduleSheetProps) => { - const { - getPaletteByKey, - } = usePalette(); - const defaultColor = getPaletteByKey('Black'); - const [scheduleColor, setScheduleColor] = useState(defaultColor); - const [colorPopoverOpen, setColorPopoverOpen] = useState(false); - const [mode, setMode] = useState<'list' | 'detail' | 'create' | 'edit'>('list'); - const selectColor = (color: ColorPaletteType) => { - setScheduleColor(color); - setColorPopoverOpen(false); - } - - const createScheduleForm = useForm>({ - resolver: zodResolver(CreateScheduleSchema), - defaultValues: { - name: "", - startDate: date, - endDate: date, - content: "", - startTime: "", - endTime: "", - type: "once", - status: "yet", - style: defaultColor.style, - } - }); - - const Content = () => { - switch(mode) { - case 'list': - return ( -
- setMode('create')}/> -
- ); - case 'create': - return ( -
-
- - -
- - - - ( - - - - - )} - /> -
-
setMode('list')} - > - - 닫기 -
-
- ) - default: return (<>) - } - } - - return ( - - div>div:last-child]:hidden min-h-[125px] h-[calc(100vh/2)] p-2.5 w-full flex flex-col", - ) - } - > - {} - - - ) -} \ No newline at end of file diff --git a/src/ui/component/popover/ColorPickPopover.tsx b/src/ui/component/popover/schedule/ColorPickPopover.tsx similarity index 90% rename from src/ui/component/popover/ColorPickPopover.tsx rename to src/ui/component/popover/schedule/ColorPickPopover.tsx index 0dba42c..8f79a2d 100644 --- a/src/ui/component/popover/ColorPickPopover.tsx +++ b/src/ui/component/popover/schedule/ColorPickPopover.tsx @@ -51,8 +51,7 @@ export const ColorPickPopover = ({ setColor }: ColorPickPopoverProps) => {
setColor(palette)} /> diff --git a/src/ui/component/popover/schedule/DatePickPopover.tsx b/src/ui/component/popover/schedule/DatePickPopover.tsx new file mode 100644 index 0000000..b8b76cf --- /dev/null +++ b/src/ui/component/popover/schedule/DatePickPopover.tsx @@ -0,0 +1,129 @@ +import { Button } from "@/components/ui/button"; +import { Calendar } from "@/components/ui/calendar"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; +import { format } from "date-fns"; +import { useState } from "react"; + +interface BaseProps { + disabled: boolean; + popoverAlign: 'start' | 'end'; +} + +interface SingleModeProps extends BaseProps { + mode: 'single'; + date: Date | undefined; + setDate: (date: Date | undefined) => void; +} + +interface RangeModeProps extends BaseProps { + mode: 'range'; + startDate: Date | undefined; + endDate: Date | undefined; + setStartDate: (date: Date | undefined) => void; + setEndDate: (date: Date | undefined) => void; +} + +type DaetPickPopoverProps = SingleModeProps | RangeModeProps; + +export const DatePickPopover = ({ ...props } : DaetPickPopoverProps) => { + const { mode, popoverAlign, disabled } = props; + + if (mode === 'single') { + const { date, setDate } = props; + const [open, setOpen] = useState(false); + const onDaySelected = (open: boolean) => { + setOpen(open); + } + return( +
{date?.toString()}
+ ) + } + + const { startDate, setStartDate, endDate, setEndDate } = props; + const [startOpen, setStartOpen] = useState(false); + const [endOpen, setEndOpen] = useState(false); + + const onStartDaySelected = (date: Date | undefined) => { + setStartDate(date); + setStartOpen(false); + } + + const onEndDaySelected = (date: Date | undefined) => { + setEndDate(date); + setEndOpen(false); + } + + + return ( +
+ + + + + + + + + - + + + + + + + + +
+ ) +} \ No newline at end of file diff --git a/src/ui/component/popover/schedule/SchedulePopover.tsx b/src/ui/component/popover/schedule/SchedulePopover.tsx new file mode 100644 index 0000000..4d770c0 --- /dev/null +++ b/src/ui/component/popover/schedule/SchedulePopover.tsx @@ -0,0 +1,303 @@ +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; +import { ScrollArea } from '@/components/ui/scroll-area'; +import { cn } from '@/lib/utils'; +import { useEffect, useState } from 'react'; +import { usePalette } from '@/hooks/use-palette'; +import { ColorPalette, type ColorPaletteType } from '@/const/ColorPalette'; +import { ColorPickPopover } from './ColorPickPopover'; +import { Input } from '@/components/ui/input'; +import { Controller, useForm } from 'react-hook-form'; +import * as z from 'zod'; +import { CreateScheduleSchema } from '@/data/form/createSchedule.schema'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Field, FieldError } from '@/components/ui/field'; +import { PenSquare, X } from 'lucide-react'; +import { ScheduleTypeLabel, type ScheduleType } from '@/const/schedule/ScheduleType'; +import { useRecord } from '@/hooks/use-record'; +import { TypePickPopover } from './TypePickPopover'; +import { ScheduleDay } from '@/const/schedule/ScheduleDay'; +import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'; +import { DatePickPopover } from './DatePickPopover'; +import { format } from 'date-fns'; +import { TimePickPopover } from './TimePickPopover'; + +interface ScheduleSheetProps { + date: Date | undefined; + open: boolean; + popoverSide: 'left' | 'right'; + popoverAlign: 'start' | 'end'; +} + +export const SchedulePopover = ({ date, open, popoverSide, popoverAlign }: ScheduleSheetProps) => { + const { + getPaletteByKey + } = usePalette(); + const [mode, setMode] = useState<'list' | 'create' | 'detail' | 'update'>('list'); + const [colorPopoverOpen, setColorPopoverOpen] = useState(false); + const dayLabelList = useRecord(ScheduleDay).keys.map((key) => { + return { + day: Number(key), + label: ScheduleDay[Number(key)] + } as { day: number, label: string }; + }) + const createScheduleForm = useForm>({ + resolver: zodResolver(CreateScheduleSchema), + defaultValues: { + name: "", + startDate: date || new Date(), + endDate: date || new Date(), + content: "", + startTime: "", + endTime: "", + type: "once", + status: "yet", + style: getPaletteByKey('Black').style, + dayList: "" + } + }); + + useEffect(() => { + console.log(date); + if (open && date) { + createScheduleForm.setValue('startDate', date); + createScheduleForm.setValue('endDate', date); + + return; + } + + setTimeout(() => { + setMode('list'); + createScheduleForm.clearErrors(); + createScheduleForm.reset(); + }, 150); + }, [open]); + + const { + name, + startDate, + endDate, + content, + startTime, + endTime, + type, + status, + style, + dayList + } = createScheduleForm.watch(); + + const selectColor = (color: ColorPaletteType) => { + createScheduleForm.setValue('style', color.style); + setColorPopoverOpen(false); + } + + const selectType = (type: ScheduleType) => { + createScheduleForm.setValue('type', type); + } + + const selectDayList = (newValues: string[]) => { + const sortedValues = newValues.sort(); + const newDayList = sortedValues.join(''); + createScheduleForm.setValue('dayList', newDayList); + } + + const selectDate = (type: 'startDate' | 'endDate', date: Date | undefined) => { + if (!date) return; + createScheduleForm.setValue(type, date); + } + + const selectTime = (type: 'startTime' | 'endTime', time: string) => { + createScheduleForm.setValue(type, time); + } + + const ListContent = () => { + return ( +
+ setMode('create')}/> +
+ ) + } + + const CreateContent = () => { + + const OnceContent = () => { + return ( +
+ selectDate('startDate', date)} + setEndDate={(date: Date | undefined) => selectDate('endDate', date)} + /> +
+ ) + } + + const DailyContent = () => { + return null; + } + + const DefaultContent = () => { + return ( + ( + + { + dayLabelList.map((day) => ( + + {day.label} + + )) + } + + ) + ) + } + + const renderContent = () => { + switch (type) { + case 'Once': + return ; + case 'Daily': + return ; + default: + return ; + } + } + + return ( +
+
+ +
+ +
+ +
+ + + ( + + + + + )} + /> +
+ + +
+ {ScheduleTypeLabel[type as keyof typeof ScheduleTypeLabel]} +
+
+ +
+
+ {renderContent()} +
+
+ {}} + endTime='' + setEndTime={(time: string | undefined) => {}} + /> +
+
setMode('list')} + > + + 취소 +
+
+ ) + } + + const DetailContent = () => { + return ( +
+ Detail +
+ ) + } + + const UpdateContent = () => { + return ( +
+ Update +
+ ) + } + + const SchedulePopoverContent = () => { + switch(mode) { + case 'list': + return + case 'create': + return + case 'detail': + return + case 'update': + return + } + } + + return ( + +
{date && format(date, "yyyy년 MM월 dd일")}
+ + {} + +
+ ) +} \ No newline at end of file diff --git a/src/ui/component/popover/schedule/TimePickPopover.tsx b/src/ui/component/popover/schedule/TimePickPopover.tsx new file mode 100644 index 0000000..48255b3 --- /dev/null +++ b/src/ui/component/popover/schedule/TimePickPopover.tsx @@ -0,0 +1,135 @@ +import { Button } from "@/components/ui/button"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; + +interface BaseProps { + disabled: boolean; + popoverAlign: 'start' | 'end'; +} + +interface SingleModeProps extends BaseProps { + mode: 'single'; + time: string | undefined; + setTime: (time: string | undefined) => void; +} + +interface RangeModeProps extends BaseProps { + mode: 'range'; + startTime: string | undefined; + setStartTime: (time: string | undefined) => void; + endTime: string | undefined; + setEndTime: (time: string | undefined) => void; +} + +type TimePickPopoverProps = SingleModeProps | RangeModeProps; + +export const TimePickPopover = ({ ...props }: TimePickPopoverProps) => { + const { mode, disabled, popoverAlign } = props; + + if (mode === 'single') { + return ( +
single
+ ) + } + + // const { startTime, setStartTime, endTime, setEndTime } = props; + + return ( +
+ + + + + + + + 오전 + + + 오후 + + + + + { + [1,2,3,4,5,6,7,8,9,10,11,12].map((time) => ( + + {time.toString().padStart(2, '0')} + + )) + } + + + + + { + Array.from({ length: 60 }).map((_, idx) => ( + + {idx.toString().padStart(0, '2')} + + )) + } + + + + + - + + + + + + + + +
+ ) +} \ No newline at end of file diff --git a/src/ui/component/popover/schedule/TypePickPopover.tsx b/src/ui/component/popover/schedule/TypePickPopover.tsx new file mode 100644 index 0000000..ce9a363 --- /dev/null +++ b/src/ui/component/popover/schedule/TypePickPopover.tsx @@ -0,0 +1,31 @@ +import { PopoverContent } from "@/components/ui/popover" +import { ScheduleTypeLabel, type ScheduleType } from "@/const/schedule/ScheduleType"; +import { useRecord } from "@/hooks/use-record"; + +interface TypePickPopoverProps { + popoverSide : 'left' | 'right'; + setType: (type: ScheduleType) => void; +} + +export const TypePickPopover = ({ popoverSide, setType }: TypePickPopoverProps) => { + const typeLabelList = useRecord(ScheduleTypeLabel).keys.map((key) => { + return { + type: key, + label: ScheduleTypeLabel[key as keyof typeof ScheduleTypeLabel] + } as { type: ScheduleType, label: string}; + }); + return ( + +
+ {typeLabelList.map((type) => ( +
setType(type.type)} + > + {type.label} +
+ ))} +
+
+ ) +} \ No newline at end of file diff --git a/src/ui/page/home/TempPage.tsx b/src/ui/page/home/TempPage.tsx new file mode 100644 index 0000000..bcdc378 --- /dev/null +++ b/src/ui/page/home/TempPage.tsx @@ -0,0 +1,25 @@ +import { PageRouting } from "@/const/PageRouting"; +import { BaseNetwork } from "@/network/BaseNetwork"; +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; + +export const TempPage = () => { + const baseNetwork = new BaseNetwork(); + const navigate = useNavigate(); + useEffect(() => { + const autoLogin = localStorage.getItem('autoLogin') === 'true'; + if (autoLogin) { + try { + (async () => { + await baseNetwork.refreshToken(); + navigate(PageRouting["HOME"].path); + })(); + } catch (err) { + localStorage.setItem('autoLogin', 'false'); + navigate(PageRouting["LOGIN"].path); + } + } + }, []); + + return (
); +} \ No newline at end of file