-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
π μν μ λ°λ₯Έ url μ²λ¦¬ μ§ν #77
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,6 @@ | ||||||||||||||||||||||
import axios from 'axios'; | ||||||||||||||||||||||
|
||||||||||||||||||||||
export const deleteUserAccount = async () => { | ||||||||||||||||||||||
const response = await axios.delete('/api/admin'); | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion μλ¬ μ²λ¦¬ λ‘μ§ μΆκ° νμ νμ¬ λ€μκ³Ό κ°μ΄ export const deleteUserAccount = async () => {
- const response = await axios.delete('/api/admin');
- return response;
+ try {
+ const response = await axios.delete('/api/admin');
+ return response;
+ } catch (error) {
+ // μλ¬ μ²λ¦¬ λ‘μ§ μΆκ°
+ throw error;
+ }
}; π Committable suggestion
Suggested change
|
||||||||||||||||||||||
return response; | ||||||||||||||||||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useMutation } from '@tanstack/react-query'; | ||
import { useRouter } from 'next/navigation'; | ||
import { toast } from 'react-toastify'; | ||
import { deleteUserAccount } from '../api/deleteUserAccount'; | ||
|
||
export const useDeleteUserAccount = () => { | ||
const router = useRouter(); | ||
|
||
return useMutation({ | ||
mutationFn: () => deleteUserAccount(), | ||
onSuccess: () => { | ||
toast.success('νν΄κ° μλ£λμμ΅λλ€.'); | ||
router.push('/'); | ||
}, | ||
onError: () => { | ||
toast.error('μ μ νν΄λ₯Ό μ€ν¨νμ΅λλ€.'); | ||
}, | ||
}); | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,6 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import React from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import React, { useState } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Logout } from '@/shared/assets/icons'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useDeleteUserAccount } from '../../model/useDeleteUserAccount'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useLogout } from '../../model/useLogout'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ProfileInfo = ({ label, value }: { label: string; value: string }) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -11,18 +12,43 @@ const ProfileInfo = ({ label, value }: { label: string; value: string }) => ( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const AdminProfile = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { mutate: logout } = useLogout(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { mutate: deleteAccount } = useDeleteUserAccount(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const [isToggleLogout, setIsToggleLogout] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const handleLogoutClick = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setIsToggleLogout((prev) => !prev); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="flex w-full justify-between"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="relative flex w-full justify-between"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="flex items-center gap-[124px] mobile:flex-col mobile:gap-[30px]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="space-y-[32px]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<ProfileInfo label="μ΄λ¦" value="κΉμ§μ" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<ProfileInfo label="μμ΄λ" value="jin1234" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<ProfileInfo label="μ΄λ©μΌ" value="[email protected]" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<label onClick={() => logout()}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+23
to
30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion νλμ½λ©λ μ¬μ©μ μ 보λ₯Ό propsλ μνλ‘ κ΄λ¦¬νλ κ²μ΄ μ’μ΅λλ€. νμ¬ μ¬μ©μ μ λ³΄κ° νλμ½λ©λμ΄ μμ΅λλ€. μ΄λ μ μ§λ³΄μμ±μ μ νμν¬ μ μμ΅λλ€. λ€μκ³Ό κ°μ΄ μμ νλ κ²μ μ μν©λλ€: + interface AdminProfileProps {
+ name: string;
+ username: string;
+ email: string;
+ }
- const AdminProfile = () => {
+ const AdminProfile = ({ name, username, email }: AdminProfileProps) => {
return (
<div className="relative flex w-full justify-between">
<div className="flex items-center gap-[124px] mobile:flex-col mobile:gap-[30px]">
<div className="space-y-[32px]">
- <ProfileInfo label="μ΄λ¦" value="κΉμ§μ" />
- <ProfileInfo label="μμ΄λ" value="jin1234" />
- <ProfileInfo label="μ΄λ©μΌ" value="[email protected]" />
+ <ProfileInfo label="μ΄λ¦" value={name} />
+ <ProfileInfo label="μμ΄λ" value={username} />
+ <ProfileInfo label="μ΄λ©μΌ" value={email} />
</div>
</div> π Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Logout /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</label> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<button onClick={handleLogoutClick}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Logout /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{isToggleLogout && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="absolute right-0 top-[30px] flex h-fit flex-col gap-2 rounded-[6px] border border-gray-200 bg-white p-2 shadow-[0px_4px_4px_0px_rgba(0,_0,_0,_0.25)]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onClick={() => logout()} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="w-full rounded-[6px] px-5 py-2 text-body2 text-gray-500 hover:bg-error hover:text-white" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
λ‘κ·Έμμ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onClick={() => deleteAccount()} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="w-full rounded-[6px] px-5 py-2 text-body2 text-gray-500 hover:bg-error hover:text-white" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
νμνν΄ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+31
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion μ κ·Όμ± λ° μ¬μ©μ κ²½ν κ°μ μ΄ νμν©λλ€.
λ€μκ³Ό κ°μ΄ μμ νλ κ²μ μ μν©λλ€: <div>
<button
+ aria-label="λ‘κ·Έμμ λ©λ΄"
+ aria-expanded={isToggleLogout}
onClick={handleLogoutClick}>
<Logout />
</button>
{isToggleLogout && (
<div className="absolute right-0 top-[30px] flex h-fit flex-col gap-2 rounded-[6px] border border-gray-200 bg-white p-2 shadow-[0px_4px_4px_0px_rgba(0,_0,_0,_0.25)]">
<button
onClick={() => logout()}
+ aria-label="λ‘κ·Έμμ μ€ν"
className="w-full rounded-[6px] px-5 py-2 text-body2 text-gray-500 hover:bg-error hover:text-white"
>
λ‘κ·Έμμ
</button>
<button
- onClick={() => deleteAccount()}
+ onClick={() => {
+ if (window.confirm('μ λ§λ‘ νμνν΄λ₯Ό μ§ννμκ² μ΅λκΉ?')) {
+ deleteAccount();
+ }
+ }}
+ aria-label="νμνν΄ μ€ν"
className="w-full rounded-[6px] px-5 py-2 text-body2 text-gray-500 hover:bg-error hover:text-white"
>
νμνν΄
</button>
</div>
)}
</div> π Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,25 @@ | ||
import { NextResponse } from 'next/server'; | ||
import type { NextRequest } from 'next/server'; | ||
|
||
export function middleware(request: NextRequest) { | ||
const accessToken = request.cookies.get('accessToken'); | ||
const MANAGE_RESTRICTED_PATHS = [ | ||
/^\/signIn$/, | ||
/^\/signUp$/, | ||
/^\/application\/.+\/(STANDARD|TRAINEE)$/, | ||
]; | ||
|
||
const requestHeaders = new Headers(request.headers); | ||
const USER_RESTRICTED_PATHS = [ | ||
/^\/admin$/, | ||
/^\/create-exhibition$/, | ||
/^\/expo-manage\/.+$/, | ||
/^\/name-tag\/.+$/, | ||
/^\/sms\/.+\/(STANDARD|TRAINEE)$/, | ||
/^\/program(\/.*)?$/, | ||
]; | ||
|
||
if (accessToken) { | ||
requestHeaders.set('role', 'manage'); | ||
} else { | ||
requestHeaders.set('role', 'user'); | ||
} | ||
function handleApiRole(request: NextRequest): NextResponse { | ||
const requestHeaders = new Headers(request.headers); | ||
const role = request.cookies.get('accessToken') ? 'manage' : 'user'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. κΆν μ€μ λ‘μ§μ 보μ κ°ν νμ νμ¬
|
||
requestHeaders.set('role', role); | ||
|
||
return NextResponse.next({ | ||
request: { | ||
|
@@ -19,6 +28,44 @@ export function middleware(request: NextRequest) { | |
}); | ||
} | ||
|
||
function isPathMatch(pathname: string, patterns: RegExp[]): boolean { | ||
return patterns.some((pattern) => pattern.test(pathname)); | ||
} | ||
|
||
export function middleware(request: NextRequest) { | ||
const { pathname } = request.nextUrl; | ||
|
||
if (pathname === '/api/role') { | ||
return handleApiRole(request); | ||
} | ||
|
||
const accessToken = request.cookies.get('accessToken'); | ||
|
||
if (!accessToken && isPathMatch(pathname, USER_RESTRICTED_PATHS)) { | ||
return NextResponse.redirect(new URL('/', request.url)); | ||
} | ||
|
||
if (accessToken && isPathMatch(pathname, MANAGE_RESTRICTED_PATHS)) { | ||
return NextResponse.redirect(new URL('/', request.url)); | ||
} | ||
|
||
return NextResponse.next(); | ||
} | ||
|
||
export const config = { | ||
matcher: ['/api/role'], | ||
matcher: [ | ||
'/api/role', | ||
'/signIn', | ||
'/signUp', | ||
'/admin', | ||
'/create-exhibition', | ||
'/expo-manage/:path*', | ||
'/name-tag/:path*', | ||
'/sms/:path*/STANDARD', | ||
'/sms/:path*/TRAINEE', | ||
'/program/:path*', | ||
'/program/detail/:path*', | ||
'/application/:path*/STANDARD', | ||
'/application/:path*/TRAINEE', | ||
], | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
catch λΈλ‘μμ κΈ°λ³Έ μλ΅μ΄ λλ½λμμ΅λλ€.
errorκ° AxiosError μΈμ€ν΄μ€κ° μλ κ²½μ°μ λν μλ΅μ΄ λλ½λμ΄ μμ΅λλ€. μ΄λ μκΈ°μΉ μμ μ€λ₯κ° λ°μν μ μμ΅λλ€.
λ€μκ³Ό κ°μ΄ μμ νλ κ²μ μ μν©λλ€:
π Committable suggestion