Skip to content
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
8 changes: 8 additions & 0 deletions apps/community/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ const nextConfig: NextConfig = {
'@aics-client/design-system',
'@aics-client/design-system/styles',
],
webpack: (config) => {
// canvas는 jsdom의 서버 전용 네이티브 의존성이므로 클라이언트 번들에서 제외
config.resolve.alias = {
...config.resolve.alias,
canvas: false,
};
return config;
},
};

export default withVanillaExtract(nextConfig);
3 changes: 3 additions & 0 deletions apps/graduate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"format": "prettier --write ."
},
"dependencies": {
"@react-pdf-viewer/core": "^3.12.0",
"@react-pdf-viewer/default-layout": "^3.12.0",
"@tanstack/react-devtools": "^0.7.0",
"@tanstack/react-query": "^5.74.4",
"@tanstack/react-query-devtools": "^5.74.6",
Expand All @@ -26,6 +28,7 @@
"dayjs": "^1.11.18",
"lucide-react": "^0.503.0",
"motion": "^12.23.24",
"pdfjs-dist": "3.11.174",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-hook-form": "^7.56.1",
Expand Down
1 change: 1 addition & 0 deletions apps/graduate/src/pages/admin/all/types/allManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ export interface StageData {
createdAt: string | null;
isSubmitted: boolean;
isApproved: boolean;
fileId: number | null;
}
17 changes: 16 additions & 1 deletion apps/graduate/src/pages/admin/all/ui/AllManagementPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState } from 'react';
import { useSearch, useNavigate } from '@tanstack/react-router';
import { useState, useEffect } from 'react';

import { DataTable, Header, Pagination, Toolbar } from '~/shared/components';
import {
Expand Down Expand Up @@ -26,6 +27,8 @@ import { extractPeriodData, getStatusLabel } from '../utils';
import UserDetailModal from './UserDetailModal.tsx';

export default function AllManagementPage() {
const navigate = useNavigate();
const searchParams = useSearch({ from: '/_afterLogin/all' });
const [isModalOpen, setIsModalOpen] = useState(false);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
Expand All @@ -34,6 +37,18 @@ export default function AllManagementPage() {
const { toast, confirm } = useToast();
const [selectedStudentId, setSelectedStudentId] = useState<number>();

useEffect(() => {
if (searchParams?.graduationUserId) {
setSelectedStudentId(Number(searchParams.graduationUserId));
setIsModalOpen(true);
navigate({
to: '/all',
search: {},
replace: true,
});
}
}, [searchParams, navigate]);

const { data: schedules, error: scheduleError } = useScheduleList();

if (scheduleError) {
Expand Down
69 changes: 37 additions & 32 deletions apps/graduate/src/pages/admin/all/ui/UserDetailModal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useNavigate } from '@tanstack/react-router';
import { Descriptions, Modal, Spin, Table } from 'antd';

import { Header } from '~/shared/components';
Expand Down Expand Up @@ -27,6 +28,7 @@ export default function UserDetailModal({
graduationUserId,
period,
}: UserDetailModalProps) {
const navigate = useNavigate();
const {
data: studentDetail,
isLoading,
Expand All @@ -50,27 +52,32 @@ export default function UserDetailModal({
dataIndex: 'stage',
key: 'stage',
render: (_: string, record: StageData) => {
if (record.isSubmitted) {
return (
<button
type='button'
style={{
background: 'none',
border: 'none',
padding: 0,
cursor: 'pointer',
color: vars.colors.main,
textDecoration: 'underline',
}}
onClick={() => {
console.log('미리보기 구현');
}}
>
{record.stage}
</button>
);
}
return record.stage;
return record.isSubmitted && status ? (
<button
type='button'
style={{
background: 'none',
border: 'none',
padding: 0,
cursor: 'pointer',
color: vars.colors.main,
textDecoration: 'underline',
}}
onClick={() => {
navigate({
to: '/file-preview',
search: {
fileId: record.fileId!,
type: status.type,
},
});
}}
>
{record.stage}
</button>
) : (
<span>{record.stage}</span>
);
},
},
{ title: '일정', dataIndex: 'period', key: 'period' },
Expand Down Expand Up @@ -133,17 +140,15 @@ export default function UserDetailModal({
</Descriptions>
</Container>

{status && (
<Container style={{ padding: '0px' }}>
<Table
dataSource={stageData}
columns={columns}
pagination={false}
bordered
rowKey='key'
/>
</Container>
)}
<Container style={{ padding: '0px' }}>
<Table
dataSource={stageData}
columns={columns}
pagination={false}
bordered
rowKey='key'
/>
</Container>
</>
);
};
Expand Down
3 changes: 3 additions & 0 deletions apps/graduate/src/pages/admin/all/utils/buildStageData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export function buildStageData(
createdAt: status.certificate.createdAt,
isSubmitted: status.certificate.submitted,
isApproved: status.certificate.approval,
fileId: status.certificate.fileId,
},
];
} else {
Expand All @@ -38,6 +39,7 @@ export function buildStageData(
createdAt: status.midThesis.createdAt,
isSubmitted: status.midThesis.submitted,
isApproved: status.midThesis.approval,
fileId: status.midThesis.fileId,
},
{
key: 'finalthesis',
Expand All @@ -46,6 +48,7 @@ export function buildStageData(
createdAt: status.finalThesis.createdAt,
isSubmitted: status.finalThesis.submitted,
isApproved: status.finalThesis.approval,
fileId: status.finalThesis.fileId,
},
];
}
Expand Down
1 change: 1 addition & 0 deletions apps/graduate/src/pages/admin/filePreview/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useFile } from './useFile';
25 changes: 25 additions & 0 deletions apps/graduate/src/pages/admin/filePreview/hooks/useFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useQuery } from '@tanstack/react-query';

import { getCertificateFile, getThesisFile } from '~/shared/api/file';
import { KEYS } from '~/shared/constants';

import { transformCertificateResponse } from '../util/transformCertificateFileResponse';
import { transformThesisResponse } from '../util/transformThesisFileResponse';

type FileType = 'CERTIFICATE' | 'THESIS';

export function useFile(fileId: number, type: FileType) {
return useQuery({
queryKey: [KEYS.STUDENT_FILE, type.toLowerCase(), fileId],
queryFn: async () => {
if (type === 'CERTIFICATE') {
const response = await getCertificateFile(fileId);
return transformCertificateResponse(response.data);
} else {
const response = await getThesisFile(fileId);
return transformThesisResponse(response.data);
}
},
enabled: !!fileId,
});
}
1 change: 1 addition & 0 deletions apps/graduate/src/pages/admin/filePreview/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as FilePreviewPage } from './ui/FilePreviewPage';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface FileItem {
graduationUserid: number;
scheduleId: number;
approval: boolean;
file: {
fileId: number;
physicalPath: string;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { style } from '@vanilla-extract/css';

import { vars } from '~/vars.css';

export const loading = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
fontSize: vars.font.size.lg,
color: vars.colors.subText,
});

export const error = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
fontSize: vars.font.size.lg,
color: vars.colors.error,
});

