- 일정 목록 조회 ui 일부 수정 - 일정 상세 조회 로직 구현 중
This commit is contained in:
3
.npmrc
Normal file
3
.npmrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@baekyangdan:registry=https://gitea.bkdhome.p-e.kr/api/packages/baekyangdan/npm/
|
||||||
|
//gitea.bkdhome.p-e.kr/api/packages/baekyangdan/npm/:_authToken=d39c7d88c52806df7522ce2b340b6577c5ec5082
|
||||||
|
always-auth=true
|
||||||
842
package-lock.json
generated
842
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@baekyangdan/core-utils": "^1.0.4",
|
||||||
"@diceui/mention": "^0.8.0",
|
"@diceui/mention": "^0.8.0",
|
||||||
"@hookform/resolvers": "^5.2.2",
|
"@hookform/resolvers": "^5.2.2",
|
||||||
"@radix-ui/react-accordion": "^1.2.12",
|
"@radix-ui/react-accordion": "^1.2.12",
|
||||||
|
|||||||
@@ -5,84 +5,68 @@ export type ColorPaletteType = {
|
|||||||
|
|
||||||
|
|
||||||
export const ColorPalette: Record<any, ColorPaletteType> = {
|
export const ColorPalette: Record<any, ColorPaletteType> = {
|
||||||
Black: {
|
|
||||||
index: 0,
|
|
||||||
style: '#000000'
|
|
||||||
},
|
|
||||||
White: {
|
|
||||||
index: 1,
|
|
||||||
style: '#FFFFFF'
|
|
||||||
},
|
|
||||||
SerenityBlue: {
|
SerenityBlue: {
|
||||||
index: 2,
|
index: 0,
|
||||||
style: '#92A8D1'
|
style: '#92A8D1'
|
||||||
},
|
},
|
||||||
CoralPink: {
|
CoralPink: {
|
||||||
index: 3,
|
index: 1,
|
||||||
style: '#F08080'
|
style: '#F08080'
|
||||||
},
|
},
|
||||||
MintIcing: {
|
MintIcing: {
|
||||||
index: 4,
|
index: 2,
|
||||||
style: '#C1E1C1'
|
style: '#C1E1C1'
|
||||||
},
|
},
|
||||||
Vanilla: {
|
Vanilla: {
|
||||||
index: 5,
|
index: 3,
|
||||||
style: '#FFFACD'
|
style: '#FFFACD'
|
||||||
},
|
},
|
||||||
Wheat: {
|
Wheat: {
|
||||||
index: 6,
|
index: 4,
|
||||||
style: '#F5DEB3'
|
style: '#F5DEB3'
|
||||||
},
|
},
|
||||||
AliceBlue: {
|
|
||||||
index: 7,
|
|
||||||
style: '#F0F8FF'
|
|
||||||
},
|
|
||||||
Lavender: {
|
Lavender: {
|
||||||
index: 8,
|
index: 5,
|
||||||
style: '#E6E6FA'
|
style: '#E6E6FA'
|
||||||
},
|
},
|
||||||
SageGreen: {
|
SageGreen: {
|
||||||
index: 9,
|
index: 6,
|
||||||
style: '#b2ac88'
|
style: '#b2ac88'
|
||||||
},
|
},
|
||||||
CloudWhite: {
|
|
||||||
index: 10,
|
|
||||||
style: '#F2F2ED'
|
|
||||||
},
|
|
||||||
LightGray: {
|
LightGray: {
|
||||||
index: 11,
|
index: 7,
|
||||||
style: '#D3D3D3'
|
style: '#D3D3D3'
|
||||||
},
|
},
|
||||||
LightKhakki: {
|
LightKhakki: {
|
||||||
index: 12,
|
index: 8,
|
||||||
style: '#F0F8E6'
|
style: '#F0F8E6'
|
||||||
},
|
},
|
||||||
DustyRose: {
|
DustyRose: {
|
||||||
index: 13,
|
index: 9,
|
||||||
style: '#D8BFD8'
|
style: '#D8BFD8'
|
||||||
},
|
},
|
||||||
CreamBeige: {
|
CreamBeige: {
|
||||||
index: 14,
|
index: 10,
|
||||||
style: '#FAF0E6'
|
style: '#FAF0E6'
|
||||||
},
|
},
|
||||||
Oatmeal: {
|
Oatmeal: {
|
||||||
index: 15,
|
index: 11,
|
||||||
style: '#FDF5E6'
|
style: '#FDF5E6'
|
||||||
},
|
},
|
||||||
CharcoalLight: {
|
CharcoalLight: {
|
||||||
index: 16,
|
index: 12,
|
||||||
style: '#A9A9A9'
|
style: '#A9A9A9'
|
||||||
},
|
},
|
||||||
PeachCream: {
|
PeachCream: {
|
||||||
index: 17,
|
index: 13,
|
||||||
style: '#FFDAB9'
|
style: '#FFDAB9'
|
||||||
},
|
},
|
||||||
LavenderBlue: {
|
LavenderBlue: {
|
||||||
index: 18,
|
index: 14,
|
||||||
style :'#CCCCFF'
|
style :'#CCCCFF'
|
||||||
},
|
},
|
||||||
SeaFoamGreen: {
|
SeaFoamGreen: {
|
||||||
index: 19,
|
index: 15,
|
||||||
style: '#93E9BE'
|
style: '#93E9BE'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ import type {
|
|||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { RefreshAccessTokenResponse } from '@/data/response/account/RefreshAccessTokenResponse';
|
import { RefreshAccessTokenResponse } from '@/data/response/account/RefreshAccessTokenResponse';
|
||||||
import type { AuthData } from '@/data/AuthData';
|
import type { AuthData } from '@/data/AuthData';
|
||||||
|
import { UnauthorizedCode, UnauthorizedMessage } from '@baekyangdan/core-utils';
|
||||||
export class BaseNetwork {
|
export class BaseNetwork {
|
||||||
protected instance: AxiosInstance;
|
protected instance: AxiosInstance;
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ export class BaseNetwork {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
status === 401
|
status === 401
|
||||||
&& errorCode === 'AccessTokenExpired'
|
&& errorCode === UnauthorizedCode.ACCESS_TOKEN_EXPIRED
|
||||||
&& !originalRequest._retry
|
&& !originalRequest._retry
|
||||||
) {
|
) {
|
||||||
originalRequest._retry = true;
|
originalRequest._retry = true;
|
||||||
@@ -97,7 +97,7 @@ export class BaseNetwork {
|
|||||||
|
|
||||||
if (!authData) {
|
if (!authData) {
|
||||||
useAuthStore.getState().logout();
|
useAuthStore.getState().logout();
|
||||||
return Promise.reject("no refresh token");
|
return Promise.reject(UnauthorizedMessage.INVALID_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isRefreshing) {
|
if (this.isRefreshing) {
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ interface CustomCalendarProps {
|
|||||||
interface EventBarPosition extends ScheduleListData {
|
interface EventBarPosition extends ScheduleListData {
|
||||||
positionStyle: React.CSSProperties;
|
positionStyle: React.CSSProperties;
|
||||||
trackIndex: number;
|
trackIndex: number;
|
||||||
|
isOverflow?: boolean;
|
||||||
|
segmentId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_VISIBLE_EVENTS = 3;
|
|
||||||
const OVERFLOW_TRACK_INDEX = MAX_VISIBLE_EVENTS + 1;
|
|
||||||
const TRACK_HEIGHT = 20;
|
const TRACK_HEIGHT = 20;
|
||||||
const TOP_OFFSET_FROM_CELL = 35;
|
const TOP_OFFSET_FROM_CELL = 35;
|
||||||
const DATE_FORMAT_ARIA = 'EEEE, MMMM do, yyyy';
|
const DATE_FORMAT_ARIA = 'EEEE, MMMM do, yyyy';
|
||||||
@@ -34,6 +34,9 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
const [popoverAlign, setPopoverAlign] = useState<'start' | 'end'>('end');
|
const [popoverAlign, setPopoverAlign] = useState<'start' | 'end'>('end');
|
||||||
const [month, setMonth] = useState(new Date());
|
const [month, setMonth] = useState(new Date());
|
||||||
const [currentDataMonth, setCurrentDataMonth] = useState(month);
|
const [currentDataMonth, setCurrentDataMonth] = useState(month);
|
||||||
|
const [windowSize, setWindowSize] = useState({ width: window.innerWidth, height: window.innerHeight });
|
||||||
|
const [maxVisibleEvents, setMaxVisibleEvents] = useState(3);
|
||||||
|
const [overflowTrackIndex, setOverflowTrackIndex] = useState(maxVisibleEvents + 1);
|
||||||
const [scheduleList, setScheduleList] = useState<Array<ScheduleListData>>([]);
|
const [scheduleList, setScheduleList] = useState<Array<ScheduleListData>>([]);
|
||||||
const [barPositions, setBarPositions] = useState<Array<EventBarPosition>>([]);
|
const [barPositions, setBarPositions] = useState<Array<EventBarPosition>>([]);
|
||||||
const scheduleNetwork = new ScheduleNetwork();
|
const scheduleNetwork = new ScheduleNetwork();
|
||||||
@@ -49,8 +52,28 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateWeekCount();
|
updateWeekCount();
|
||||||
|
const handleResize = () => {
|
||||||
|
setWindowSize({
|
||||||
|
width: window.innerWidth,
|
||||||
|
height: window.innerHeight
|
||||||
|
});
|
||||||
|
if (window.innerHeight >= 850) {
|
||||||
|
setMaxVisibleEvents(3);
|
||||||
|
setOverflowTrackIndex(4);
|
||||||
|
} else {
|
||||||
|
setMaxVisibleEvents(2);
|
||||||
|
setOverflowTrackIndex(3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
updateWeekCount();
|
updateWeekCount();
|
||||||
|
|
||||||
@@ -151,7 +174,7 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
|
|
||||||
let assignedTrack = -1;
|
let assignedTrack = -1;
|
||||||
|
|
||||||
for (let track = 0; track < MAX_VISIBLE_EVENTS; track++) {
|
for (let track = 0; track < maxVisibleEvents; track++) {
|
||||||
let isAvailable = true;
|
let isAvailable = true;
|
||||||
for (const day of eventDays) {
|
for (const day of eventDays) {
|
||||||
const dayKey = format(day, DATE_FORMAT_KEY);
|
const dayKey = format(day, DATE_FORMAT_KEY);
|
||||||
@@ -192,33 +215,50 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
|
|
||||||
const regularPositions: EventBarPosition[] = [];
|
const regularPositions: EventBarPosition[] = [];
|
||||||
|
|
||||||
|
// 달력을 초과한 부분에 대한 처리
|
||||||
|
const visibleDayKeys = Array.from(cellInfoMap.keys());
|
||||||
|
if (!visibleDayKeys || visibleDayKeys.length === 0) return;
|
||||||
|
|
||||||
|
const calendarStart = parse(visibleDayKeys.at(0)!, DATE_FORMAT_KEY, new Date());
|
||||||
|
const calendarEnd = parse(visibleDayKeys.at(-1)!, DATE_FORMAT_KEY, new Date());
|
||||||
|
|
||||||
scheduleListWithTrack.forEach(schedule => {
|
scheduleListWithTrack.forEach(schedule => {
|
||||||
const startKey = format(new Date(schedule.startDate), DATE_FORMAT_KEY);
|
const startDateObj = new Date(schedule.startDate);
|
||||||
const endKey = format(new Date(schedule.endDate), DATE_FORMAT_KEY);
|
const endDateObj = new Date(schedule.endDate);
|
||||||
|
|
||||||
const startInfo = cellInfoMap.get(startKey);
|
const renderStartDate = startDateObj > calendarStart ? startDateObj : calendarStart;
|
||||||
const endInfo = cellInfoMap.get(endKey);
|
const renderEndDate = endDateObj < calendarEnd ? endDateObj : calendarEnd;
|
||||||
|
|
||||||
if (startInfo && endInfo) {
|
const renderStartKey = format(renderStartDate, DATE_FORMAT_KEY);
|
||||||
const startRect = startInfo.rect;
|
const renderEndKey = format(renderEndDate, DATE_FORMAT_KEY);
|
||||||
const endRect = endInfo.rect;
|
|
||||||
|
|
||||||
const baseTop = startRect.top - containerRect.top;
|
const allRenderDays = eachDayOfInterval({ start: renderStartDate, end: renderEndDate });
|
||||||
const top = baseTop + TOP_OFFSET_FROM_CELL + (schedule.trackIndex * (TRACK_HEIGHT + 5));
|
|
||||||
const left = startRect.left - containerRect.left + 5;
|
|
||||||
const width = endRect.right - startRect.left - 10;
|
|
||||||
|
|
||||||
regularPositions.push({
|
let segmentStartDay = renderStartDate;
|
||||||
...schedule,
|
|
||||||
trackIndex: schedule.trackIndex,
|
allRenderDays.forEach((currentDay, index) => {
|
||||||
positionStyle: {
|
const dayOfWeek = currentDay.getDay();
|
||||||
top: `${top}px`,
|
const isLastDayOfEvent = index === allRenderDays.length - 1;
|
||||||
left: `${left}px`,
|
|
||||||
width: `${width}px`,
|
if (dayOfWeek === 6 && !isLastDayOfEvent) {
|
||||||
height: `${TRACK_HEIGHT}px`
|
const segmentEndDay = currentDay;
|
||||||
|
|
||||||
|
createAndPushPosition(
|
||||||
|
regularPositions, schedule,
|
||||||
|
segmentStartDay, segmentEndDay,
|
||||||
|
cellInfoMap, containerRect
|
||||||
|
);
|
||||||
|
|
||||||
|
segmentStartDay = new Date(currentDay);
|
||||||
|
segmentStartDay.setDate(segmentStartDay.getDate() + 1);
|
||||||
|
} else if (isLastDayOfEvent) {
|
||||||
|
createAndPushPosition(
|
||||||
|
regularPositions, schedule,
|
||||||
|
segmentStartDay, currentDay,
|
||||||
|
cellInfoMap, containerRect
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const overflowPositions: EventBarPosition[] = [];
|
const overflowPositions: EventBarPosition[] = [];
|
||||||
@@ -229,7 +269,7 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
const dayRect = dayInfo.rect;
|
const dayRect = dayInfo.rect;
|
||||||
|
|
||||||
const baseTop = dayRect.top - containerRect.top;
|
const baseTop = dayRect.top - containerRect.top;
|
||||||
const top = baseTop + TOP_OFFSET_FROM_CELL + ((OVERFLOW_TRACK_INDEX - 1) * (TRACK_HEIGHT + 5));
|
const top = baseTop + TOP_OFFSET_FROM_CELL + ((overflowTrackIndex - 1) * (TRACK_HEIGHT + 5));
|
||||||
const left = dayRect.left - containerRect.left + 5;
|
const left = dayRect.left - containerRect.left + 5;
|
||||||
const width = dayInfo.cell.clientWidth - 10;
|
const width = dayInfo.cell.clientWidth - 10;
|
||||||
|
|
||||||
@@ -239,7 +279,9 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
startDate: Converter.dateToUTC9(new Date()),
|
startDate: Converter.dateToUTC9(new Date()),
|
||||||
endDate: Converter.dateToUTC9(new Date()),
|
endDate: Converter.dateToUTC9(new Date()),
|
||||||
style: '#9CA3AF',
|
style: '#9CA3AF',
|
||||||
trackIndex: OVERFLOW_TRACK_INDEX,
|
trackIndex: overflowTrackIndex,
|
||||||
|
isOverflow: true,
|
||||||
|
segmentId: dayKey,
|
||||||
positionStyle: {
|
positionStyle: {
|
||||||
top: `${top}px`,
|
top: `${top}px`,
|
||||||
left: `${left}px`,
|
left: `${left}px`,
|
||||||
@@ -250,7 +292,46 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
setBarPositions([...regularPositions, ...overflowPositions]);
|
setBarPositions([...regularPositions, ...overflowPositions]);
|
||||||
}, [scheduleList, month, currentDataMonth]);
|
}, [scheduleList, month, currentDataMonth, windowSize]);
|
||||||
|
|
||||||
|
const createAndPushPosition = (
|
||||||
|
positions: EventBarPosition[],
|
||||||
|
schedule: ScheduleListData & { trackIndex: number },
|
||||||
|
segmentStartDay: Date,
|
||||||
|
segmentEndDay: Date,
|
||||||
|
cellInfoMap: Map<string, { cell: HTMLElement, rect: DOMRect }>,
|
||||||
|
containerRect: DOMRect
|
||||||
|
) => {
|
||||||
|
const renderStartKey = format(segmentStartDay, DATE_FORMAT_KEY);
|
||||||
|
const renderEndKey = format(segmentEndDay, DATE_FORMAT_KEY);
|
||||||
|
|
||||||
|
const startInfo = cellInfoMap.get(renderStartKey);
|
||||||
|
const endInfo = cellInfoMap.get(renderEndKey);
|
||||||
|
|
||||||
|
if (startInfo && endInfo) {
|
||||||
|
const startRect = startInfo.rect;
|
||||||
|
const endRect = endInfo.rect;
|
||||||
|
|
||||||
|
const baseTop = startRect.top - containerRect.top;
|
||||||
|
const top = baseTop + TOP_OFFSET_FROM_CELL + (schedule.trackIndex * (TRACK_HEIGHT + 5));
|
||||||
|
|
||||||
|
const left = startRect.left - containerRect.left + 5;
|
||||||
|
const width = endRect.right - startRect.left - 10;
|
||||||
|
|
||||||
|
positions.push({
|
||||||
|
...schedule,
|
||||||
|
trackIndex: schedule.trackIndex,
|
||||||
|
id: schedule.id,
|
||||||
|
segmentId: `${schedule.id}-${renderStartKey}`,
|
||||||
|
positionStyle: {
|
||||||
|
top: `${top}px`,
|
||||||
|
left: `${left}px`,
|
||||||
|
width: `${width}px`,
|
||||||
|
height: `${TRACK_HEIGHT}px`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleMonthChange = async (month: Date) => {
|
const handleMonthChange = async (month: Date) => {
|
||||||
setMonth(month);
|
setMonth(month);
|
||||||
@@ -313,6 +394,29 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
open={popoverOpen}
|
open={popoverOpen}
|
||||||
onOpenChange={handleOpenChange}
|
onOpenChange={handleOpenChange}
|
||||||
>
|
>
|
||||||
|
{
|
||||||
|
barPositions.map(pos => (
|
||||||
|
<PopoverTrigger
|
||||||
|
className="z-100"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
}}
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
key={pos.segmentId}
|
||||||
|
className={cn(
|
||||||
|
`flex flex-row justify-start items-center absolute z-100`,
|
||||||
|
"py-0.5 px-2 rounded-sm text-xs text-white overflow-hidden"
|
||||||
|
)}
|
||||||
|
style={{...pos.positionStyle, backgroundColor: pos.style}}
|
||||||
|
>
|
||||||
|
{pos.name}
|
||||||
|
</div>
|
||||||
|
</PopoverTrigger>
|
||||||
|
))
|
||||||
|
}
|
||||||
<Calendar
|
<Calendar
|
||||||
mode="single"
|
mode="single"
|
||||||
className="h-full w-full border border-indigo-200 rounded-lg shadow-sm shadow-indigo-200"
|
className="h-full w-full border border-indigo-200 rounded-lg shadow-sm shadow-indigo-200"
|
||||||
@@ -350,20 +454,7 @@ export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{
|
|
||||||
barPositions.map(pos => (
|
|
||||||
<div
|
|
||||||
key={pos.id}
|
|
||||||
className={cn(
|
|
||||||
`flex flex-row justify-start items-center absolute`,
|
|
||||||
"py-0.5 px-2 rounded-sm text-xs text-white overflow-hidden pointer-events-none"
|
|
||||||
)}
|
|
||||||
style={{...pos.positionStyle, backgroundColor: pos.style}}
|
|
||||||
>
|
|
||||||
{pos.name}
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
<SchedulePopover
|
<SchedulePopover
|
||||||
date={selectedDate}
|
date={selectedDate}
|
||||||
open={popoverOpen}
|
open={popoverOpen}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { PopoverContent } from '@/components/ui/popover';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { ScheduleCreateContent } from './content/ScheduleCreateContent';
|
import { ScheduleCreateContent } from './content/ScheduleCreateContent';
|
||||||
import { ScheduleListContent } from './content/ScheduleListContent';
|
import { ScheduleListContent } from './content/ScheduleListContent';
|
||||||
|
import { ScheduleDetailContent } from './content/ScheduleDetailContent';
|
||||||
|
|
||||||
interface ScheduleSheetProps {
|
interface ScheduleSheetProps {
|
||||||
date: Date | undefined;
|
date: Date | undefined;
|
||||||
@@ -12,6 +13,7 @@ interface ScheduleSheetProps {
|
|||||||
|
|
||||||
export const SchedulePopover = ({ date, open, popoverSide, popoverAlign }: ScheduleSheetProps) => {
|
export const SchedulePopover = ({ date, open, popoverSide, popoverAlign }: ScheduleSheetProps) => {
|
||||||
const [mode, setMode] = useState<'list' | 'create' | 'detail' | 'update'>('list');
|
const [mode, setMode] = useState<'list' | 'create' | 'detail' | 'update'>('list');
|
||||||
|
const [detailId, setDetailId] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
@@ -42,6 +44,7 @@ export const SchedulePopover = ({ date, open, popoverSide, popoverAlign }: Sched
|
|||||||
case 'list':
|
case 'list':
|
||||||
return <ScheduleListContent
|
return <ScheduleListContent
|
||||||
setMode={setMode}
|
setMode={setMode}
|
||||||
|
setId={setDetailId}
|
||||||
date={date}
|
date={date}
|
||||||
popoverAlign={popoverAlign}
|
popoverAlign={popoverAlign}
|
||||||
popoverSide={popoverSide}
|
popoverSide={popoverSide}
|
||||||
@@ -56,7 +59,14 @@ export const SchedulePopover = ({ date, open, popoverSide, popoverAlign }: Sched
|
|||||||
open={open}
|
open={open}
|
||||||
/>
|
/>
|
||||||
case 'detail':
|
case 'detail':
|
||||||
return <DetailContent />
|
return <ScheduleDetailContent
|
||||||
|
setMode={setMode}
|
||||||
|
date={date}
|
||||||
|
popoverAlign={popoverAlign}
|
||||||
|
popoverSide={popoverSide}
|
||||||
|
open={open}
|
||||||
|
id={detailId}
|
||||||
|
/>
|
||||||
case 'update':
|
case 'update':
|
||||||
return <UpdateContent />
|
return <UpdateContent />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,5 +11,9 @@ export interface ScheduleCreateContentProps extends BaseProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ScheduleListContentProps extends BaseProps {
|
export interface ScheduleListContentProps extends BaseProps {
|
||||||
|
setId: (id: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScheduleDetailContentProps extends BaseProps {
|
||||||
|
id: string;
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ export const ScheduleCreateContent = ({ date, setMode, popoverSide, popoverAlign
|
|||||||
endTime: getCurrentTimeString('standard'),
|
endTime: getCurrentTimeString('standard'),
|
||||||
type: "once",
|
type: "once",
|
||||||
status: "yet",
|
status: "yet",
|
||||||
style: getPaletteByKey('Black').style,
|
style: getPaletteByKey('SerenityBlue').style,
|
||||||
dayList: "",
|
dayList: "",
|
||||||
participantList: []
|
participantList: []
|
||||||
}
|
}
|
||||||
@@ -312,6 +312,7 @@ export const ScheduleCreateContent = ({ date, setMode, popoverSide, popoverAlign
|
|||||||
"bg-white text-red-400",
|
"bg-white text-red-400",
|
||||||
"hover:text-white hover:bg-red-400"
|
"hover:text-white hover:bg-red-400"
|
||||||
)}
|
)}
|
||||||
|
onClick={() => setMode('list')}
|
||||||
>
|
>
|
||||||
취소
|
취소
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import type { ScheduleDetailContentProps } from './ContentProps';
|
||||||
|
|
||||||
|
export const ScheduleDetailContent = ({ date, setMode, popoverSide, popoverAlign, id }: ScheduleDetailContentProps) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="w-full h-full flex flex-col justify-start items-start gap-4"
|
||||||
|
>
|
||||||
|
{id}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ import { ScheduleListData } from "@/data/response";
|
|||||||
import { Converter } from "@/util/Converter";
|
import { Converter } from "@/util/Converter";
|
||||||
import { ScheduleListTile } from "../tile/ScheduleListTile";
|
import { ScheduleListTile } from "../tile/ScheduleListTile";
|
||||||
|
|
||||||
export const ScheduleListContent = ({ date, setMode, popoverAlign, popoverSide, open }: ScheduleListContentProps) => {
|
export const ScheduleListContent = ({ date, setMode, popoverAlign, popoverSide, open, setId }: ScheduleListContentProps) => {
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [scheduleList, setScheduleList] = useState<Array<ScheduleListData>>([]);
|
const [scheduleList, setScheduleList] = useState<Array<ScheduleListData>>([]);
|
||||||
const scheduleNetwork = new ScheduleNetwork();
|
const scheduleNetwork = new ScheduleNetwork();
|
||||||
@@ -65,6 +65,11 @@ export const ScheduleListContent = ({ date, setMode, popoverAlign, popoverSide,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const moveToDetail = (id: string) => {
|
||||||
|
setId(id);
|
||||||
|
setMode('detail');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full flex flex-col gap-4">
|
<div className="w-full h-full flex flex-col gap-4">
|
||||||
<div className="relative w-full h-10 border-b border-b-indigo-300 flex flex-row items-center justify-center">
|
<div className="relative w-full h-10 border-b border-b-indigo-300 flex flex-row items-center justify-center">
|
||||||
@@ -84,6 +89,7 @@ export const ScheduleListContent = ({ date, setMode, popoverAlign, popoverSide,
|
|||||||
<div className="w-full h-full flex flex-col justify-start items-start gap-3">
|
<div className="w-full h-full flex flex-col justify-start items-start gap-3">
|
||||||
{ scheduleList.map(schedule => (
|
{ scheduleList.map(schedule => (
|
||||||
<ScheduleListTile
|
<ScheduleListTile
|
||||||
|
onClick={moveToDetail}
|
||||||
data={schedule}
|
data={schedule}
|
||||||
setMode={setMode}
|
setMode={setMode}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -72,14 +72,14 @@ export const ColorPickPopover = ({ setColor }: ColorPickPopoverProps) => {
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
"text-indigo-300 group-hover:text-white transition-all duration-150"
|
"text-indigo-300 select-none group-hover:text-white text-sm transition-all duration-150"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{ seeMore ? " 접기 " : "더 보기"}
|
{ seeMore ? " 접기 " : "더 보기"}
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-0 h-0 border-l-8 border-l-transparent border-r-8 border-r-transparent border-b-14 border-b-indigo-300",
|
"w-0 h-0 border-l-6 border-l-transparent border-r-6 border-r-transparent border-b-10 border-b-indigo-300",
|
||||||
"group-hover:border-b-white trnasition-all duration-150",
|
"group-hover:border-b-white trnasition-all duration-150",
|
||||||
!seeMore && "rotate-180"
|
!seeMore && "rotate-180"
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ export const TimePickPopover = ({ ...props }: TimePickPopoverProps) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent
|
<PopoverContent
|
||||||
className="w-fit h-42 flex flex-row p-0"
|
className="200 w-fit h-42 flex flex-row p-0"
|
||||||
align={'end'}
|
align={'end'}
|
||||||
side={popoverAlign === 'start' ? 'bottom' : 'top'}
|
side={popoverAlign === 'start' ? 'bottom' : 'top'}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,17 +5,29 @@ import { Converter } from "@/util/Converter";
|
|||||||
interface ScheduleListTileProps {
|
interface ScheduleListTileProps {
|
||||||
setMode: (mode: 'list' | 'create' | 'detail' | 'update') => void;
|
setMode: (mode: 'list' | 'create' | 'detail' | 'update') => void;
|
||||||
data: ScheduleListData;
|
data: ScheduleListData;
|
||||||
|
onClick: (id: string) => void;
|
||||||
}
|
}
|
||||||
export const ScheduleListTile = ({ setMode, data }: ScheduleListTileProps) => {
|
export const ScheduleListTile = ({ setMode, data, onClick }: ScheduleListTileProps) => {
|
||||||
const formatter = Converter.isoStringToFormattedString;
|
const formatter = Converter.isoStringToFormattedString;
|
||||||
|
|
||||||
|
const handleOnClickTile = (id: string) => {
|
||||||
|
onClick(id);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full h-15 rounded-sm border flex flex-row items-center cursor-default group"
|
className="w-full select-none h-15 rounded-sm border shadow-sm shadow-indigo-200 flex flex-row items-center cursor-default group"
|
||||||
|
style={{
|
||||||
|
borderColor: data.style
|
||||||
|
}}
|
||||||
|
onClick={() => handleOnClickTile(data.id)}
|
||||||
>
|
>
|
||||||
<div className={`w-6 h-full rounded-l-xs group-hover:w-10 transition-all duration-150`} style={{backgroundColor: `${data.style}CC`}} />
|
<div className={`w-6 h-full rounded-l-xs group-hover:w-10 transition-all duration-150`} style={{backgroundColor: `${data.style}CC`}} />
|
||||||
<div
|
<div
|
||||||
className="w-[calc(100%-24px)] px-2 h-full flex flex-col justify-center items-start"
|
className="w-[calc(100%-24px)] border-l px-2 h-full flex flex-col justify-center items-start"
|
||||||
|
style={{
|
||||||
|
borderLeftColor: data.style
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex-6 h-full flex flex-row justify-end items-start">
|
<div className="flex-6 h-full flex flex-row justify-end items-start">
|
||||||
<span
|
<span
|
||||||
|
|||||||
Reference in New Issue
Block a user