Skip to content
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

grade upload/#9 #41

Merged
merged 18 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions app/(sub-page)/file-upload/page.tsx

This file was deleted.

32 changes: 32 additions & 0 deletions app/(sub-page)/grade-upload/components/manual.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default function Manual() {
return (
<div className="flex justify-center">
<div className="flex flex-col gap-6">
<h1 className="text-center text-3xl font-bold p-4 border-b-2 border-gray-100 md:text-4xl">
ํ•œ ๋ฒˆ์˜ ์„ฑ์ ํ‘œ ์ž…๋ ฅ์œผ๋กœ
<br /> ๋งž์ถคํ˜• ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜์„ธ์š” !
</h1>
<div className="text-base flex flex-col gap-2 md:text-lg">
<div>
1.
<a
target="_blank"
className="pl-1 text-primary hover:text-dark-hover"
href="https://msi.mju.ac.kr/servlet/security/MySecurityStart"
>
MyiWeb MSI
</a>
์— ์ ‘์† ํ›„ ๋กœ๊ทธ์ธ(PCํ™˜๊ฒฝ ๊ถŒ์žฅ)
</div>
<div>2. ์ขŒ์ธก ์„ฑ์ /์กธ์—… ๋ฉ”๋‰ด โ†’ ์„ฑ์ ํ‘œ(์ƒ๋‹ด์šฉ,B4)ํด๋ฆญ</div>
<div>3. ์šฐ์ธก ์ƒ๋‹จ ์กฐํšŒ๋ฒ„ํŠผ ํด๋ฆญ โ†’ ํ”„๋ฆฐํŠธ ์•„์ด์ฝ˜ ํด๋ฆญ</div>
<div>4. ์ธ์‡„ ์ •๋ณด์˜ ๋Œ€์ƒ(PDF๋กœ ์ €์žฅ) ์„ค์ • โ†’ ํ•˜๋‹จ ์ €์žฅ ๋ฒ„ํŠผ ํด๋ฆญ </div>
<div>5. ์ €์žฅํ•œ ํŒŒ์ผ ์—…๋กœ๋“œ </div>
<div className="text-xs md:text-sm text-primary">
โ€ข ํšŒ์› ๊ฐ€์ž…ํ•œ ํ•™๋ฒˆ๊ณผ ์ผ์น˜ํ•˜๋Š” ํ•™๋ฒˆ์˜ ์„ฑ์ ํ‘œ๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
</div>
</div>
</div>
</div>
);
}
12 changes: 12 additions & 0 deletions app/(sub-page)/grade-upload/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import ContentContainer from '../../ui/view/atom/content-container';
import Manual from './components/manual';
import UploadTakenLecture from '../../ui/lecture/upload-taken-lecture/upload-taken-lecture';

export default function GradeUploadPage() {
return (
<ContentContainer className="flex flex-col justify-center gap-8 min-h-[70vh]">
<Manual />
<UploadTakenLecture />
</ContentContainer>
);
}
18 changes: 18 additions & 0 deletions app/__test__/ui/view/upload-pdf.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import UploadPdf from '@/app/ui/view/molecule/upload-pdf/upload-pdf';
import { render, screen } from '@testing-library/react';
import fireEvent from '@testing-library/user-event';