export const empty = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
fontSize: vars.font.size.lg,
color: vars.colors.subDark,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { style } from '@vanilla-extract/css';

import { vars } from '~/vars.css';

export const toolbar = style({
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gridTemplateRows: 'auto auto',
gap: vars.spacing.sm,
padding: vars.spacing.md,
backgroundColor: vars.colors.white,
border: `1px solid ${vars.colors.border}`,
borderRadius: vars.radius.md,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
});

export const infoItem = style({
fontSize: vars.font.size.md,
color: vars.colors.label,
fontWeight: vars.font.weight.medium,
display: 'flex',
alignItems: 'center',
padding: vars.spacing.xs,
});

export const button = style({
width: '100%',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { style } from '@vanilla-extract/css';

import { vars } from '~/vars.css';

export const root = style({
display: 'flex',
flexDirection: 'column',
height: '100vh',
width: '100vw',
overflow: 'hidden',
backgroundColor: vars.colors.sub,
});
export const container = style({
padding: vars.spacing.xl,
maxWidth: '1200px',
margin: '0 auto',
});
export const backButtonWrapper = style({
marginBottom: vars.spacing.sm,
});

export const filePreviewContainer = style({
position: 'relative',
width: '100%',
height: 'calc(100vh - 200px)',
overflow: 'auto',
backgroundColor: vars.colors.sub,
});

export const toolbarWrapper = style({
position: 'absolute',
bottom: vars.spacing.lg,
left: '50%',
transform: 'translateX(-50%)',
zIndex: 10,
transition: 'opacity 0.3s ease-in-out',
opacity: 1,
pointerEvents: 'auto',
selectors: {
'&[data-visible="false"]': {
opacity: 0,
pointerEvents: 'none',
},
},
});
Loading
Loading