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

Feature/#141 예외 처리 코드 개선 #149

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,25 @@ const MilestoneHistorySection = async () => {
);

return (
<div className="w-full min-w-[260px] flex-1 rounded-sm bg-white p-5 lg:max-w-[280px]">
<div className="relative w-full min-w-[260px] flex-1 rounded-sm bg-white p-5 lg:max-w-[280px]">
<SubTitle title="실적 등록" urlText="등록하기" url="/my-page/milestone/register" />
<div className="mt-4">
{milestoneHistoriesOfStudent?.content.map((milestoneHistory) => (
<div key={milestoneHistory.id} className="flex flex-col gap-[2px] border-b border-border py-2">
<p>{milestoneHistory.description}</p>
<p className="flex items-end justify-between">
<span className="text-xs text-comment">활동일: {milestoneHistory.activatedAt}</span>
<MilestoneHistoryStatusLabel
status={milestoneHistory.status}
rejectReason={milestoneHistory.rejectReason}
/>
</p>
</div>
))}
{milestoneHistoriesOfStudent ? (
milestoneHistoriesOfStudent.content.map((milestoneHistory) => (
<div key={milestoneHistory.id} className="flex flex-col gap-[2px] border-b border-border py-2">
<p>{milestoneHistory.description}</p>
<p className="flex items-end justify-between">
<span className="text-xs text-comment">활동일: {milestoneHistory.activatedAt}</span>
<MilestoneHistoryStatusLabel
status={milestoneHistory.status}
rejectReason={milestoneHistory.rejectReason}
/>
</p>
</div>
))
) : (
<div className="absolute inset-0 flex items-center justify-center text-comment">등록한 실적이 없습니다.</div>
)}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import SubTitle from '@/components/SubTitle';
import { useAppSelector } from '@/lib/hooks/redux';
import { useStudentMemberQuery } from '@/lib/hooks/useApi';
import { appendDashPhoneNumber, convertCareer } from '@/lib/utils/utils';
import { VscWarning } from '@react-icons/all-files/vsc/VscWarning';

import StudentInfoLabel from './StudentInfoLabel';

Expand All @@ -14,9 +15,9 @@ const StudentInfoSection = () => {
const auth = useAppSelector((state) => state.auth).value;
const { data: member } = useStudentMemberQuery(auth.uid);
return (
<div className="flex-grow rounded-sm bg-white p-5">
<div className="relative flex-grow rounded-sm bg-white p-5">
<SubTitle title="내 정보" urlText="수정" url="/my-page/edit" />
{member && (
{member ? (
<div className="my-5">
<div className="mb-5 flex flex-wrap items-end gap-4">
<p className="text-xl font-bold">{member.name}</p>
Expand All @@ -42,6 +43,14 @@ const StudentInfoSection = () => {
/>
</div>
</div>
) : (
<div className="text-admin-semantic-error-light absolute inset-0 flex flex-col items-center justify-center gap-2 text-center">
<VscWarning className="h-8 w-8" />
<p>
학생 정보를 불러오는 데<br />
실패했습니다.
</p>
</div>
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const MilestoneOverview = ({ searchFilterPeriod }: MilestoneOverviewProps) => {
[milestoneScoresOfStudent],
);
return (
<div className="flex flex-wrap justify-center gap-4">
<div className="flex flex-wrap justify-center gap-4 md:flex-nowrap">
<MilestoneWrapper>
<MilestoneChart chartSize={180} fontSize="lg" milestoneOverviewScore={milestoneOverviewScore} />
<MilestoneTable milestoneOverviewScore={milestoneOverviewScore} />
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/CustomLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const CustomLayout = ({ children }: Readonly<{ children: React.ReactNode }>) =>
<AdminHeader />
<AdminSidebar />
<AdminPageWrapper>
<section className="m-5 min-h-[80vh] min-w-admin rounded-sm bg-white p-5">{children}</section>
<section className="relative m-5 min-h-[80vh] min-w-admin rounded-sm bg-white p-5">{children}</section>
<AdminFooter />
</AdminPageWrapper>
</>
Expand Down
18 changes: 18 additions & 0 deletions frontend/src/app/admin/milestone/list/[slug]/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Link from 'next/link';

export default function NotFound() {
return (
<div className="absolute inset-0 flex items-center justify-center">
<div className="flex h-full flex-col items-center justify-center gap-2">
<h2 className="text-xl font-semibold">404 Not Found</h2>
<p>요청하신 리소스를 찾을 수 없습니다.</p>
<Link
href="/admin/milestone/list"
className="mt-4 rounded-sm bg-admin-primary-main px-4 py-2 text-sm text-white hover:bg-admin-primary-dark"
>
목록으로
</Link>
</div>
</div>
);
}
4 changes: 4 additions & 0 deletions frontend/src/app/admin/milestone/list/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { convertMilestoneHistoryStatus } from '@/lib/utils/utils';

import FilePreview from './components/FilePreview';
import MilestoneHistoryStatusChangeButton from './components/MilestoneHistoryStatusChangeButton';
import { notFound } from 'next/navigation';

interface MilestoneHistoryDetailPageProps {
params: {
Expand All @@ -16,6 +17,9 @@ interface MilestoneHistoryDetailPageProps {

const Page = async ({ params: { slug } }: MilestoneHistoryDetailPageProps) => {
const history = await getMilestoneHistory(slug);

if (!history) notFound();

return (
<div className="flex flex-col gap-8">
<div className="flex w-full gap-4">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { useMilestoneHistoryExcelFileQuery } from '@/lib/hooks/useAdminApi';
import { useMemo } from 'react';
import { toast } from 'react-toastify';

interface MilestoneHistoryExcelFileDownloadButtonProps {
field: number | null;
Expand All @@ -17,14 +18,25 @@ const MilestoneHistoryExcelFileDownloadButton = ({ field, keyword }: MilestoneHi
return '';
}, [excelFile]);

const handleExcelDownloadButtonClick = () => {
if (!excelFileUrl) {
toast.error('파일을 불러오는 데 실패하였습니다.');
return;
}
const a = document.createElement('a');
a.href = excelFileUrl;
a.download = '마일스톤_실적_내역_목록.xlsx';
a.click();
};

return (
<a
<button
type="button"
className="rounded-sm bg-admin-primary-main px-4 py-2 text-white hover:bg-admin-primary-dark"
href={excelFileUrl}
download={'마일스톤_실적_내역_목록.xlsx'}
onClick={handleExcelDownloadButtonClick}
>
Excel로 다운로드
</a>
</button>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const MilestoneHistoryTable = ({ histories }: MilestoneHistoryTableProps) => {
</tr>
</thead>
<tbody>
{histories.map((history) => (
{histories?.map((history) => (
<tr
key={history.id}
className="cursor-pointer border-b-[1px] border-admin-border hover:bg-admin-background-light [&_td]:h-[50px] [&_td]:break-keep"
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/app/admin/milestone/list/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ const Page = async ({ searchParams }: { searchParams?: { [key: string]: string |
<div>
<div className="flex items-center rounded-sm border-[1px] border-admin-border bg-admin-background-light px-5 py-3 text-sm">
<span className="mr-20">
총 <span className="text-admin-primary-main">{milstoneHistories.totalElements}</span>건의 내역이 있습니다.
총 <span className="text-admin-primary-main">{milstoneHistories?.totalElements ?? 0}</span>건의 내역이
있습니다.
</span>
<SearchBox
initialValues={{ field, keyword }}
fieldCategories={milestoneHistorySearchField}
path="/admin/milestone/list"
/>
</div>
<MilestoneHistoryTable histories={milstoneHistories.content} />
<MilestoneHistoryTable histories={milstoneHistories?.content} />
<div className="flex justify-end">
<MilestoneHistoryExcelFileDownloadButton field={field} keyword={keyword} />
</div>
<Pagination currentPage={page} totalItems={milstoneHistories.totalElements} pathname={pathname} />
<Pagination currentPage={page} totalItems={milstoneHistories?.totalElements} pathname={pathname} />
</div>
);
};
Expand Down
20 changes: 16 additions & 4 deletions frontend/src/app/admin/milestone/rank/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useMilestoneHistoryScoreExcelFileQuery, useMilestoneScoresQuery } from
import { useMilestoneQuery } from '@/lib/hooks/useApi';
import { convertMilestoneGroup } from '@/lib/utils/utils';
import { Period } from '@/types/common';
import { toast } from 'react-toastify';

const Page = ({ searchParams }: { searchParams?: { [key: string]: string | undefined } }) => {
const [filterPeriod, setFilterPeriod] = useState<Period>({
Expand Down Expand Up @@ -45,6 +46,17 @@ const Page = ({ searchParams }: { searchParams?: { [key: string]: string | undef
);
const { data: milestones } = useMilestoneQuery();

const handleExcelDownloadButtonClick = () => {
if (!excelFileUrl) {
toast.error('파일을 불러오는 데 실패하였습니다.');
return;
}
const a = document.createElement('a');
a.href = excelFileUrl;
a.download = '마일스톤_점수_현황.xlsx';
a.click();
};

return (
<div>
<div className="mb-8 flex justify-end">
Expand Down Expand Up @@ -108,13 +120,13 @@ const Page = ({ searchParams }: { searchParams?: { [key: string]: string | undef
</table>
</div>
<div className="flex justify-end">
<a
<button
type="button"
className="rounded-sm bg-admin-primary-main px-4 py-2 text-white hover:bg-admin-primary-dark"
href={excelFileUrl}
download={'마일스톤_점수_현황.xlsx'}
onClick={handleExcelDownloadButtonClick}
>
Excel로 다운로드
</a>
</button>
</div>
<Pagination currentPage={page} totalItems={milestoneScores?.totalElements ?? 0} pathname={pathname} />
</div>
Expand Down
38 changes: 34 additions & 4 deletions frontend/src/app/admin/milestone/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,50 @@ const Page = () => {

const { mutate: registerHistories } = useRegisterHistoryInBatchMutation();

const handleStandardFileDownloadButtonClick = () => {
if (!standardFileUrl) {
toast.error('파일을 불러오는 데 실패하였습니다.');
return;
}
const a = document.createElement('a');
a.href = standardFileUrl;
a.download = '마일스톤_실적_내역_목록.xlsx';
a.click();
};

const handleSampleFileDownloadButtonClick = () => {
if (!sampleFileUrl) {
toast.error('파일을 불러오는 데 실패하였습니다.');
return;
}
const a = document.createElement('a');
a.href = sampleFileUrl;
a.download = '마일스톤_실적_내역_목록.xlsx';
a.click();
};

return (
<>
<div className="flex items-center rounded-sm border-[1px] border-admin-border bg-admin-background-light px-5 py-3 text-sm">
<p className="flex flex-1 justify-center gap-1">
점수 산정 기준 표 - <Image src="/images/admin/pdf_icon.svg" alt="pdf" width="16" height="16" />
<a className="pl-[0.5px] text-red-500 underline underline-offset-4" href={standardFileUrl} download>
<button
type="button"
onClick={handleStandardFileDownloadButtonClick}
className="pl-[0.5px] text-red-500 underline underline-offset-4"
>
점수산정파일.pdf
</a>
</button>
</p>
<p className="flex flex-1 justify-center gap-1">
일괄등록 파일 예시 - <Image src="/images/admin/xlsx_icon.svg" alt="xlsx" width="16" height="16" />
<a className="pl-[0.5px] text-green-500 underline underline-offset-4" href={sampleFileUrl} download>
<button
type="button"
onClick={handleSampleFileDownloadButtonClick}
className="pl-[0.5px] text-green-500 underline underline-offset-4"
>
sample.xlsx
</a>
</button>
</p>
</div>
<Formik
Expand Down