Skip to content

Commit a487694

Browse files
authored
Merge pull request #139 from billilge/refactor/#137-mobile-design
[Refactor/#137] 학생회비 납부 표시, 사이드바 항목 추가, 레이아웃 등 디자인 수정 + 추가 기능 수정
2 parents 0d25779 + 3b197f0 commit a487694

File tree

25 files changed

+283
-105
lines changed

25 files changed

+283
-105
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"dotenv": "^16.4.5",
3838
"firebase": "^11.3.1",
3939
"js-base64": "^3.7.7",
40+
"js-cookie": "^3.0.5",
4041
"lodash": "^4.17.21",
4142
"lucide-react": "^0.475.0",
4243
"next": "^15.0.3",
@@ -62,6 +63,7 @@
6263
"@testing-library/dom": "^10.4.0",
6364
"@testing-library/jest-dom": "^6.6.3",
6465
"@types/jest": "^29.5.12",
66+
"@types/js-cookie": "^3.0.6",
6567
"@types/node": "^20",
6668
"@types/react": "^18",
6769
"@types/react-dom": "^18",
Lines changed: 3 additions & 0 deletions
Loading

public/assets/icons/side-menu/admin-homepage.svg

Lines changed: 120 additions & 0 deletions
Loading

src/app/callback/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { useEffect, Suspense } from 'react';
44
import { useSearchParams, useRouter } from 'next/navigation';
55
import { handleLoginSuccess } from '@/utils/loginHandler';
6+
import Cookies from 'js-cookie';
67

78
function CallbackContent() {
89
const searchParams = useSearchParams();
@@ -13,7 +14,7 @@ function CallbackContent() {
1314
const email = searchParams.get('email');
1415
const accessToken = searchParams.get('accessToken');
1516

16-
localStorage.setItem('email', email || '');
17+
Cookies.set('email', email || '');
1718

1819
if (!status) return;
1920

src/app/mobile/admin/dashboard/page.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22

33
import { useState, useEffect } from 'react';
4-
import MobileLayout from '@/components/mobile/layout';
54
import Header from '@/components/mobile/Header';
65
import Dropdown from '@/components/mobile/Dropdown';
76
import useDropdown from '@/hooks/useDropdown';
@@ -104,7 +103,7 @@ export default function Dashboard() {
104103
};
105104

106105
return (
107-
<MobileLayout>
106+
<div>
108107
<Header title="관리자 대시보드" />
109108

110109
<section className="itmes-center mt-2.5 flex w-full justify-between px-5">
@@ -171,6 +170,6 @@ export default function Dashboard() {
171170
hideDropdown={hideDropdown}
172171
positionClasses="top-[80px] right-5"
173172
/>
174-
</MobileLayout>
173+
</div>
175174
);
176175
}

src/app/mobile/admin/notification/page.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22

33
import { useEffect, useState } from 'react';
4-
import MobileLayout from '@/components/mobile/layout';
54
import NotificationItem from '@/components/mobile/NotificationItem';
65
import Header from '@/components/mobile/Header';
76
import { elapsedTime } from '@/utils/elapsedTime';
@@ -32,7 +31,7 @@ export default function Notification() {
3231
};
3332

3433
return (
35-
<MobileLayout>
34+
<div>
3635
<Header title="관리자 알림" />
3736
{notificationDetail?.length === 0 ? (
3837
<div className="flex h-dvh items-center justify-center text-gray-secondary">
@@ -53,6 +52,6 @@ export default function Notification() {
5352
/>
5453
))
5554
)}
56-
</MobileLayout>
55+
</div>
5756
);
5857
}

src/app/mobile/history/page.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22

33
import { useEffect, useState, useMemo } from 'react';
4-
import MobileLayout from '@/components/mobile/layout';
54
import Header from '@/components/mobile/Header';
65
import ReturnItem from '@/app/mobile/history/_components/ReturnItem';
76
import RentalItem from '@/app/mobile/history/_components/RentalItem';
@@ -194,7 +193,7 @@ export default function UserRentalList() {
194193
);
195194

196195
return (
197-
<MobileLayout>
196+
<div>
198197
<Header title="대여 기록" menu />
199198

200199
{/* 반납이 필요한 물품 */}
@@ -287,6 +286,6 @@ export default function UserRentalList() {
287286
<div className="text-body-2-normal_medi">© wink</div>
288287
</div>
289288
</div>
290-
</MobileLayout>
289+
</div>
291290
);
292291
}

src/app/mobile/layout.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use client';
2+
3+
import useAuthRedirect from '@/hooks/useAuthRedirect';
4+
import React, { useEffect } from 'react';
5+
import { usePathname } from 'next/navigation';
6+
7+
export default function MobileLayout({
8+
children,
9+
}: {
10+
children: React.ReactNode;
11+
}) {
12+
const pathname = usePathname();
13+
14+
// 제외할 경로 목록
15+
const excludedRoutes = ['/mobile/sign-in', '/mobile/sign-up'];
16+
17+
const isExcluded = excludedRoutes.includes(pathname);
18+
19+
useAuthRedirect();
20+
21+
useEffect(() => {
22+
if (!isExcluded) {
23+
const originalBgColor = document.body.style.backgroundColor;
24+
document.body.style.backgroundColor = '#F3F4F6';
25+
26+
return () => {
27+
document.body.style.backgroundColor = originalBgColor;
28+
};
29+
}
30+
31+
return undefined;
32+
}, [isExcluded]);
33+
34+
if (isExcluded) {
35+
// 레이아웃 없이 children만 렌더링
36+
return children;
37+
}
38+
39+
return (
40+
<div className="flex min-h-screen justify-center">
41+
<div className="flex w-full max-w-md flex-col">{children}</div>
42+
</div>
43+
);
44+
}

src/app/mobile/main/_components/MainHeader/index.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import Sidebar from '@/components/mobile/SidebarMenu/index';
55
import { useEffect, useState } from 'react';
66
import IconAlarm from 'public/assets/icons/icon-alarm.svg';
77
import IconHamburger from 'public/assets/icons/icon-hamburger.svg';
8+
import IconFeeCheck from 'public/assets/icons/icon-fee-check.svg';
89
import { getNotificationCount } from '@/apis/notification';
10+
import Cookies from 'js-cookie';
911

1012
export default function MainHeader() {
1113
const router = useRouter();
@@ -15,6 +17,7 @@ export default function MainHeader() {
1517
name: string;
1618
id: string;
1719
role: string;
20+
isFeePaid: boolean;
1821
} | null>(null);
1922

2023
useEffect(() => {
@@ -31,7 +34,7 @@ export default function MainHeader() {
3134
}, []);
3235

3336
useEffect(() => {
34-
const storedUser = localStorage.getItem('user');
37+
const storedUser = Cookies.get('user');
3538
if (storedUser) {
3639
setUser(JSON.parse(storedUser));
3740
}
@@ -40,8 +43,8 @@ export default function MainHeader() {
4043
return (
4144
<>
4245
<section className="fixed top-0 z-10 flex h-10 w-full max-w-md items-center justify-between bg-[#F3F4F6] px-4 py-1.5">
43-
<div className="text-heading-3_D font-semibold text-black-primary">
44-
{user?.name}
46+
<div className="flex items-center gap-2 text-heading-3_D font-semibold text-black-primary">
47+
{user?.name}{user?.isFeePaid ? <IconFeeCheck /> : null}
4548
</div>
4649
<div className="flex gap-[7px]">
4750
<button

src/app/mobile/main/page.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22

33
import { useEffect, useState } from 'react';
4-
import MobileLayout from '@/components/mobile/layout';
54
import MainHeader from '@/app/mobile/main/_components/MainHeader';
65
import Carousel from '@/app/mobile/main/_components/Carousel';
76
import WelfareItem from '@/app/mobile/main/_components/WelfareItem';
@@ -12,6 +11,7 @@ import IconSearch from 'public/assets/icons/icon-search.svg';
1211
import { useRouter } from 'next/navigation';
1312
import { requestNotificationPermission } from '@/utils/pushNotification';
1413
import PopUp from '@/components/mobile/PopUp';
14+
import Cookies from 'js-cookie';
1515

1616
export default function MobileMain() {
1717
const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false);
@@ -42,7 +42,7 @@ export default function MobileMain() {
4242
}, [searchQuery]);
4343

4444
useEffect(() => {
45-
if (!localStorage.getItem('token')) {
45+
if (!Cookies.get('token')) {
4646
router.replace('/mobile/sign-in');
4747
return;
4848
}
@@ -51,7 +51,7 @@ export default function MobileMain() {
5151
requestNotificationPermission();
5252

5353
// "다시 보지 않기" 플래그가 없으면 팝업 표시
54-
if (!localStorage.getItem('popUpDismissed2')) {
54+
if (!Cookies.get('popUpDismissed3')) {
5555
setShowPopUp(true);
5656
}
5757
}, []);
@@ -77,9 +77,9 @@ export default function MobileMain() {
7777
};
7878

7979
return (
80-
<MobileLayout>
80+
<div>
8181
<MainHeader />
82-
<div className="mt-10 flex flex-col gap-[50px] px-4 pt-4">
82+
<div className="mt-10 flex flex-col gap-[50px] px-4 py-4">
8383
<Carousel images={images} />
8484

8585
<section className="flex flex-col gap-4">
@@ -113,11 +113,11 @@ export default function MobileMain() {
113113
{showPopUp && (
114114
<PopUp
115115
title="🚨 공지사항 안내 🚨"
116-
content={`시험기간(04.14.~04.28.) 동안\n복지물품 대여가 일시 중단됩니다.\n
116+
content={`2025년 1학기 복지물품 대여는\n6월 2일(월)부로 종료됩니다.\n
117117
이용에 참고 부탁드립니다!`}
118118
onClickCta={() => setShowPopUp(false)}
119119
onClickOther={() => {
120-
localStorage.setItem('popUpDismissed2', 'true');
120+
Cookies.set('popUpDismissed3', 'true');
121121
setShowPopUp(false);
122122
}}
123123
/>
@@ -129,6 +129,6 @@ export default function MobileMain() {
129129
onCloseAction={() => setIsBottomSheetOpen(false)}
130130
item={selectedItem}
131131
/>
132-
</MobileLayout>
132+
</div>
133133
);
134134
}

0 commit comments

Comments
 (0)