Skip to content

Commit 294f170

Browse files
authored
Merge pull request #143 from imaginer-dev/24-add-new-event
feature: ๋‹ฌ๋ ฅ์— ์ผ์ • ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
2 parents c0925ff + 54238fd commit 294f170

File tree

7 files changed

+198
-65
lines changed

7 files changed

+198
-65
lines changed

โ€Žsrc/App.tsxโ€Ž

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,7 @@
1-
import { Calendar } from './components/common/Calendar.tsx';
1+
import MyCalendarPage from './pages/MyCalendarPage';
22

33
function App() {
4-
return (
5-
<div>
6-
<header className="relative z-10">
7-
<div className="drawer">
8-
<input id="my-drawer-3" type="checkbox" className="drawer-toggle" />
9-
<div className="drawer-content flex flex-col">
10-
{/* Navbar */}
11-
<div className="navbar w-full">
12-
<div className="flex-none lg:hidden">
13-
<label htmlFor="my-drawer-3" aria-label="open sidebar" className="btn btn-square btn-ghost">
14-
<svg
15-
xmlns="http://www.w3.org/2000/svg"
16-
fill="none"
17-
viewBox="0 0 24 24"
18-
className="inline-block h-6 w-6 stroke-current"
19-
>
20-
<path
21-
strokeLinecap="round"
22-
strokeLinejoin="round"
23-
strokeWidth="2"
24-
d="M4 6h16M4 12h16M4 18h16"
25-
></path>
26-
</svg>
27-
</label>
28-
</div>
29-
<div className="flex-1">
30-
<h1 className="flex-end min-w-40 rounded bg-base-200 p-2 text-center text-sm">๊ฐœ์ธ ์ผ์ • ์บ˜๋ฆฐ๋”</h1>
31-
</div>
32-
</div>
33-
</div>
34-
<div className="drawer-side">
35-
<label htmlFor="my-drawer-3" aria-label="close sidebar" className="drawer-overlay"></label>
36-
<ul className="menu min-h-full w-80 bg-base-200 p-4">
37-
{/* Sidebar content here */}
38-
<li>
39-
<a>๊ทธ๋ฃน ์ผ์ • ์บ˜๋ฆฐ๋” 1</a>
40-
</li>
41-
<li>
42-
<a>๊ทธ๋ฃน ์ผ์ • ์บ˜๋ฆฐ๋” 2</a>
43-
</li>
44-
</ul>
45-
</div>
46-
</div>
47-
</header>
48-
<main className="z-1 relative flex-grow">
49-
<div className="ml-auto max-w-7xl px-4 sm:px-6 lg:px-8">
50-
<div className="rounded bg-white p-6 px-4 sm:px-0">
51-
<Calendar />
52-
</div>
53-
</div>
54-
</main>
55-
</div>
56-
);
4+
return <MyCalendarPage />;
575
}
586