describe('์„ฑ์  ์—…๋กœ๋“œ', () => {
it('pdf๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ์ˆ˜ ์—†๋‹ค', async () => {
render(<UploadPdf />);

const targetFile = new File(['grade'], 'grade.pdf', {
type: 'text/plain',
});

const uploadBox = await screen.findByTestId('upload-box');
fireEvent.upload(uploadBox, targetFile);

expect(screen.queryByText('์ถ”๊ฐ€')).not.toBeInTheDocument();
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[request change]

  • ์ด ๋ถ€๋ถ„์€ ์ง€๊ธˆ ํ™•์ธํ•ด์„œ ์ฝ”๋ฉ˜ํŠธ๋ฅผ ๋‚จ๊น๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ๋ช…๋งŒ ๋ณด๋ฉด pdf๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ์ด ์—…๋กœ๋“œ๋  ๋•Œ ์—…๋กœ๋“œ๊ฐ€ ์•ˆ ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ํ…Œ์ŠคํŠธ ๋‚ด์šฉ์„ ๋ณด๋ฉด pdf ํŒŒ์ผ์„ ์—…๋กœ๋“œํ–ˆ์„ ๋•Œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  • ๋‘ ๊ฐ€์ง€ ์ˆ˜์ •์‚ฌํ•ญ์„ ์ œ์•ˆํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  • ์ฒซ์งธ, ํ…Œ์ŠคํŠธ๋ช…์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ช…๋งŒ ๋ณด์•„๋„ ์–ด๋–ค ํ…Œ์ŠคํŠธ์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ช…์— ๋Œ€ํ•œ ์˜๊ฒฌ์€ PR #42์— ๋‚จ๊ฒจ๋‘์—ˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  • ๋‘˜์งธ, ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. pdf ํŒŒ์ผ์„ ์—…๋กœ๋“œํ–ˆ์„ ๋•Œ์™€ pdf๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ–ˆ์„ ๋•Œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.
  • ํ˜„์žฌ๋Š” ์ฒ˜๋ฆฌ๊ฐ€ ์•ˆ ๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ, ์„ฑ์ ํ‘œ๊ฐ€ ์•„๋‹Œ pdf๊ฐ€ ์—…๋กœ๋“œ๋˜์—ˆ์„ ๋•Œ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ ๋‚˜์ค‘์— ์ถ”๊ฐ€๋˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋„ค์š”.

});
2 changes: 2 additions & 0 deletions app/business/api-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ const BASE_URL = process.env.API_MOCKING === 'enable' ? 'http://localhost:9090'

export const API_PATH = {
revenue: `${BASE_URL}/revenue`,
registerUserGrade: `${BASE_URL}/registerUserGrade`,
parsePDFtoText: `${BASE_URL}/parsePDFtoText`,
takenLectures: `${BASE_URL}/taken-lectures`,
};
35 changes: 35 additions & 0 deletions app/business/lecture/taken-lecture.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use server';
import { FormState } from '@/app/ui/view/molecule/form/form-root';
import { API_PATH } from '../api-path';

export const registerUserGrade = async (prevState: FormState, formData: FormData) => {
const parsingText = await parsePDFtoText(formData);

const res = await fetch(API_PATH.registerUserGrade, {
method: 'POST',
body: JSON.stringify({ parsingText }),
});

if (!res.ok) {
return {
errors: {},
message: 'fail upload grade',
};
}

return {
errors: {},
message: '',
};
};

export const parsePDFtoText = async (formData: FormData) => {
const res = await fetch(API_PATH.parsePDFtoText, { method: 'POST', body: formData });
if (!res.ok) {
return {
errors: {},
message: 'fail parsing to text',
};
}
return await res.json();
};
19 changes: 19 additions & 0 deletions app/hooks/usePdfFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useState } from 'react';
import { z } from 'zod';

export type FileType = File | null;

export default function usePdfFile() {
const [file, setFile] = useState<FileType>(null);

const changeFile = (file: File) => {
if (!validate.parse(file.name)) return;
setFile(file);
};

const validate = z.string().refine((value) => value.endsWith('.pdf'), {
message: 'File must be a PDF',
});

return { file, changeFile };
}
2 changes: 2 additions & 0 deletions app/mocks/data.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export const revenue = [
{ month: 'Nov', revenue: 3000 },
{ month: 'Dec', revenue: 4800 },
];
export const parsePDF =
'์ถœ๋ ฅ์ผ์ž : 2022/10/05|1/1|ICT์œตํ•ฉ๋Œ€ํ•™ ์œตํ•ฉ์†Œํ”„ํŠธ์›จ์–ดํ•™๋ถ€ ์‘์šฉ์†Œํ”„ํŠธ์›จ์–ด์ „๊ณต, ๋ชจ์œ ๊ฒฝ(60201671), ํ˜„ํ•™์  - ์žฌํ•™, ์ด์ˆ˜ - 4, ์ž…ํ•™ - ์‹ ์ž…ํ•™(2020/03/02)|ํ† ์ต - 440, ์˜์–ด๊ต๊ณผ๋ชฉ๋ฉด์ œ - ๋ฉด์ œ์—†์Œ, ์ตœ์ข…ํ•™์ ๋ณ€๋™ - ๋ถˆ์ผ์น˜๋ณตํ•™(2022/07/12)|ํŽธ์ž…์ƒ ์ธ์ •ํ•™์  - ๊ต์–‘ 0, ์ „๊ณต 0, ์ž์œ ์„ ํƒ 0, ์„ฑ๊ฒฝ๊ณผ์ธ๊ฐ„์ดํ•ด 0|๊ตํ™˜ํ•™์ƒ ์ธ์ •ํ•™์  - ํ•™๋ฌธ๊ธฐ์ดˆ๊ต์–‘ 0, ์ผ๋ฐ˜๊ต์–‘ 0, ์ „๊ณต 0, ๋ณต์ˆ˜์ „๊ณตํ•™๋ฌธ๊ธฐ์ดˆ๊ต์–‘ 0, ๋ณต์ˆ˜์ „๊ณต 0, ์—ฐ๊ณ„์ „๊ณต 0, ๋ถ€์ „๊ณต 0, ์ž์œ ์„ ํƒ 0|๊ณตํ†ต๊ต์–‘ 17, ํ•ต์‹ฌ๊ต์–‘ 12, ํ•™๋ฌธ๊ธฐ์ดˆ๊ต์–‘ 12, ์ผ๋ฐ˜๊ต์–‘ 3, ์ „๊ณต 33, ๋ณต์ˆ˜์ „๊ณต 0, ์—ฐ๊ณ„์ „๊ณต 0, ๋ถ€์ „๊ณต 0, ๊ต์ง 0, ์ž์œ ์„ ํƒ 0|์ด ์ทจ๋“ํ•™์  - 77, ์ด์  - 296.5, ํ‰๊ท ํ‰์  - 4.06|์ด์ˆ˜๊ตฌ๋ถ„|์ˆ˜๊ฐ•๋…„๋„/ํ•™๊ธฐ|ํ•œ๊ธ€์ฝ”๋“œ|๊ณผ๋ชฉ์ฝ”๋“œ|๊ณผ๋ชฉ๋ช…|ํ•™์ |๋“ฑ๊ธ‰|์ค‘๋ณต|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2020๋…„ 2ํ•™๊ธฐ|๊ตํ•„141|KMA02141|4์ฐจ์‚ฐ์—…ํ˜๋ช…๊ณผ๋ฏธ๋ž˜์‚ฌํšŒ์ง„๋กœ์„ ํƒ|2|P|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2021๋…„ 1ํ•™๊ธฐ|๊ตํ•„104|KMA02104|๊ธ€์“ฐ๊ธฐ|3|A+|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2021๋…„ 2ํ•™๊ธฐ|๊ตํ•„122|KMA02122|๊ธฐ๋…๊ต์™€๋ฌธํ™”|2|A0|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2020๋…„ 1ํ•™๊ธฐ|๊ตํ•„106|KMA02106|์˜์–ด1|2|A0|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2021๋…„ 1ํ•™๊ธฐ|๊ตํ•„107|KMA02107|์˜์–ด2|2|A0|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2021๋…„ 1ํ•™๊ธฐ|๊ตํ•„108|KMA02108|์˜์–ดํšŒํ™”1|1|B+|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2021๋…„ 2ํ•™๊ธฐ|๊ตํ•„109|KMA02109|์˜์–ดํšŒํ™”2|1|B+|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2020๋…„ 1ํ•™๊ธฐ|๊ตํ•„101|KMA02101|์ฑ„ํ”Œ|0.5|P|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2020๋…„ 2ํ•™๊ธฐ|๊ตํ•„101|KMA02101|์ฑ„ํ”Œ|0.5|P|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2021๋…„ 1ํ•™๊ธฐ|๊ตํ•„101|KMA02101|์ฑ„ํ”Œ|0.5|P|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2021๋…„ 2ํ•™๊ธฐ|๊ตํ•„101|KMA02101|์ฑ„ํ”Œ|0.5|P|๊ณตํ†ต๊ต์–‘ (๊ตฌ ํ•„์ˆ˜๊ต์–‘)|2020๋…„ 2ํ•™๊ธฐ|๊ตํ•„102|KMA02102|ํ˜„๋Œ€์‚ฌํšŒ์™€๊ธฐ๋…๊ต์œค๋ฆฌ|2|A+|ํ•ต์‹ฌ๊ต์–‘ (๊ตฌ ์„ ํƒ๊ต์–‘)|2021๋…„ 1ํ•™๊ธฐ|๊ต์„ 130|KMA02130|๊ณ ์ „์œผ๋กœ์ฝ๋Š”์ธ๋ฌธํ•™|3|B+|ํ•ต์‹ฌ๊ต์–‘ (๊ตฌ ์„ ํƒ๊ต์–‘)|2020๋…„ 1ํ•™๊ธฐ|๊ต์„ 127|KMA02127|์ฐฝ์—…์ž…๋ฌธ|3|A+|ํ•ต์‹ฌ๊ต์–‘ (๊ตฌ ์„ ํƒ๊ต์–‘)|2021๋…„ 2ํ•™๊ธฐ|๊ต์„ 110|KMA02110|์ฒ ํ•™๊ณผ์ธ๊ฐ„|3|A+|ํ•ต์‹ฌ๊ต์–‘ (๊ตฌ ์„ ํƒ๊ต์–‘)|2020๋…„ 2ํ•™๊ธฐ|๊ต์„ 142|KMA02142|ํ˜„๋Œ€์‚ฌํšŒ์™€์‹ฌ๋ฆฌํ•™|3|A+|ํ•™๋ฌธ๊ธฐ์ดˆ๊ต์–‘ (๊ตฌ ๊ธฐ์ดˆ๊ต์–‘)|2020๋…„ 2ํ•™๊ธฐ|๊ธฐ์‚ฌ133|KMD02133|ICT๋น„์ฆˆ๋‹ˆ์Šค์™€๊ฒฝ์˜|3|A+|ํ•™๋ฌธ๊ธฐ์ดˆ๊ต์–‘ (๊ตฌ ๊ธฐ์ดˆ๊ต์–‘)|2020๋…„ 1ํ•™๊ธฐ|๊ธฐ์‚ฌ134|KMD02134|๋งˆ์ผ€ํŒ…๊ณผICT์œตํ•ฉ๊ธฐ์ˆ |3|A+|ํ•™๋ฌธ๊ธฐ์ดˆ๊ต์–‘ (๊ตฌ ๊ธฐ์ดˆ๊ต์–‘)|2020๋…„ 1ํ•™๊ธฐ|๊ธฐ์‚ฌ135|KMD02135|์ €์ž‘๊ถŒ๊ณผ์†Œํ”„ํŠธ์›จ์–ด|3|A+|ํ•™๋ฌธ๊ธฐ์ดˆ๊ต์–‘ (๊ตฌ ๊ธฐ์ดˆ๊ต์–‘)|2020๋…„ 2ํ•™๊ธฐ|๊ธฐ์ปด112|KMI02112|์ปดํ“จํ„ฐ๋…ผ๋ฆฌ์˜์ดํ•ด|3|A+|์ผ๋ฐ˜๊ต์–‘ (๊ตฌ ๊ท ํ˜•๊ต์–‘)|2020๋…„ 2ํ•™๊ธฐ|๊ธฐ์ปด125|KMI02125|์ƒํ™œ์†์˜์Šค๋งˆํŠธIT(KCU)|3|A+|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 1ํ•™๊ธฐ|์‘์†Œ204|HEC01204|DB์„ค๊ณ„๋ฐ๊ตฌํ˜„1|3|B+|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 2ํ•™๊ธฐ|์‘์†Œ305|HEC01305|DB์„ค๊ณ„๋ฐ๊ตฌํ˜„2|3|B+|์ „๊ณต1๋‹จ๊ณ„|2020๋…„ 2ํ•™๊ธฐ|์œต์†Œ103|HEB01103|๊ฐ์ฒด์ง€ํ–ฅ์ ์‚ฌ๊ณ ์™€ํ”„๋กœ๊ทธ๋ž˜๋ฐ|3|B0|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 1ํ•™๊ธฐ|์‘์†Œ208|HEC01208|๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜1|3|B+|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 2ํ•™๊ธฐ|์‘์†Œ207|HEC01207|๋ฐ์ดํ„ฐ๊ตฌ์กฐ์™€์•Œ๊ณ ๋ฆฌ์ฆ˜2|3|B+|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 2ํ•™๊ธฐ|์‘์†Œ212|HEC01212|์‹œ์Šคํ…œํ”„๋กœ๊ทธ๋ž˜๋ฐ1|3|B+|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 1ํ•™๊ธฐ|์‘์†Œ211|HEC01211|์›นํ”„๋กœ๊ทธ๋ž˜๋ฐ1|3|A+|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 2ํ•™๊ธฐ|์‘์†Œ209|HEC01209|์›นํ”„๋กœ๊ทธ๋ž˜๋ฐ2|3|A0|์ „๊ณต1๋‹จ๊ณ„|2020๋…„ 1ํ•™๊ธฐ|์œต์†Œ101|HEB01101|์ ˆ์ฐจ์ ์‚ฌ๊ณ ์™€ํ”„๋กœ๊ทธ๋ž˜๋ฐ|3|A+|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 2ํ•™๊ธฐ|์‘์†Œ210|HEC01210|ํด๋ผ์ด์–ธํŠธ์„œ๋ฒ„ํ”„๋กœ๊ทธ๋ž˜๋ฐ|3|A0|์ „๊ณต1๋‹จ๊ณ„|2021๋…„ 1ํ•™๊ธฐ|์‘์†Œ202|HEC01202|ํŒจํ„ด์ค‘์‹ฌ์‚ฌ๊ณ ์™€ํ”„๋กœ๊ทธ๋ž˜๋ฐ|3|A0||';

export const takenLectures = JSON.parse(`{
"totalCredit": 115,
Expand Down
14 changes: 13 additions & 1 deletion app/mocks/handlers.mock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HttpResponse, http, delay } from 'msw';
import { revenue, takenLectures } from './data.mock';
import { revenue, parsePDF, takenLectures } from './data.mock';
import { API_PATH } from '../business/api-path';

export const handlers = [
Expand All @@ -8,6 +8,18 @@ export const handlers = [
console.log(revenue);
return HttpResponse.json(revenue);
}),

http.post(API_PATH.parsePDFtoText, async () => {
await delay(1000);
console.log(parsePDF);
return HttpResponse.json(parsePDF);
}),

http.post(API_PATH.registerUserGrade, async () => {
await delay(1000);
throw new HttpResponse(null, { status: 200 });
}),

http.get(API_PATH.takenLectures, () => {
return HttpResponse.json(takenLectures);
}),
Expand Down
16 changes: 16 additions & 0 deletions app/ui/lecture/upload-taken-lecture/upload-taken-lecture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client';

import { registerUserGrade } from '@/app/business/lecture/taken-lecture.command';
import UploadPdf from '@/app/ui/view/molecule/upload-pdf/upload-pdf';
import Form from '../../view/molecule/form';

function UploadTakenLecture() {
return (
<Form action={registerUserGrade} id="์„ฑ์ ์—…๋กœ๋“œ">
<UploadPdf />
<Form.SubmitButton label="๊ฒฐ๊ณผ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ" position="center" size="md" />
</Form>
);
}

export default UploadTakenLecture;
13 changes: 13 additions & 0 deletions app/ui/view/molecule/upload-pdf/upload-pdf.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Meta, StoryObj } from '@storybook/react';
import UploadPdf from './upload-pdf';

const meta = {
title: 'ui/view/molecule/UploadFile',
component: UploadPdf,
} satisfies Meta<typeof UploadPdf>;

export default meta;

export const Default: StoryObj<typeof meta> = {
render: () => <UploadPdf />,
};
40 changes: 40 additions & 0 deletions app/ui/view/molecule/upload-pdf/upload-pdf.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client';
import Image from 'next/image';
import uploadBox from '@/public/assets/upload-box.svg';
import checkedBox from '@/public/assets/checked-box.svg';
import usePdfFile from '@/app/hooks/usePdfFile';
import { ChangeEvent } from 'react';

function UploadPdf() {
const { file, changeFile } = usePdfFile();

const handleChangeFileInput = (event: ChangeEvent<HTMLInputElement>) => {
const { files } = event.target;
if (files) changeFile(files[0]);
};

return (
<div className="flex flex-col items-center gap-4">
<div
role="button"
className="relative p-2 m-auto w-96 flex flex-col justify-center items-center gap-2 border-dashed border-2 rounded-sm rounded-bl-xl border-light-blue-6 bg-light-blue-1 text-light-blue-6 max-lg:w-80"
>
<Image src={file ? checkedBox : uploadBox} width={40} height={28} className="mx-auto" alt="upload-button" />
<span className="text-center break-keep whitespace-pre-line max-w-48 truncate">
{file ? file.name : '๋งˆ์šฐ์Šค๋กœ ๋“œ๋ž˜๊ทธ ํ•˜๊ฑฐ๋‚˜ ์•„์ด์ฝ˜์„ ๋ˆŒ๋Ÿฌ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.'}
</span>
<input
onChange={handleChangeFileInput}
type="file"
className="absolute bg-black opacity-0 w-96 max-lg:w-80 h-full"
name="file"
accept=".pdf"
data-testid="upload-box"
required
/>
</div>
</div>
);
}

export default UploadPdf;
5 changes: 5 additions & 0 deletions public/assets/checked-box.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/assets/upload-box.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading