Skip to content

Commit a9efe32

Browse files
authored
Merge branch 'dev' into 127--ui--calendarmain
2 parents 25019e7 + 2ca3741 commit a9efe32

29 files changed

+473
-94
lines changed

โ€Žsrc/App.tsxโ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import Calendar from './components/common/Calendar.tsx';
1+
import Calendar from './components/common/Calendar';
2+
23

34
function App() {
45
return (
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: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
import { FC } from 'react';
1+
import { FC, useState } from 'react';
22
import GroupFormNameInput from './GroupFormNameInput';
33
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,16 +22,26 @@ const GroupForm: FC<Props> = ({
2022
startDate = new Date().toString(),
2123
endDate = new Date().toString(),
2224
memo = '',
25+
memberList = [],
2326
onSubmit,
2427
}) => {
28+
const [member, setMember] = useState<Member[]>(memberList);
29+
30+
const onClick = (newMember: Member) => {
31+
setMember((prev) => [...prev, newMember]);
32+
};
33+
2534
return (
26-
<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+
>
2739
<div className="flex h-full w-full flex-1 flex-col gap-4">
2840
<GroupFormNameInput name={name} />
29-
<GroupFormDescriptionInput description={description} />
41+
<GroupFormDescriptionInput description={description ?? ''} />
3042
<GroupFormDateInput startDate={startDate} endDate={endDate} />
31-
<UserInvite />
32-
<GroupFormMemoInput memo={memo} />
43+
<UserInvite member={member} setMember={onClick} />
44+
<GroupFormMemoInput memo={memo ?? ''} />
3345
</div>
3446
<button type="submit" className="btn btn-outline btn-primary w-full">
3547
์ €์žฅ
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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type Event = {
1818
};
1919
*/
2020

21+
2122
interface EventInfo {
2223
timeText: string;
2324
event: {
@@ -213,6 +214,7 @@ export default function Calendar() {
213214
<div className="mt-10">{selectedDate && <EventCards events={selectedEvents} date={selectedDate} />}</div>
214215
</div>
215216
);
217+
216218
}
217219

218220
function renderEventContent(eventInfo: EventInfo) {

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

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,59 @@
1-
import { FC } from 'react';
1+
import { FC, useState } from 'react';
2+
import { searchUser } from '../../apis/authApis.ts';
23
import DialogButton from '@/components/common/DialogButton';
34
import { IconUserPlus } from '@/assets/icons';
45
import UserInviteDialog from '@/components/common/UserInviteDialog';
6+
import { Member } from '@/types/Member.ts';
7+
import UserInvited from './UserInvited.tsx';
8+
9+
interface Props {
10+
member: Member[];
11+
setMember: any;
12+
}
13+
14+
const UserInvite: FC<Props> = ({ member, setMember }) => {
15+
const [email, setEamil] = useState('');
16+
const [list, setList] = useState<Member[]>([]);
17+
18+
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
19+
setEamil(event.target.value);
20+
};
21+
22+
const onSearchClick = () => {
23+
searchUser(email).then((searchedUserList) => {
24+
if (!searchedUserList.length) {
25+
alert('ํ•ด๋‹น ๋‹‰๋„ค์ž„์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.');
26+
return;
27+
}
28+
setList(searchedUserList);
29+
});
30+
};
31+
32+
const onUserItemClick = (clickedUser: Member) => {
33+
setMember(clickedUser);
34+
};
535

6-
export const UserInvite: FC = () => {
736
return (
837
<div>
938
๋ฉค๋ฒ„ ์ดˆ๋Œ€ํ•˜๊ธฐ *
1039
<ul className="flex gap-2">
40+
{member.map((user) => (
41+
<UserInvited id={user.id} user_nickname={user.user_nickname} key={user.id + '-UserInvited'} />
42+
))}
1143
<li>
1244
<DialogButton
1345
classname={'userInvite bg-base-200 hover:bg-base-300'}
1446
name={<IconUserPlus />}
1547
title={'๋ฉค๋ฒ„ ์ฐพ๊ธฐ'}
1648
desc={''}
17-
children={<UserInviteDialog />}
49+
children={
50+
<UserInviteDialog
51+
onUserItemClick={onUserItemClick}
52+
list={list}
53+
onChange={onChange}
54+
onSearchClick={onSearchClick}
55+
/>
56+
}
1857
/>
1958
</li>
2059
</ul>

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

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,16 @@
11
import InputForm from './InputForm.tsx';
2-
import { searchUser } from '../../apis/authApis.ts';
3-
import { FC, useState } from 'react';
2+
import { FC } from 'react';
43
import { IconSearch } from '@/assets/icons';
4+
import { Member } from '@/types/Member.ts';
55
import UserInviteList from './UserInviteList.tsx';
6+
interface Props {
7+
list: Member[];
8+
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
9+
onSearchClick: () => void;
10+
onUserItemClick: (clickedUser: Member) => void;
11+
}
612

7-
const UserInvite: FC = () => {
8-
const [email, setEamil] = useState('');
9-
const [list, setList] = useState<any[]>([]);
10-
11-
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
12-
setEamil(event.target.value);
13-
};
14-
15-
const onSearchClick = () => {
16-
searchUser(email).then((nickNames) => {
17-
if (!nickNames.length) {
18-
alert('ํ•ด๋‹น ๋‹‰๋„ค์ž„์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.');
19-
return;
20-
}
21-
setList(
22-
nickNames.map(({ user_nickname, id }) => {
23-
return <UserInviteList user_nickname={user_nickname} id={id} key={id + '-UserInviteList'} />;
24-
}),
25-
);
26-
return list;
27-
});
28-
};
29-
13+
const UserInvite: FC<Props> = ({ list, onChange, onSearchClick, onUserItemClick }) => {
3014
return (
3115
<div>
3216
<div className="flex items-end">
@@ -36,7 +20,14 @@ const UserInvite: FC = () => {
3620
</button>
3721
</div>
3822
<ul id="searchList" role="list" className="divide-y divide-gray-100">
39-
{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+
))}
4031
</ul>
4132
</div>
4233
);

0 commit comments

Comments
ย (0)