597
export default App;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { useEventState } from '@/stores/myEventsStore.ts';
2+
import DialogButton from '@/components/common/DialogButton';
3+
import { InputRef } from '../common/InputForm.tsx';
4+
import { useState, useRef } from 'react';
5+
6+
const CreateEventButton = () => {
7+
const { addEvents } = useEventState();
8+
const [eventTitle, setTitle] = useState('');
9+
const [startDate, setStartDate] = useState('');
10+
const [endDate, setEndDate] = useState('');
11+
const titleRef = useRef<HTMLInputElement>(null);
12+
const startRef = useRef<HTMLInputElement>(null);
13+
const endRef = useRef<HTMLInputElement>(null);
14+
15+
const onTitleChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
16+
setTitle(event.target.value);
17+
};
18+
19+
const onStartDateChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
20+
setStartDate(event.target.value);
21+
};
22+
23+
const onEndDateChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
24+
setEndDate(event.target.value);
25+
};
26+
27+
const onCreateClicked = () => {
28+
if (eventTitle !== '' && startDate !== '') {
29+
addEvents({ title: eventTitle, start: startDate, end: endDate === '' ? startDate : endDate });
30+
}
31+
setTitle('');
32+
setStartDate('');
33+
setEndDate('');
34+
if (titleRef.current) {
35+
titleRef.current.value = '';
36+
}
37+
if (startRef.current) {
38+
startRef.current.value = '';
39+
}
40+
if (endRef.current) {
41+
endRef.current.value = '';
42+
}
43+
};
44+
45+
const eventForm = (
46+
<div>
47+
<hr className="mt-1" />
48+
<InputRef title="์ผ์ • ์ œ๋ชฉ" placeholder="์ƒˆ ์ผ์ • ์ œ๋ชฉ" onChange={onTitleChanged} ref={titleRef} />
49+
<InputRef title="์‹œ์ž‘ ๋‚ ์งœ" placeholder="YYYY-MM-DD" onChange={onStartDateChanged} ref={startRef} />
50+
<InputRef title="๋ ๋‚ ์งœ" placeholder="YYYY-MM-DD" onChange={onEndDateChanged} ref={endRef} />
51+
<hr className="mb-2 mt-2" />
52+
<button className="btn w-full bg-primary text-base-100" onClick={onCreateClicked}>
53+
์ถ”๊ฐ€ํ•˜๊ธฐ
54+
</button>
55+
</div>
56+
);
57+
return (
58+
<div className="p-8">
59+
<DialogButton
60+
classname="btn bg-primary text-base-100 w-full"
61+
name={'์ƒˆ ์ผ์ • ์ถ”๊ฐ€ํ•˜๊ธฐ'}
62+
title={'์ผ์ • ์ถ”๊ฐ€'}
63+
desc={''}
64+
children={eventForm}
65+
/>
66+
</div>
67+
);
68+
};
69+
export default CreateEventButton;

โ€Žsrc/components/common/Calendar.tsxโ€Ž

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,9 @@ import FullCalendar from '@fullcalendar/react';
22
import dayGridPlugin from '@fullcalendar/daygrid';
33
import interactionPlugin from '@fullcalendar/interaction';
44
import { useRef, useState, useEffect } from 'react';
5+
import { useEventState } from '@/stores/myEventsStore';
56

6-
const events = [
7-
{ title: 'Meeting', start: new Date() },
8-
{ title: 'Meeting', start: '2024-05-08' },
9-
{ title: 'Meeting', start: '2024-05-08' },
10-
{ title: 'Meeting', start: '2024-05-08' },
11-
];
12-
13-
export function Calendar() {
7+
const Calendar: React.FC = () => {
148
const [calendarHeight, setCalendarHeight] = useState<string | number>('auto');
159
const calendarRef = useRef<FullCalendar | null>(null);
1610
const handlePrev = () => {
@@ -76,6 +70,7 @@ export function Calendar() {
7670
};
7771
}, [updateSize]);
7872

73+
const events = useEventState();
7974
return (
8075
<div>
8176
<FullCalendar
@@ -116,7 +111,7 @@ export function Calendar() {
116111
/>
117112
</div>
118113
);
119-
}
114+
};
120115

121116
interface EventInfo {
122117
timeText: string;
@@ -135,3 +130,5 @@ function renderEventContent(eventInfo: EventInfo) {
135130
</>
136131
);
137132
}
133+
134+
export default Calendar;

โ€Žsrc/components/common/InputForm.tsxโ€Ž

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { HTMLProps } from 'react';
1+
import { HTMLProps, forwardRef } from 'react';
22

