Skip to content

Commit 2ca3741

Browse files
authored
Merge pull request #155 from imaginer-dev/31-일정-수정-버튼을-클릭시-DB에-UPDATE-할-수-있어야-한다
31 일정 수정 버튼을 클릭시 db에 update 할 수 있어야 한다
2 parents fdbeddd + 29640bd commit 2ca3741

29 files changed

+442
-99
lines changed

src/App.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import MyCalendarPage from './pages/MyCalendarPage';
1+
import Calendar from './components/common/Calendar';
22

33
function App() {
4-
54
return (
65
<div>
76
<header className="relative z-10">
@@ -53,7 +52,6 @@ function App() {
5352
</main>
5453
</div>
5554
);
56-
5755
}
5856

5957
export default App;

src/apis/groupScheduleApis.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import supabase from '@/supabase';
2+
import { Member } from '@/types/Member';
3+
4+
export const getOneGroupSchedule = async (scheduleId: string) => {
5+
const { data, error } = await supabase.from('group_schedules').select('*').eq('id', +scheduleId);
6+
7+
if (error) {
8+
throw error;
9+
}
10+
11+
if (!data) {
12+
throw new Error('데이터를 찾을 수 없습니다.');
13+
}
14+
15+
return data[0];
16+
};
17+
18+
interface UpdateGroupSchedule {
19+
name: string;
20+
description: string;
21+
startDate: string;
22+
endDate: string;
23+
memo: string;
24+
scheduleId: string;
25+
}
26+
27+
export const updateGroupSchedule = async ({
28+
name,
29+
description,
30+
startDate,
31+
endDate,
32+
memo,
33+
scheduleId,
34+
}: UpdateGroupSchedule) => {
35+
const { data, error } = await supabase
36+
.from('group_schedules')
37+
.update({
38+
title: name,
39+
description,
40+
start_date: startDate,
41+
end_date: endDate,
42+
memo,
43+
})
44+
.eq('id', +scheduleId);
45+
46+
if (error) {
47+
throw error;
48+
}
49+
50+
return data;
51+
};
52+
53+
interface UpdateGroupScheduleMember {
54+
updatedMemberList: Member[];
55+
groupId: string;
56+
}
57+
58+
export const updateGroupScheduleMember = async ({ updatedMemberList, groupId }: UpdateGroupScheduleMember) => {
59+
const { error: deleteError } = await supabase.from('group_user_ralations').delete().eq('group_id', groupId);
60+
if (deleteError) {
61+
throw deleteError;
62+
}
63+
64+
const { data, error: insertError } = await supabase.from('group_user_ralations').insert(
65+
updatedMemberList.map((member) => ({
66+
group_id: +groupId,
67+
user_id: member.id,
68+
})),
69+
);
70+
71+
if (insertError) {
72+
throw insertError;
73+
}
74+
75+
return data;
76+
};
77+
78+
export const getAllGroupMembers = async (groupId: string) => {
79+
// group_user_ralations 의 응답 결과의 user_id를 포함하는 profile리스트를 받아온다.
80+
const { data, error } = await supabase.from('group_user_ralations').select('user_id').eq('group_id', +groupId);
81+
82+
if (error) {
83+
throw error;
84+
}
85+
86+
if (!data) {
87+
throw new Error('데이터를 찾을 수 없습니다.');
88+
}
89+
90+
const { data: allUserProfile, error: getProfileError } = await supabase
91+
.from('profiles')
92+
.select('*')
93+
.in(
94+
'id',
95+
data.map((d) => d.user_id),
96+
);
97+
98+
if (getProfileError) {
99+
throw getProfileError;
100+
}
101+
102+
return allUserProfile;
103+
};

src/components/GroupForm/GroupForm.tsx renamed to src/components/Group/GroupForm.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import GroupFormDescriptionInput from './GroupFormDescriptionInput';
44
import GroupFormDateInput from './GroupFormDateInput';
55
import UserInvite from '../common/UserInvite';
66
import GroupFormMemoInput from './GroupFormMemoInput';
7+
import { Member } from '@/types/Member';
78

89
interface Props {
910
name?: string;
10-
description?: string;
11+
description?: string | null;
1112
startDate?: string;
1213
endDate?: string;
13-
memo?: string;
14-
onSubmit: React.FormEventHandler<HTMLFormElement>;
14+
memo?: string | null;
15+
memberList?: Member[];
16+
onSubmit: (e: React.FormEvent<HTMLFormElement>, userList: Member[]) => void;
1517
}
1618

1719
const GroupForm: FC<Props> = ({
@@ -20,18 +22,26 @@ const GroupForm: FC<Props> = ({
2022
startDate = new Date().toString(),
2123
endDate = new Date().toString(),
2224
memo = '',
25+
memberList = [],
2326
onSubmit,
2427
}) => {
25-
const [member, setMember] = useState<any[]>([]);
28+
const [member, setMember] = useState<Member[]>(memberList);
29+
30+
const onClick = (newMember: Member) => {
31+
setMember((prev) => [...prev, newMember]);
32+
};
2633

2734
return (
28-
<form onSubmit={onSubmit} className="container mx-auto flex max-w-sm flex-1 flex-col gap-4 pb-[50px] pt-4">
35+
<form
36+
onSubmit={(e) => onSubmit(e, member)}
37+
className="container mx-auto flex max-w-sm flex-1 flex-col gap-4 pb-[50px] pt-4"
38+
>
2939
<div className="flex h-full w-full flex-1 flex-col gap-4">
3040
<GroupFormNameInput name={name} />
31-
<GroupFormDescriptionInput description={description} />
41+
<GroupFormDescriptionInput description={description ?? ''} />
3242
<GroupFormDateInput startDate={startDate} endDate={endDate} />
33-
<UserInvite member={member} setMember={setMember} />
34-
<GroupFormMemoInput memo={memo} />
43+
<UserInvite member={member} setMember={onClick} />
44+
<GroupFormMemoInput memo={memo ?? ''} />
3545
</div>
3646
<button type="submit" className="btn btn-outline btn-primary w-full">
3747
저장
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/components/common/Calendar.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { useRef, useState, useEffect } from 'react';
66
import { useEventState } from '@/stores/myEventsStore';
77
import { getPersonalSchedule } from '@/apis/personalScheduleApi';
88

9-
109
type Event = {
1110
title: string;
1211
start: Date | string;
@@ -16,15 +15,7 @@ interface EventCardsProps {
1615
date: Date | string | null;
1716
}
1817

19-
const events = [
20-
{ title: 'Meeting', start: new Date() },
21-
{ title: 'Meeting', start: '2024-05-08' },
22-
{ title: 'Meeting', start: '2024-05-08' },
23-
{ title: 'Meeting', start: '2024-05-08' },
24-
];
25-
26-
export function Calendar() {
27-
18+
export default function Calendar() {
2819
const [calendarHeight, setCalendarHeight] = useState<string | number>('auto');
2920
const calendarRef = useRef<FullCalendar | null>(null);
3021
const [selectedEvents, setSelectedEvents] = useState<Event[]>([]);
@@ -154,7 +145,7 @@ export function Calendar() {
154145
<div className="mt-10">{selectedDate && <EventCards events={selectedEvents} date={selectedDate} />}</div>
155146
</div>
156147
);
157-
};
148+
}
158149

159150
interface EventInfo {
160151
timeText: string;
@@ -174,7 +165,6 @@ function renderEventContent(eventInfo: EventInfo) {
174165
);
175166
}
176167

177-
178168
function EventCards({ events, date }: EventCardsProps) {
179169
const [menuOpen, setMenuOpen] = useState(-1);
180170

@@ -222,4 +212,3 @@ function EventCards({ events, date }: EventCardsProps) {
222212
</div>
223213
);
224214
}
225-

src/components/common/UserInvite.tsx

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,57 @@ import { searchUser } from '../../apis/authApis.ts';
33
import DialogButton from '@/components/common/DialogButton';
44
import { IconUserPlus } from '@/assets/icons';
55
import UserInviteDialog from '@/components/common/UserInviteDialog';
6-
import UserInvited from './UserInvited';
7-
import UserInviteList from './UserInviteList.tsx';
6+
import { Member } from '@/types/Member.ts';
7+
import UserInvited from './UserInvited.tsx';
88

99
interface Props {
10-
member: any;
10+
member: Member[];
1111
setMember: any;
1212
}
1313

1414
const UserInvite: FC<Props> = ({ member, setMember }) => {
1515
const [email, setEamil] = useState('');
16-
const [list, setList] = useState<any[]>([]);
16+
const [list, setList] = useState<Member[]>([]);
1717

1818
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
1919
setEamil(event.target.value);
2020
};
2121

2222
const onSearchClick = () => {
23-
searchUser(email).then((nickNames) => {
24-
if (!nickNames.length) {
23+
searchUser(email).then((searchedUserList) => {
24+
if (!searchedUserList.length) {
2525
alert('해당 닉네임을 찾을 수 없습니다.');
2626
return;
2727
}
28-
nickNames.map(({ user_nickname, id }) => {
29-
setList([
30-
<UserInviteList
31-
user_nickname={user_nickname}
32-
id={id}
33-
key={id + '-UserInviteList'}
34-
onClick={() => {
35-
if (!user_nickname.length) return;
36-
setMember([...member, <UserInvited user_nickname={user_nickname} id={id} key={id + '-Member'} />]);
37-
}}
38-
/>,
39-
]);
40-
});
28+
setList(searchedUserList);
4129
});
4230
};
4331

32+
const onUserItemClick = (clickedUser: Member) => {
33+
setMember(clickedUser);
34+
};
35+
4436
return (
4537
<div>
4638
멤버 초대하기 *
4739
<ul className="flex gap-2">
48-
{member}
40+
{member.map((user) => (
41+
<UserInvited id={user.id} user_nickname={user.user_nickname} key={user.id + '-UserInvited'} />
42+
))}
4943
<li>
5044
<DialogButton
5145
classname={'userInvite bg-base-200 hover:bg-base-300'}
5246
name={<IconUserPlus />}
5347
title={'멤버 찾기'}
5448
desc={''}
55-
children={<UserInviteDialog list={list} onChange={onChange} onSearchClick={onSearchClick} />}
49+
children={
50+
<UserInviteDialog
51+
onUserItemClick={onUserItemClick}
52+
list={list}
53+
onChange={onChange}
54+
onSearchClick={onSearchClick}
55+
/>
56+
}
5657
/>
5758
</li>
5859
</ul>

src/components/common/UserInviteDialog.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import InputForm from './InputForm.tsx';
22
import { FC } from 'react';
33
import { IconSearch } from '@/assets/icons';
4+
import { Member } from '@/types/Member.ts';
5+
import UserInviteList from './UserInviteList.tsx';
46
interface Props {
5-
list: any[];
7+
list: Member[];
68
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
79
onSearchClick: () => void;
10+
onUserItemClick: (clickedUser: Member) => void;
811
}
912

10-
const UserInvite: FC<Props> = ({ list, onChange, onSearchClick }) => {
13+
const UserInvite: FC<Props> = ({ list, onChange, onSearchClick, onUserItemClick }) => {
1114
return (
1215
<div>
1316
<div className="flex items-end">
@@ -17,7 +20,14 @@ const UserInvite: FC<Props> = ({ list, onChange, onSearchClick }) => {
1720
</button>
1821
</div>
1922
<ul id="searchList" role="list" className="divide-y divide-gray-100">
20-
{list}
23+
{list.map((user) => (
24+
<UserInviteList
25+
id={user.id}
26+
onClick={() => onUserItemClick(user)}
27+
user_nickname={user.user_nickname}
28+
key={user.id + '-UserInviteList'}
29+
/>
30+
))}
2131
</ul>
2232
</div>
2333
);

0 commit comments

Comments
 (0)