- {TUTORIAL_UPLOAD.map((feature, index) => (
-
- ))}
+
+
+
+
+
+ MYIWEB 성적표
+
+ 를 통해
+ 나만의 졸업사정결과를 확인해요
-
+
+
);
}
diff --git a/app/business/services/lecture/taken-lecture.command.ts b/app/business/services/lecture/taken-lecture.command.ts
index 0c2086c4..a07fc6d9 100644
--- a/app/business/services/lecture/taken-lecture.command.ts
+++ b/app/business/services/lecture/taken-lecture.command.ts
@@ -29,7 +29,7 @@ export const registerUserGrade = async (prevState: FormState, formData: FormData
message: 'fail upload grade',
};
}
- redirect('/my');
+ redirect('/result');
};
export const parsePDFtoText = async (formData: FormData) => {
diff --git a/app/ui/result/result-category/result-category.skeleton.tsx b/app/ui/result/result-category/result-category.skeleton.tsx
index e5477e4e..87c54505 100644
--- a/app/ui/result/result-category/result-category.skeleton.tsx
+++ b/app/ui/result/result-category/result-category.skeleton.tsx
@@ -4,7 +4,10 @@ import ResultCategoryCardSkeleton from '../result-category-card/result-category-
async function ResultCategorySkeleton() {
return (
{Array.from({ length: 4 }).map((_, index) => (
diff --git a/app/ui/result/result-category/result-category.tsx b/app/ui/result/result-category/result-category.tsx
index a032ddd9..3d260e75 100644
--- a/app/ui/result/result-category/result-category.tsx
+++ b/app/ui/result/result-category/result-category.tsx
@@ -1,7 +1,7 @@
'use client';
import { cn } from '@/app/utils/shadcn/utils';
import ResultCategoryCard from '../result-category-card/result-category-card';
-import { CreditResponse, useFetchCredits } from '@/app/store/querys/result';
+import { useFetchCredits } from '@/app/store/querys/result';
import { RESULT_CATEGORY } from '@/app/utils/key/result-category.key';
import { ResultCategoryKey } from '../result-category-detail-content/result-category-detail-content.stories';
@@ -22,7 +22,10 @@ function ResultCategory() {
return (
{sortedCategories.map(({ category, totalCredit, takenCredit }, index) => (
{
+ const { category: categoryName, totalCredit, takenCredit } = category;
+ if (categoryName === 'CHAPEL') return accumulator;
+ const categoryRemainCredit = totalCredit - takenCredit < 0 ? 0 : totalCredit - takenCredit;
+ return accumulator + categoryRemainCredit;
+ }, 0);
+
+ const percentage = getPercentage(totalCredit - remainCredit, totalCredit);
const displaySeveralMajor = (notation: 'major' | 'title'): React.ReactNode => {
return majors.map((major, index) => {
@@ -23,21 +34,15 @@ function UserInfoContent({ data }: UserInfoContentProps) {
return (
<>
-
- 졸업필요학점보다{' '}
-
- {totalCredit - takenCredit}
-
- 학점이 부족합니다.
-
-
+
+
- 이름
- 학번
{displaySeveralMajor('title')}
- - 졸업필요학점
- - 총 이수 학점
+ - 졸업최소학점
+ - 현재이수학점
- 졸업가능여부
diff --git a/app/ui/user/user-info-card/user-info-message.tsx b/app/ui/user/user-info-card/user-info-message.tsx
new file mode 100644
index 00000000..8a03d9f2
--- /dev/null
+++ b/app/ui/user/user-info-card/user-info-message.tsx
@@ -0,0 +1,25 @@
+interface UserInfoMessageProps {
+ studentName: string;
+ remainCredit: number;
+}
+
+function UserInfoMessage({ studentName, remainCredit }: UserInfoMessageProps) {
+ return (
+
+ {studentName}님,
+ {remainCredit > 0 ? (
+ <>
+ 졸업까지
+
+ {remainCredit}
+
+ 학점 남았어요.
+ >
+ ) : (
+ '졸업을 축하합니다 !'
+ )}
+
+ );
+}
+
+export default UserInfoMessage;
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 c84aeb12..dea08a18 100644
--- a/app/ui/user/user-info-navigator/user-info-navigator.tsx
+++ b/app/ui/user/user-info-navigator/user-info-navigator.tsx
@@ -11,7 +11,7 @@ function formatUserInfo(userInfo: InitUserInfoResponse | UserInfoResponse | unde
if (!userInfo) {
return {
name: '소중한 GUEST',
- major: '성적표를 입력하고, 졸업 여부를 확인하세요',
+ major: '성적표 입력 후, 졸업 여부를 확인해요',
studentNumber: '',
};
}
@@ -19,7 +19,7 @@ function formatUserInfo(userInfo: InitUserInfoResponse | UserInfoResponse | unde
if (isInitUser(userInfo)) {
return {
name: '명지인',
- major: '성적표를 입력하고, 졸업 여부를 확인하세요',
+ major: '성적표 입력 후, 졸업 여부를 확인해요',
studentNumber: userInfo.studentNumber,
};
}
@@ -36,7 +36,7 @@ export default async function UserInfoNavigator() {
return (
-
+
{userInfo.name}
diff --git a/app/ui/view/molecule/image-card/image-card.stories.tsx b/app/ui/view/molecule/image-card/image-card.stories.tsx
deleted file mode 100644
index 82b7cf3c..00000000
--- a/app/ui/view/molecule/image-card/image-card.stories.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import featureIamge from '@/public/assets/tutorial/tutorial-feature1.png';
-import type { Meta, StoryObj } from '@storybook/react';
-import ImageCard, { ImageCardProps } from './image-card';
-
-const meta = {
- title: 'ui/view/molecule/ImageCard',
- component: ImageCard,
- tags: ['autodocs'],
- parameters: {
- componentSubtitle: '요소는 이미지, 제목 그리고 설명 제공되는 경우에 사용됩니다.',
- },
- argTypes: {
- image: {
- description: 'ImageCard의 이미지를 설정할 수 있습니다.',
- },
- title: {
- description: 'ImageCard의 title 내용을 설정할 수 있습니다.',
- },
- content: {
- description: 'ImageCard의 content 내용을 설정할 수 있습니다.',
- },
- },
-} as Meta
;
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {
- args: {
- image: featureIamge,
- title: 'first',
- content: '강의 커스텀을 통한 졸업 사정 예측',
- },
- render: (args: ImageCardProps) => ,
-};
diff --git a/app/ui/view/molecule/image-card/image-card.tsx b/app/ui/view/molecule/image-card/image-card.tsx
deleted file mode 100644
index 03e5acd7..00000000
--- a/app/ui/view/molecule/image-card/image-card.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { cn } from '@/app/utils/shadcn/utils';
-import Image, { StaticImageData } from 'next/image';
-
-export interface ImageCardProps {
- image: StaticImageData;
- title: string;
- content: React.ReactNode;
- className?: string;
-}
-
-function ImageCard({ image, title, content, className }: ImageCardProps) {
- return (
-
-
-
{title}
-
{content}
-
- );
-}
-
-export default ImageCard;
diff --git a/middleware.ts b/middleware.ts
index 68beb0d2..941185f9 100644
--- a/middleware.ts
+++ b/middleware.ts
@@ -27,15 +27,13 @@ async function getAuth(request: NextRequest): Promise<{
}
const allowedOnlyGuestPath = ['/sign-in', '/sign-up', '/find-password', '/find-id'];
-const allowedGuestPath = ['/tutorial', ...allowedOnlyGuestPath];
+const allowedGuestPath = ['/', '/tutorial', ...allowedOnlyGuestPath];
+const allowInitUserPath = ['/', '/tutorial', '/grade-upload'];
function isAllowedGuestPath(path: string, strict: boolean = false) {
- if (path === '/') {
- return true;
- }
-
const allowedPath = strict ? allowedOnlyGuestPath : allowedGuestPath;
- return allowedPath.some((allowedPath) => path.startsWith(allowedPath));
+
+ return allowedPath.some((allowedPath) => path === allowedPath);
}
export async function middleware(request: NextRequest) {
@@ -45,10 +43,6 @@ export async function middleware(request: NextRequest) {
return await retryAuth(request);
}
- if (auth.role === 'init' && !request.nextUrl.pathname.startsWith('/grade-upload')) {
- return Response.redirect(new URL('/grade-upload', request.url));
- }
-
if (auth.role === 'guest' && !isAllowedGuestPath(request.nextUrl.pathname)) {
return Response.redirect(new URL('/sign-in', request.url));
}
@@ -56,6 +50,14 @@ export async function middleware(request: NextRequest) {
if (auth.role !== 'guest' && isAllowedGuestPath(request.nextUrl.pathname, true)) {
return Response.redirect(new URL('/my', request.url));
}
+
+ if (auth.role === 'init' && !allowInitUserPath.some((path) => request.nextUrl.pathname === path)) {
+ return Response.redirect(new URL('/grade-upload', request.url));
+ }
+
+ if (auth.role === 'user' && request.nextUrl.pathname === '/') {
+ return Response.redirect(new URL('/my', request.url));
+ }
}
async function retryAuth(request: NextRequest) {
diff --git a/public/assets/dimond.svg b/public/assets/dimond.svg
new file mode 100644
index 00000000..14371df7
--- /dev/null
+++ b/public/assets/dimond.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/assets/file.svg b/public/assets/file.svg
new file mode 100644
index 00000000..ca1b4456
--- /dev/null
+++ b/public/assets/file.svg
@@ -0,0 +1,6 @@
+
diff --git a/public/assets/maru.png b/public/assets/maru.png
new file mode 100644
index 00000000..11403be8
Binary files /dev/null and b/public/assets/maru.png differ
diff --git a/public/assets/tutorial/tutorial-feature1.gif b/public/assets/tutorial/tutorial-feature1.gif
new file mode 100644
index 00000000..dc6a1c68
Binary files /dev/null and b/public/assets/tutorial/tutorial-feature1.gif differ
diff --git a/public/assets/tutorial/tutorial-feature1.png b/public/assets/tutorial/tutorial-feature1.png
deleted file mode 100644
index 80c6e0b9..00000000
Binary files a/public/assets/tutorial/tutorial-feature1.png and /dev/null differ
diff --git a/public/assets/tutorial/tutorial-feature2.gif b/public/assets/tutorial/tutorial-feature2.gif
new file mode 100644
index 00000000..c09bca8a
Binary files /dev/null and b/public/assets/tutorial/tutorial-feature2.gif differ
diff --git a/public/assets/tutorial/tutorial-feature2.png b/public/assets/tutorial/tutorial-feature2.png
deleted file mode 100644
index 65734ec8..00000000
Binary files a/public/assets/tutorial/tutorial-feature2.png and /dev/null differ
diff --git a/public/assets/tutorial/tutorial-feature3.gif b/public/assets/tutorial/tutorial-feature3.gif
new file mode 100644
index 00000000..f64e0cba
Binary files /dev/null and b/public/assets/tutorial/tutorial-feature3.gif differ
diff --git a/public/assets/tutorial/tutorial-feature3.png b/public/assets/tutorial/tutorial-feature3.png
deleted file mode 100644
index a8ebc3db..00000000
Binary files a/public/assets/tutorial/tutorial-feature3.png and /dev/null differ