33
interface Props extends HTMLProps<HTMLInputElement> {
44
title: string;
55
placeholder: string;
6-
hint: string;
6+
hint?: string;
77
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
88
error?: boolean;
99
errorText?: string;
@@ -33,4 +33,31 @@ const InputForm: React.FC<Props> = ({ title, placeholder, hint, onChange, error
3333
);
3434
};
3535

36+
export const InputRef: React.FC<Props> = forwardRef(
37+
({ title, placeholder, hint, onChange, error = false, errorText = '', ...rest }, ref) => {
38+
return (
39+
<label htmlFor={rest.id} className="form-control w-full">
40+
<div className="label">
41+
<span className="label-text">{title}</span>
42+
</div>
43+
<input
44+
id={rest.id}
45+
placeholder={placeholder}
46+
className="input input-bordered w-full"
47+
onChange={onChange}
48+
ref={ref}
49+
{...rest}
50+
/>
51+
{error || hint ? (
52+
<div className="label flex h-8 flex-row items-center">
53+
<span className={`label-text-alt ${error ? 'text-error' : ''}`}>{error ? errorText : hint}</span>
54+
</div>
55+
) : (
56+
''
57+
)}
58+
</label>
59+
);
60+
},
61+
);
62+
3663
export default InputForm;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import Calendar from '../components/common/Calendar.tsx';
2+
import CreateEventButton from '@/components/MyCalendar/CreateEventButton.tsx';
3+
4+
const MyCalendarPage: React.FC = () => {
5+
return (
6+
<div>
7+
<header className="relative z-10">
8+
<div className="drawer">
9+
<input id="my-drawer-3" type="checkbox" className="drawer-toggle" />
10+
<div className="drawer-content flex flex-col">
11+
{/* Navbar */}
12+
<div className="navbar w-full">
13+
<div className="flex-none lg:hidden">
14+
<label htmlFor="my-drawer-3" aria-label="open sidebar" className="btn btn-square btn-ghost">
15+
<svg
16+
xmlns="http://www.w3.org/2000/svg"
17+
fill="none"
18+
viewBox="0 0 24 24"
19+
className="inline-block h-6 w-6 stroke-current"
20+
>
21+
<path
22+
strokeLinecap="round"
23+
strokeLinejoin="round"
24+
strokeWidth="2"
25+
d="M4 6h16M4 12h16M4 18h16"
26+
></path>
27+
</svg>
28+
</label>
29+
</div>
30+
<div className="flex-1">
31+
<h1 className="base-200 min-w-40 p-2 text-center">๊ฐœ์ธ ์ผ์ • ์บ˜๋ฆฐ๋”</h1>
32+
</div>
33+
</div>
34+
</div>
35+
<div className="drawer-side">
36+
<label htmlFor="my-drawer-3" aria-label="close sidebar" className="drawer-overlay"></label>
37+
<ul className="menu min-h-full w-80 bg-base-200 p-4">
38+
{/* Sidebar content here */}
39+
<li>
40+
<a>๊ทธ๋ฃน ์ผ์ • ์บ˜๋ฆฐ๋” 1</a>
41+
</li>
42+
<li>
43+
<a>๊ทธ๋ฃน ์ผ์ • ์บ˜๋ฆฐ๋” 2</a>
44+
</li>
45+
</ul>
46+
</div>
47+
</div>
48+
</header>
49+
<main className="z-1 relative flex-grow">
50+
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
51+
<div className="rounded bg-white p-6 px-4 sm:px-0">
52+
<Calendar />
53+
</div>
54+
</div>
55+
</main>
56+
<CreateEventButton />
57+
</div>
58+
);
59+
};
60+
61+
export default MyCalendarPage;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { create } from 'zustand';
2+
import { Events } from '../utils/index.ts';
3+
4+
const initialEventsState: Events[] = [
5+
{ title: 'Meeting', start: new Date(), end: new Date() },
6+
{ title: 'Meeting2', start: '2024-05-08', end: '2024-05-12', backgroundColor: 'red', borderColor: 'red' },
7+
{ title: 'Meeting3', start: '2024-05-08', end: '2024-05-10', backgroundColor: 'green', borderColor: 'green' },
8+
{ title: 'Meeting4', start: '2024-05-08', end: '2024-05-11' },
9+
];
10+
11+
interface EventsState {
12+
events: Events[];
13+
addEvents: (event: Events) => void;
14+
initEvents: () => void;
15+
}
16+
17+
export const useEventState = create<EventsState>()((set) => ({
18+
events: [...initialEventsState],
19+
20+
addEvents: (newEvent: Events) => set((state) => ({ events: [...state.events, newEvent] })),
21+
initEvents: () => set(() => ({ events: [] })),
22+
}));

โ€Žsrc/utils/index.tsโ€Ž

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export interface Events {
2+
id?: string;
3+
title: string;
4+
start: Date | string;
5+
end: Date | string;
6+
backgroundColor?: string;
7+
borderColor?: string;
8+
textColor?: string;
9+
}

0 commit comments

Comments
ย (0)