diff --git a/app/business/api-path.ts b/app/business/api-path.ts index ec95e279..c17bf5f9 100644 --- a/app/business/api-path.ts +++ b/app/business/api-path.ts @@ -7,7 +7,6 @@ export const API_PATH = { takenLectures: `${BASE_URL}/taken-lectures`, resultCategoryDetailInfo: `${BASE_URL}/result-category-detail-info`, user: `${BASE_URL}/users`, - resultUserInfo: `${BASE_URL}/resultUserInfo`, credits: `${BASE_URL}/credits`, auth: `${BASE_URL}/auth`, lectures: `${BASE_URL}/lectures`, diff --git a/app/business/result/result.query.ts b/app/business/result/result.query.ts index a718881e..0763d40a 100644 --- a/app/business/result/result.query.ts +++ b/app/business/result/result.query.ts @@ -1,45 +1,8 @@ -import { LectureInfo } from '@/app/type/lecture'; import { API_PATH } from '../api-path'; import { cookies } from 'next/headers'; import { httpErrorHandler } from '@/app/utils/http/http-error-handler'; -import { RESULT_CATEGORY } from '@/app/utils/key/result-category.key'; +import { CreditResponse, ResultCategoryDetailResponse } from './result.type'; -export interface ResultCategoryDetailLectures { - categoryName: string; - totalCredits: number; - takenCredits: number; - takenLectures: LectureInfo[]; - haveToLectures: LectureInfo[]; - completed: boolean; -} - -export interface ResultCategoryDetailResponse { - totalCredit: number; - takenCredit: number; - detailCategory: ResultCategoryDetailLectures[]; - completed: boolean; -} - -export interface Major { - majorType: 'PRIMARY' | 'DUAL' | 'SUB'; - major: string; -} - -export interface ResultUserInfo { - studentNumber: string; - studentName: string; - completionDivision: Major[]; - totalCredit: number; - takenCredit: number; - graduated: boolean; -} - -export interface CreditResponse { - category: keyof typeof RESULT_CATEGORY; - totalCredit: number; - takenCredit: number; - completed: boolean; -} export const fetchResultCategoryDetailInfo = async (category: string): Promise => { //FIX : category를 querystring으로 호출하는 건은 mock단계에서는 불필요할 것으로 예상, 실제 api 연결시 변경 예정 try { diff --git a/app/business/result/result.type.ts b/app/business/result/result.type.ts new file mode 100644 index 00000000..2fa3b412 --- /dev/null +++ b/app/business/result/result.type.ts @@ -0,0 +1,30 @@ +import { LectureInfo } from '@/app/type/lecture'; +import { RESULT_CATEGORY } from '@/app/utils/key/result-category.key'; + +export interface ResultCategoryDetailLectures { + categoryName: string; + totalCredits: number; + takenCredits: number; + takenLectures: LectureInfo[]; + haveToLectures: LectureInfo[]; + completed: boolean; +} + +export interface ResultCategoryDetailResponse { + totalCredit: number; + takenCredit: number; + detailCategory: ResultCategoryDetailLectures[]; + completed: boolean; +} + +export interface Major { + majorType: 'PRIMARY' | 'DUAL' | 'SUB'; + major: string; +} + +export interface CreditResponse { + category: keyof typeof RESULT_CATEGORY; + totalCredit: number; + takenCredit: number; + completed: boolean; +} diff --git a/app/business/user/user.query.ts b/app/business/user/user.query.ts index 88d666da..cd759e03 100644 --- a/app/business/user/user.query.ts +++ b/app/business/user/user.query.ts @@ -1,12 +1,12 @@ import { httpErrorHandler } from '@/app/utils/http/http-error-handler'; import { API_PATH } from '../api-path'; -import { UserInfoResponse } from './user.type'; + import { cookies } from 'next/headers'; import { isValidation } from '@/app/utils/zod/validation.util'; -import { UserInfoResponseSchema } from './user.validation'; -import { ResultUserInfo } from '../result/result.query'; +import { InitUserInfoResponse, UserInfoResponse } from './user.type'; +import { UserInfoResponseSchema, InitUserInfoResponseSchema } from './user.validation'; -export async function getUserInfo(): Promise { +export async function fetchUserInfo(): Promise { try { const response = await fetch(`${API_PATH.user}`, { headers: { @@ -18,7 +18,7 @@ export async function getUserInfo(): Promise { httpErrorHandler(response, result); - if (isValidation(result, UserInfoResponseSchema)) { + if (isValidation(result, UserInfoResponseSchema || InitUserInfoResponseSchema)) { return result; } else { throw 'Invalid user info response schema.'; @@ -27,20 +27,3 @@ export async function getUserInfo(): Promise { throw error; } } - -export async function fetchResultUserInfo(): Promise { - try { - const response = await fetch(API_PATH.resultUserInfo, { - headers: { - Authorization: `Bearer ${cookies().get('accessToken')?.value}`, - }, - }); - - const result = await response.json(); - - httpErrorHandler(response, result); - return result; - } catch (error) { - throw error; - } -} diff --git a/app/business/user/user.type.ts b/app/business/user/user.type.ts index 3f18be25..fc267e86 100644 --- a/app/business/user/user.type.ts +++ b/app/business/user/user.type.ts @@ -1,23 +1,29 @@ // https://stackoverflow.com/questions/76957592/error-only-async-functions-are-allowed-to-be-exported-in-a-use-server-file // server action 파일에서는 async function만 export 가능 -import { SignInResponseSchema, UserInfoResponseSchema, ValidateTokenResponseSchema } from './user.validation'; +import { + InitUserInfoResponseSchema, + SignInResponseSchema, + UserInfoResponseSchema, + ValidateTokenResponseSchema, +} from './user.validation'; import z from 'zod'; -export interface SignUpRequestBody { +export interface SignInRequestBody { authId: string; password: string; - studentNumber: string; - engLv: string; } -export interface SignInRequestBody { +export interface SignUpRequestBody { authId: string; password: string; + studentNumber: string; + engLv: string; } export type SignInResponse = z.infer; export type UserInfoResponse = z.infer; +export type InitUserInfoResponse = z.infer; export type ValidateTokenResponse = z.infer; diff --git a/app/business/user/user.validation.ts b/app/business/user/user.validation.ts index ae8aaafd..89596799 100644 --- a/app/business/user/user.validation.ts +++ b/app/business/user/user.validation.ts @@ -1,13 +1,11 @@ import { z } from 'zod'; -// api 변경 예정 - export const UserInfoResponseSchema = z.object({ studentNumber: z.string(), studentName: z.string(), completionDivision: z.array( z.object({ - majorType: z.string(), + majorType: z.enum(['PRIMARY', 'DUAL', 'SUB']), major: z.string(), }), ), @@ -16,6 +14,15 @@ export const UserInfoResponseSchema = z.object({ graduated: z.boolean(), }); +export const InitUserInfoResponseSchema = z.object({ + studentNumber: z.string(), + studentName: z.null(), + completionDivision: z.null(), + totalCredit: z.null(), + takenCredit: z.null(), + graduated: z.null(), +}); + export const ValidateTokenResponseSchema = z.object({ accessToken: z.string(), }); diff --git a/app/mocks/data.mock.ts b/app/mocks/data.mock.ts index 2deb61d8..2de1a1c6 100644 --- a/app/mocks/data.mock.ts +++ b/app/mocks/data.mock.ts @@ -69,7 +69,7 @@ export const takenLectures = JSON.parse(`{ ] }`); -export const resultUserInfo = JSON.parse(`{ +export const userInfo = JSON.parse(`{ "studentNumber": "60181666", "studentName": "장진욱", "completionDivision" : [ @@ -195,6 +195,15 @@ export const resultCategoryDetailInfo = JSON.parse(`{ "completed": false }`); +export const users = JSON.parse(`[ + { + "authId": "admin", + "password": "admin", + "studentNumber": "60000000", + "engLv": "ENG12" + } + ]`); + export const credits = JSON.parse(`[ { "category": "COMMON_CULTURE", @@ -269,6 +278,7 @@ export const credits = JSON.parse(`[ "completed": false } ]`); + export const searchLectures = JSON.parse(`{ "lectures": [ { diff --git a/app/mocks/db.mock.ts b/app/mocks/db.mock.ts index 6ee804cc..84c8057f 100644 --- a/app/mocks/db.mock.ts +++ b/app/mocks/db.mock.ts @@ -1,46 +1,39 @@ import { SearchLectures } from '../business/lecture/search-lecture.query'; import { TakenLectures } from '../business/lecture/taken-lecture.query'; -import { CreditResponse, ResultCategoryDetailResponse, ResultUserInfo } from '../business/result/result.query'; -import { SignUpRequestBody, SignInRequestBody, UserInfoResponse } from '../business/user/user.type'; -import { takenLectures, resultCategoryDetailInfo, resultUserInfo, credits, searchLectures } from './data.mock'; - -interface MockUser { - authId: string; - password: string; - studentNumber: string; - engLv: string; - major: string; - isSumbitted: boolean; - name: string; -} +import { CreditResponse, ResultCategoryDetailResponse } from '../business/result/result.type'; +import { + SignUpRequestBody, + SignInRequestBody, + UserInfoResponse, + InitUserInfoResponse, +} from '../business/user/user.type'; +import { takenLectures, credits, searchLectures, userInfo, users, resultCategoryDetailInfo } from './data.mock'; interface MockDatabaseState { takenLectures: TakenLectures; resultCategoryDetailInfo: ResultCategoryDetailResponse; - resultUserInfo: ResultUserInfo; credits: CreditResponse[]; - users: MockUser[]; + users: SignUpRequestBody[]; searchLectures: SearchLectures; + userInfo: UserInfoResponse; } type MockDatabaseAction = { getTakenLectures: () => TakenLectures; getSearchLectures: () => SearchLectures; - getResultCategoryDetailInfo: () => ResultCategoryDetailResponse; addTakenLecture: (lectureId: number) => boolean; deleteTakenLecture: (lectureId: number) => boolean; - getUser: (authId: string) => MockUser | undefined; createUser: (user: SignUpRequestBody) => boolean; signIn: (userData: SignInRequestBody) => boolean; getCredits: () => CreditResponse[]; - getUserInfo: (authId: string) => UserInfoResponse; - getResultUserInfo: () => ResultUserInfo; + getUserInfo: (authId: string) => UserInfoResponse | InitUserInfoResponse; + getResultCategoryDetailInfo: () => ResultCategoryDetailResponse; }; export const mockDatabase: MockDatabaseAction = { getTakenLectures: () => mockDatabaseStore.takenLectures, - getResultUserInfo: () => mockDatabaseStore.resultUserInfo, getSearchLectures: () => mockDatabaseStore.searchLectures, + getResultCategoryDetailInfo: () => mockDatabaseStore.resultCategoryDetailInfo, deleteTakenLecture: (lectureId) => { if (mockDatabaseStore.takenLectures.takenLectures.find((lecture) => lecture.id === lectureId)) { mockDatabaseStore.takenLectures.takenLectures = mockDatabaseStore.takenLectures.takenLectures.filter( @@ -64,22 +57,13 @@ export const mockDatabase: MockDatabaseAction = { ]; return true; }, - getResultCategoryDetailInfo: () => mockDatabaseStore.resultCategoryDetailInfo, - getUser: (authId: string) => mockDatabaseStore.users.find((user) => user.authId === authId), + getCredits: () => mockDatabaseStore.credits, createUser: (user: SignUpRequestBody) => { if (mockDatabaseStore.users.find((u) => u.authId === user.authId || u.studentNumber === user.studentNumber)) { return false; } - mockDatabaseStore.users = [ - ...mockDatabaseStore.users, - { - ...user, - isSumbitted: false, - major: '융소입니다', - name: '모킹이2', - }, - ]; + mockDatabaseStore.users = [...mockDatabaseStore.users, user]; return true; }, signIn: (userData: SignInRequestBody) => { @@ -91,32 +75,14 @@ export const mockDatabase: MockDatabaseAction = { if (!user) { return { studentNumber: '', - studentName: '', - completionDivision: [ - { - majorType: '', - major: '', - }, - ], - totalCredit: 0, - takenCredit: 0, - graduated: false, + studentName: null, + completionDivision: null, + totalCredit: null, + takenCredit: null, + graduated: null, }; } - return { - studentNumber: user.studentNumber, - studentName: user.name, - completionDivision: [ - { - majorType: 'primary', - major: '디지털컨텐츠디자인학과', - }, - ], - - totalCredit: 132, - takenCredit: 50, - graduated: false, - }; + return mockDatabaseStore.userInfo; }, }; @@ -124,19 +90,9 @@ const initialState: MockDatabaseState = { takenLectures: takenLectures, resultCategoryDetailInfo: resultCategoryDetailInfo, credits: credits, - resultUserInfo: resultUserInfo, - users: [ - { - authId: 'admin', - password: 'admin', - studentNumber: '60000000', - engLv: 'ENG12', - isSumbitted: false, - major: '융소입니다', - name: '모킹이', - }, - ], + users: users, searchLectures: searchLectures, + userInfo: userInfo, }; function initStore(): MockDatabaseState { diff --git a/app/mocks/handlers/result-handler.mock.ts b/app/mocks/handlers/result-handler.mock.ts index 52ac5b1e..32941455 100644 --- a/app/mocks/handlers/result-handler.mock.ts +++ b/app/mocks/handlers/result-handler.mock.ts @@ -2,7 +2,7 @@ import { HttpResponse, http, delay } from 'msw'; import { API_PATH } from '../../business/api-path'; import { mockDatabase } from '../db.mock'; import { ErrorResponseData } from '@/app/utils/http/http-error-handler'; -import { CreditResponse, ResultCategoryDetailResponse } from '@/app/business/result/result.query'; +import { CreditResponse, ResultCategoryDetailResponse } from '@/app/business/result/result.type'; export const resultHandlers = [ http.get( diff --git a/app/mocks/handlers/taken-lecture-handler.mock.ts b/app/mocks/handlers/taken-lecture-handler.mock.ts index daf28079..7b208698 100644 --- a/app/mocks/handlers/taken-lecture-handler.mock.ts +++ b/app/mocks/handlers/taken-lecture-handler.mock.ts @@ -32,7 +32,6 @@ export const takenLectureHandlers = [ }), http.post(API_PATH.parsePDFtoText, async () => { await delay(1000); - console.log(parsePDF); return HttpResponse.json(parsePDF); }), diff --git a/app/mocks/handlers/user-handler.mock.ts b/app/mocks/handlers/user-handler.mock.ts index e045474a..229469e8 100644 --- a/app/mocks/handlers/user-handler.mock.ts +++ b/app/mocks/handlers/user-handler.mock.ts @@ -7,9 +7,9 @@ import { SignInResponse, ValidateTokenResponse, UserInfoResponse, + InitUserInfoResponse, } from '@/app/business/user/user.type'; import { ErrorResponseData } from '@/app/utils/http/http-error-handler'; -import { ResultUserInfo } from '@/app/business/result/result.query'; function mockDecryptToken(token: string) { if (token === 'fake-access-token') { @@ -32,39 +32,26 @@ export const userHandlers = [ accessToken: 'fake-access-token', }); }), - http.get(`${API_PATH.user}`, async ({ request }) => { - const accessToken = request.headers.get('Authorization')?.replace('Bearer ', ''); - if (accessToken === 'undefined' || !accessToken) { - return HttpResponse.json({ status: 401, message: 'Unauthorized' }, { status: 401 }); - } - - const userInfo = mockDatabase.getUserInfo(mockDecryptToken(accessToken).authId); - await delay(3000); - - if (!userInfo) { - return HttpResponse.json({ status: 401, message: 'Unauthorized' }, { status: 401 }); - } - - return HttpResponse.json(userInfo); - }), - http.get(API_PATH.resultUserInfo, async ({ request }) => { - const accessToken = request.headers.get('Authorization')?.replace('Bearer ', ''); - if (accessToken === 'undefined' || !accessToken) { - return HttpResponse.json({ status: 401, message: 'Unauthorized' }, { status: 401 }); - } + http.get( + API_PATH.user, + async ({ request }) => { + const accessToken = request.headers.get('Authorization')?.replace('Bearer ', ''); + if (accessToken === 'undefined' || !accessToken) { + return HttpResponse.json({ status: 401, message: 'Unauthorized' }, { status: 401 }); + } + const userInfo = mockDatabase.getUserInfo(mockDecryptToken(accessToken).authId); + await delay(3000); - const userInfo = mockDatabase.getResultUserInfo(); - await delay(2000); + if (!userInfo) { + return HttpResponse.json({ status: 401, message: 'Unauthorized' }, { status: 401 }); + } - if (!userInfo) { - return HttpResponse.json({ status: 401, message: 'Unauthorized' }, { status: 401 }); - } + return HttpResponse.json(userInfo); + }, + ), - return HttpResponse.json(userInfo); - }), http.post(`${API_PATH.user}/sign-up`, async ({ request }) => { const userData = await request.json(); - const isSuccess = mockDatabase.createUser(userData); await delay(500); diff --git a/app/ui/result/result-category-detail-content/result-category-detail-content.tsx b/app/ui/result/result-category-detail-content/result-category-detail-content.tsx index 6b2a7a0b..1cee5608 100644 --- a/app/ui/result/result-category-detail-content/result-category-detail-content.tsx +++ b/app/ui/result/result-category-detail-content/result-category-detail-content.tsx @@ -4,7 +4,7 @@ import { cn } from '@/app/utils/shadcn/utils'; import { useState } from 'react'; import { ResultCategoryDetailLectureToggle } from '../result-category-detail-lecture/result-category-detail-lecture-toggle'; import ResultCagegoryDetailLecture from '../result-category-detail-lecture/result-cagegory-detail-lecture'; -import { ResultCategoryDetailResponse } from '@/app/business/result/result.query'; +import { ResultCategoryDetailResponse } from '@/app/business/result/result.type'; interface ResultCategoryDetailContentProps { info: ResultCategoryDetailResponse; diff --git a/app/ui/result/result-category-detail-lecture/result-cagegory-detail-lecture.tsx b/app/ui/result/result-category-detail-lecture/result-cagegory-detail-lecture.tsx index 3d48179a..988077cc 100644 --- a/app/ui/result/result-category-detail-lecture/result-cagegory-detail-lecture.tsx +++ b/app/ui/result/result-category-detail-lecture/result-cagegory-detail-lecture.tsx @@ -1,7 +1,7 @@ import { Table } from '../../view/molecule/table'; import AnnounceMessageBox from '@/app/ui/view/molecule/announce-message-box/announce-massage-box'; -import { ResultCategoryDetailLectures } from '@/app/business/result/result.query'; import LabelContainer from '@/app/ui/view/atom/label-container/label-container'; +import { ResultCategoryDetailLectures } from '@/app/business/result/result.type'; const headerInfo = ['과목코드', '과목명', '학점']; diff --git a/app/ui/user/user-credit-result.tsx b/app/ui/user/user-credit-result.tsx index a9b45591..fc67872f 100644 --- a/app/ui/user/user-credit-result.tsx +++ b/app/ui/user/user-credit-result.tsx @@ -1,10 +1,11 @@ -import { getUserInfo } from '@/app/business/user/user.query'; +import { fetchUserInfo } from '@/app/business/user/user.query'; import books from '@/public/assets/books.png'; import pencil from '@/public/assets/pencil.png'; import Image from 'next/image'; export default async function UserCreditResult() { - const userInfo = await getUserInfo(); + const userInfo = await fetchUserInfo(); + return (
diff --git a/app/ui/user/user-info-card/init-user-announce.tsx b/app/ui/user/user-info-card/init-user-announce.tsx new file mode 100644 index 00000000..565b2dfd --- /dev/null +++ b/app/ui/user/user-info-card/init-user-announce.tsx @@ -0,0 +1,13 @@ +function InitUserAnnounce() { + return ( +
+

+ 성적표 PDF 업로드를 통해 +
+ 졸업사정 결과를 확인할 수 있어요. +

+
+ ); +} + +export default InitUserAnnounce; diff --git a/app/ui/user/user-info-card/user-info-card.tsx b/app/ui/user/user-info-card/user-info-card.tsx index 6fc977de..949a83e1 100644 --- a/app/ui/user/user-info-card/user-info-card.tsx +++ b/app/ui/user/user-info-card/user-info-card.tsx @@ -1,60 +1,20 @@ -import { getPercentage } from '@/app/utils/chart.util'; -import PieChart from '../../view/molecule/pie-chart/pie-chart'; -import { fetchResultUserInfo } from '@/app/business/user/user.query'; -import { MAJOR_NOTATION } from '@/app/utils/key/result-category.key'; +import { fetchUserInfo } from '@/app/business/user/user.query'; +import { InitUserInfoResponse, UserInfoResponse } from '@/app/business/user/user.type'; +import InitUserAnnounce from './init-user-announce'; +import UserInfoContent from './user-info-content'; async function UserInfoCard() { - const { - studentNumber, - studentName, - completionDivision: majors, - totalCredit, - takenCredit, - graduated, - } = await fetchResultUserInfo(); + const data = await fetchUserInfo(); - const displaySeveralMajor = (notation: 'major' | 'title'): React.ReactNode => { - return majors.map((major, index) => { - const { major: majorName, majorType } = major; + function isInitUser(x: UserInfoResponse | InitUserInfoResponse): x is InitUserInfoResponse { + return typeof x.studentName === null; + } - return
  • {notation === 'title' ? MAJOR_NOTATION[majorType] : majorName}
  • ; - }); - }; + function renderUserInfo(data: UserInfoResponse | InitUserInfoResponse) { + isInitUser(data) ? : ; + } - return ( - <> -

    - 졸업필요학점보다 {totalCredit - takenCredit}학점이 부족합니다. -

    -
    -
    -
      -
    • 이름
    • -
    • 학번
    • - {displaySeveralMajor('title')} -
    • 졸업필요학점
    • -
    • 총 이수 학점
    • -
    • 졸업가능여부
    • -
    -
      -
    • {studentNumber}
    • -
    • {studentName}
    • - {displaySeveralMajor('major')} -
    • {totalCredit}
    • -
    • {takenCredit}
    • -
    • {graduated ? '가능' : '불가능'}
    • -
    -
    -
    - -
    -
    -

    - * 서비스의 결과는 공식적인 효력을 갖지 않습니다. 정확한 졸업사정결과는 소속 단과대 교학팀에서의 확인을 - 권장합니다. -

    - - ); + return <>{renderUserInfo(data)}; } export default UserInfoCard; diff --git a/app/ui/user/user-info-card/user-info-content.tsx b/app/ui/user/user-info-card/user-info-content.tsx new file mode 100644 index 00000000..46fae233 --- /dev/null +++ b/app/ui/user/user-info-card/user-info-content.tsx @@ -0,0 +1,58 @@ +import { UserInfoResponse } from '@/app/business/user/user.type'; +import { MAJOR_NOTATION } from '@/app/utils/key/result-category.key'; +import React from 'react'; +import PieChart from '../../view/molecule/pie-chart/pie-chart'; +import { getPercentage } from '@/app/utils/chart.util'; + +interface UserInfoContentProps { + data: UserInfoResponse; +} + +function UserInfoContent({ data }: UserInfoContentProps) { + const { studentNumber, studentName, completionDivision: majors, totalCredit, takenCredit, graduated } = data; + + const displaySeveralMajor = (notation: 'major' | 'title'): React.ReactNode => { + return majors.map((major, index) => { + const { major: majorName, majorType } = major; + + return
  • {notation === 'title' ? MAJOR_NOTATION[majorType] : majorName}
  • ; + }); + }; + + return ( + <> +

    + 졸업필요학점보다 {totalCredit - takenCredit}학점이 부족합니다. +

    +
    +
    +
      +
    • 이름
    • +
    • 학번
    • + {displaySeveralMajor('title')} +
    • 졸업필요학점
    • +
    • 총 이수 학점
    • +
    • 졸업가능여부
    • +
    +
      +
    • {studentNumber}
    • +
    • {studentName}
    • + {displaySeveralMajor('major')} +
    • {totalCredit}
    • +
    • {takenCredit}
    • +
    • {graduated ? '가능' : '불가능'}
    • +
    +
    +
    + +
    +
    +

    + * 서비스의 결과는 공식적인 효력을 갖지 않습니다. 정확한 졸업사정결과는 소속 단과대 교학팀에서의 확인을 + 권장합니다. +

    + + ); +} + +export default UserInfoContent; diff --git a/app/ui/user/user-info-navigator/user-info-navigator.tsx b/app/ui/user/user-info-navigator/user-info-navigator.tsx index 56caea14..d291e8f9 100644 --- a/app/ui/user/user-info-navigator/user-info-navigator.tsx +++ b/app/ui/user/user-info-navigator/user-info-navigator.tsx @@ -1,9 +1,11 @@ +import { UserInfoResponseSchema } from '@/app/business/user/user.validation'; import Avatar from '../../view/atom/avatar/avatar'; import Button from '../../view/atom/button/button'; -import { getUserInfo } from '@/app/business/user/user.query'; +import { fetchUserInfo } from '@/app/business/user/user.query'; +import { z } from 'zod'; export default async function UserInfoNavigator() { - const userInfo = await getUserInfo(); + const userInfo = (await fetchUserInfo()) as z.infer; return (
    @@ -15,7 +17,6 @@ export default async function UserInfoNavigator() {
    {userInfo.completionDivision[0].major}
    {userInfo.studentNumber}
    -
    diff --git a/middleware.ts b/middleware.ts index c61ab09a..90a7fa7e 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1,6 +1,6 @@ import type { NextRequest } from 'next/server'; import { validateToken } from './app/business/user/user.command'; -import { getUserInfo } from './app/business/user/user.query'; +import { fetchUserInfo } from './app/business/user/user.query'; async function getAuth(request: NextRequest): Promise<{ role: 'guest' | 'user' | 'init'; @@ -24,10 +24,9 @@ async function getAuth(request: NextRequest): Promise<{ request.cookies.set('accessToken', validatedResult.accessToken); - // 유저 정보 요청 - const user = await getUserInfo(); + const user = await fetchUserInfo(); return { - role: user.isSumbitted ? 'user' : 'init', + role: user.studentName ? 'user' : 'init', }; } @@ -43,7 +42,6 @@ export async function middleware(request: NextRequest) { // 개발용이성을 위해 isAuth=true 일 때만 동작 if (isAuth === 'true') { const auth = await getAuth(request); - if (auth.role === 'init' && !request.nextUrl.pathname.startsWith('/grade-upload')) { return Response.redirect(new URL('/grade-upload', request.url)); }