Skip to content

Commit 76c2295

Browse files
committed
✨ feat : Add class user info api
- Add API to get class user information via cid passed as a query - Modify login state management logic - Add permission enum for class user Related issue: #104
1 parent 47e6676 commit 76c2295

File tree

13 files changed

+121
-80
lines changed

13 files changed

+121
-80
lines changed

src/api/apiUtils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ api.interceptors.response.use(
4040
}
4141
} catch (error) {
4242
console.error('トークンの有効期限が切れました。');
43+
window.location.href = '/intro';
4344
}
4445
}
4546
return Promise.reject(error);

src/api/classUser/getClassInfo.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import req from '../apiUtils';
2+
3+
const getClassInfo = async (uId: number, cId: number) => {
4+
const response = await req(`/cu/${uId}/${cId}/info`, 'get', 'gin');
5+
console.log(response);
6+
7+
return response.data;
8+
};
9+
10+
export default getClassInfo;

src/app/intro/googleLogin/page.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const Page = () => {
1717
const setRefreshToken = useSetRecoilState(refreshTokenState);
1818
const router = useRouter();
1919
useEffect(() => {
20-
console.log(code);
2120
if (code) {
2221
postGoogleLogin(code).then(res => {
2322
if (res.user) {

src/app/layout.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import type {Metadata} from 'next';
22
import {Inter} from 'next/font/google';
33
import {Navbar} from '../components/navbar';
44
import {Footer} from '../components/footer';
5-
import Protect from '../components/protect';
65
import RecoilRootContainer from '../components/RecoilRootContainer';
76
import './globals.css';
87
import '@/src/styles/variable.css';
@@ -19,15 +18,13 @@ const RootLayout = ({children}: {children: React.ReactNode}) => {
1918
<html lang="en">
2019
<body className={inter.className}>
2120
<RecoilRootContainer>
22-
<Protect>
23-
<div className="flex h-full relative">
24-
<Navbar />
25-
<div className="grow overflow-x-auto overflow-y-auto">
26-
<div className="mainContainer">{children}</div>
27-
<Footer />
28-
</div>
21+
<div className="flex h-full relative">
22+
<Navbar />
23+
<div className="grow overflow-x-auto overflow-y-auto">
24+
<div className="mainContainer">{children}</div>
25+
<Footer />
2926
</div>
30-
</Protect>
27+
</div>
3128
</RecoilRootContainer>
3229
</body>
3330
</html>

src/components/navbar/Navbar.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,13 @@
22
import {useState} from 'react';
33
import Image from 'next/image';
44
import Link from 'next/link';
5-
import {useParams, usePathname} from 'next/navigation';
6-
import {useRecoilValue} from 'recoil';
7-
import userState from '@/src/recoil/atoms/userState';
5+
import {useParams, usePathname, useSearchParams} from 'next/navigation';
86
import {MaterialContainer, MaterialForm} from './material';
97
import Profile from './profile';
10-
import {User} from '@/src/interfaces/user';
118
import icons from '@/public/svgs/navbar';
129
import '@/src/styles/variable.css';
1310

1411
const Navbar = () => {
15-
const user = useRecoilValue(userState) as User;
1612
const [isOpen, setIsOpen] = useState<boolean>(false);
1713

1814
const pages = [
@@ -24,6 +20,8 @@ const Navbar = () => {
2420

2521
const router = usePathname();
2622
const params = useParams<{className: string; materialName: string}>();
23+
const searchParams = useSearchParams();
24+
const search = searchParams.get('id');
2725

2826
if (router === '/intro' || router === '/intro/googleLogin') {
2927
return null;
@@ -33,7 +31,7 @@ const Navbar = () => {
3331
<div className="w-72 h-full bg-gray-50">
3432
<div className="relative w-72 px-6 pt-5 navbar flex flex-col">
3533
{/* Profile */}
36-
<Profile user={user} params={params} />
34+
<Profile params={params} cId={search} />
3735
<div className="h-px bg-zinc-300"></div>
3836
<div className="h-8"></div>
3937

@@ -82,7 +80,7 @@ const Navbar = () => {
8280
</div>
8381
{isOpen ? <MaterialForm setIsOpen={setIsOpen} /> : null}
8482
</div>
85-
<MaterialContainer params={params} />
83+
<MaterialContainer params={params} cId={search} />
8684
</div>
8785
<div className="h-16"></div>
8886

src/components/navbar/profile/Profile.tsx

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,45 @@
1-
import {useState} from 'react';
1+
import {useEffect, useState} from 'react';
22
import Image from 'next/image';
33
import {useRouter} from 'next/navigation';
4+
import {useRecoilState, useRecoilValue} from 'recoil';
45
import EditName from './EditName';
56
import Warning from '../../warning/Warning';
7+
import getClassInfo from '@/src/api/classUser/getClassInfo';
68
import putUserName from '@/src/api/classUser/putUserName';
9+
import classUserState from '@/src/recoil/atoms/classUserState';
10+
import userState from '@/src/recoil/atoms/userState';
711
import {ParamsProps} from '@/src/interfaces/navbar';
8-
import {User} from '@/src/interfaces/user';
9-
import ClassUser from '@/src/model/User';
1012
import icons from '@/public/svgs/navbar';
13+
import ROLES from '@/src/constants/roles';
1114

12-
const Profile = ({user, params}: {user: User; params: ParamsProps}) => {
15+
const Profile = ({cId, params}: {cId: string | null; params: ParamsProps}) => {
1316
const router = useRouter();
17+
const user = useRecoilValue(userState);
18+
const [classUser, setClassUser] = useRecoilState(classUserState);
1419
const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);
1520
const [isEditOpen, setIsEditOpen] = useState<boolean>(false);
1621
const [isOpen, setIsOpen] = useState<boolean>(false);
1722

23+
useEffect(() => {
24+
if (cId && !classUser) {
25+
getClassInfo(user.id, parseInt(cId)).then(res => {
26+
console.log(res);
27+
setClassUser(res);
28+
});
29+
}
30+
if (!params.className) {
31+
setClassUser(null);
32+
}
33+
}, [cId, classUser, params]);
34+
1835
const toggleDropdown = () => {
1936
setDropdownOpen(!dropdownOpen);
2037
console.log(params);
2138
};
2239

2340
const handleEditName = (name: string) => {
2441
setDropdownOpen(false);
25-
putUserName(user.id, 4, name);
42+
if (classUser) putUserName(classUser.uid, 4, name);
2643
};
2744

2845
const handleClickDelete = () => {
@@ -38,14 +55,16 @@ const Profile = ({user, params}: {user: User; params: ParamsProps}) => {
3855
<div className="relative w-full h-12 flex items-start justify-between box-content ">
3956
<div className="flex items-center">
4057
<Image
41-
src={user.image}
58+
src={user ? user.image : ''}
4259
width={10}
4360
height={10}
4461
alt="userImage"
4562
className="w-8 h-8 rounded-lg object-cover"
4663
/>
4764

48-
<div className="mx-2">{user.name}</div>
65+
<div className="mx-2">
66+
{classUser ? classUser.nickname : user ? user.name : ''}
67+
</div>
4968
</div>
5069
<button
5170
className="relative w-8 h-8 rounded-lg float-end"
@@ -55,37 +74,41 @@ const Profile = ({user, params}: {user: User; params: ParamsProps}) => {
5574
</button>
5675
{dropdownOpen && (
5776
<ul className="absolute top-[32px] right-0 bg-white rounded-lg overflow-hidden drop-shadow-lg">
58-
<li
59-
className="p-2 hover:bg-gray-200"
60-
onClick={() => {
61-
setIsEditOpen(true);
62-
setDropdownOpen(false);
63-
}}
64-
>
65-
Edit Name
66-
</li>
67-
{ClassUser.managerRoll === 'manager' ? (
68-
<li
69-
className="p-2 hover:bg-gray-200"
70-
onClick={() => {
71-
setIsOpen(true);
72-
setDropdownOpen(false);
73-
}}
74-
>
75-
Edit group
76-
</li>
77+
{classUser ? (
78+
<>
79+
<li
80+
className="p-2 hover:bg-gray-200"
81+
onClick={() => {
82+
setIsEditOpen(true);
83+
setDropdownOpen(false);
84+
}}
85+
>
86+
Edit Name
87+
</li>
88+
{ROLES[classUser.role_id] === 'ADMIN' ? (
89+
<li
90+
className="p-2 hover:bg-gray-200"
91+
onClick={() => {
92+
setIsOpen(true);
93+
setDropdownOpen(false);
94+
}}
95+
>
96+
Edit group
97+
</li>
98+
) : null}
99+
<li
100+
className="p-2 hover:bg-gray-200"
101+
onClick={() => {
102+
setIsOpen(true);
103+
setDropdownOpen(false);
104+
}}
105+
>
106+
{ROLES[classUser.role_id] === 'ADMIN'
107+
? 'Delete group'
108+
: 'Leave group'}
109+
</li>
110+
</>
77111
) : null}
78-
<li
79-
className="p-2 hover:bg-gray-200"
80-
onClick={() => {
81-
setIsOpen(true);
82-
setDropdownOpen(false);
83-
}}
84-
>
85-
{ClassUser.managerRoll === 'manager'
86-
? 'Delete group'
87-
: 'Leave group'}
88-
</li>
89112
<li className="p-2 hover:bg-gray-200" onClick={handleClickLogout}>
90113
Logout
91114
</li>

src/components/protect/Protect.tsx

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/components/protect/index.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/constants/roles.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const ROLES: {[key: number]: string} = {
2+
1: 'USER',
3+
2: 'ADMIN',
4+
3: 'ASSISTANT',
5+
4: 'APPLICANT',
6+
5: 'BLACKLIST',
7+
6: 'INVITE',
8+
};
9+
10+
export default ROLES;

src/interfaces/user/ClassUser.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
interface ClassUser {
2+
uid: number;
3+
nickname: string;
4+
role_id: number;
5+
image: string;
6+
}
7+
8+
export default ClassUser;

0 commit comments

Comments
 (0)