Skip to content
Open
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
16 changes: 16 additions & 0 deletions apps/admin/src/apis/controller/analytics/getConceptHistory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { $api } from '@apis';

const getConceptHistory = (studentId: number, options?: { enabled?: boolean }) => {
return $api.useQuery(
'get',
'/api/admin/analytics/concept-history/{studentId}',
{
params: {
path: { studentId },
},
},
options
);
};

export default getConceptHistory;
3 changes: 3 additions & 0 deletions apps/admin/src/apis/controller/analytics/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import getConceptHistory from './getConceptHistory';

export { getConceptHistory };
12 changes: 10 additions & 2 deletions apps/admin/src/apis/controller/conceptGraph/getNode.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { $api } from '@apis';

const getNode = () => {
return $api.useQuery('get', '/api/admin/concept/graph/node');
interface GetNodeParams {
onlyFocusCardCandidates?: boolean;
}

const getNode = (params: GetNodeParams = {}) => {
return $api.useQuery('get', '/api/admin/concept/graph/node', {
params: {
query: params,
},
});
};

export default getNode;
7 changes: 7 additions & 0 deletions apps/admin/src/apis/controller/focusCard/deleteFocusCard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const deleteFocusCard = () => {
return $api.useMutation('delete', '/api/admin/focus-card/{id}');
};

export default deleteFocusCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const deleteFocusCardIssuance = () => {
return $api.useMutation('delete', '/api/admin/focus-card/issuance/{id}');
};

export default deleteFocusCardIssuance;
11 changes: 11 additions & 0 deletions apps/admin/src/apis/controller/focusCard/getFocusCardById.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { $api } from '@apis';

const getFocusCardById = (id: number) => {
return $api.useQuery('get', '/api/admin/focus-card/{id}', {
params: {
path: { id },
},
});
};

export default getFocusCardById;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { $api } from '@apis';
import { GetFocusCardIssuanceByDateParams } from '@types';

const getFocusCardIssuanceByDate = (
{ studentId, issuedDate }: GetFocusCardIssuanceByDateParams,
options?: { enabled?: boolean }
) => {
return $api.useQuery(
'get',
'/api/admin/focus-card/issuance/by-date',
{
params: {
query: {
studentId,
...(issuedDate ? { issuedDate } : {}),
},
},
},
options
);
};

export default getFocusCardIssuanceByDate;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { $api } from '@apis';
import { GetFocusCardIssuanceCandidatesParams } from '@types';

const getFocusCardIssuanceCandidates = (
{ studentId, problemId, targetDate }: GetFocusCardIssuanceCandidatesParams,
options?: { enabled?: boolean }
) => {
return $api.useQuery(
'get',
'/api/admin/focus-card/issuance/candidates',
{
params: {
query: {
studentId,
problemId,
...(targetDate ? { targetDate } : {}),
},
},
},
options
);
};

export default getFocusCardIssuanceCandidates;
7 changes: 7 additions & 0 deletions apps/admin/src/apis/controller/focusCard/getFocusCardList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const getFocusCardList = () => {
return $api.useQuery('get', '/api/admin/focus-card');
};

export default getFocusCardList;
23 changes: 23 additions & 0 deletions apps/admin/src/apis/controller/focusCard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import deleteFocusCard from './deleteFocusCard';
import deleteFocusCardIssuance from './deleteFocusCardIssuance';
import getFocusCardById from './getFocusCardById';
import getFocusCardIssuanceByDate from './getFocusCardIssuanceByDate';
import getFocusCardIssuanceCandidates from './getFocusCardIssuanceCandidates';
import getFocusCardList from './getFocusCardList';
import postFocusCard from './postFocusCard';
import postFocusCardAutoIssue from './postFocusCardAutoIssue';
import postFocusCardContent from './postFocusCardContent';
import postFocusCardIssuance from './postFocusCardIssuance';

export {
deleteFocusCard,
deleteFocusCardIssuance,
getFocusCardById,
getFocusCardIssuanceByDate,
getFocusCardIssuanceCandidates,
getFocusCardList,
postFocusCard,
postFocusCardAutoIssue,
postFocusCardContent,
postFocusCardIssuance,
};
7 changes: 7 additions & 0 deletions apps/admin/src/apis/controller/focusCard/postFocusCard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const postFocusCard = () => {
return $api.useMutation('post', '/api/admin/focus-card');
};

export default postFocusCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const postFocusCardAutoIssue = () => {
return $api.useMutation('post', '/api/admin/focus-card/auto-issue');
};

export default postFocusCardAutoIssue;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const postFocusCardContent = () => {
return $api.useMutation('post', '/api/admin/focus-card/{id}/content');
};

export default postFocusCardContent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const postFocusCardIssuance = () => {
return $api.useMutation('post', '/api/admin/focus-card/issuance');
};

export default postFocusCardIssuance;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const deletePublishFocusCardLink = () => {
return $api.useMutation('delete', '/api/admin/publish-focus-card-links/{linkId}');
};

export default deletePublishFocusCardLink;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { $api } from '@apis';
import { PostPublishFocusCardLinkCandidatesParams } from '@types';

// HTTP 메서드는 POST지만 read-only 후보 조회 — body 파라미터 크기가 커서 BE가 POST 로 노출.
// 의미상 query 이므로 useQuery 사용 (enabled / 캐시 / staleness 정상 동작).
const getPublishFocusCardLinkCandidates = (
{ studentId, problemSetId, targetDate }: PostPublishFocusCardLinkCandidatesParams,
options?: { enabled?: boolean }
) => {
return $api.useQuery(
'post',
'/api/admin/publish/focus-card-link-candidates',
{
body: {
studentId,
problemSetId,
...(targetDate ? { targetDate } : {}),
},
},
options
);
};

export default getPublishFocusCardLinkCandidates;
13 changes: 12 additions & 1 deletion apps/admin/src/apis/controller/publish/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import deletePublish from './deletePublish';
import deletePublishFocusCardLink from './deletePublishFocusCardLink';
import getPublish from './getPublish';
import getPublishById from './getPublishById';
import getPublishFocusCardLinkCandidates from './getPublishFocusCardLinkCandidates';
import postPublish from './postPublish';
import postPublishFocusCardLink from './postPublishFocusCardLink';

export { deletePublish, getPublish, getPublishById, postPublish };
export {
deletePublish,
deletePublishFocusCardLink,
getPublish,
getPublishById,
getPublishFocusCardLinkCandidates,
postPublish,
postPublishFocusCardLink,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { $api } from '@apis';

const postPublishFocusCardLink = () => {
return $api.useMutation('post', '/api/admin/publishes/{publishId}/focus-card-links');
};

export default postPublishFocusCardLink;
2 changes: 2 additions & 0 deletions apps/admin/src/apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
export { $api } from './client';

// controllers
export * from './controller/analytics';
export * from './controller/auth';
export * from './controller/concept';
export * from './controller/conceptGraph';
export * from './controller/dailyComment';
export * from './controller/diagnosis';
export * from './controller/file';
export * from './controller/focusCard';
export * from './controller/menu';
export * from './controller/mockExam';
export * from './controller/notice';
Expand Down
35 changes: 17 additions & 18 deletions apps/admin/src/components/common/GNB.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useState, useEffect, useRef } from 'react';
import { Link } from '@tanstack/react-router';
import { Link, useLocation } from '@tanstack/react-router';
import { GraduationCap, Search, ChevronDown, ChevronRight, LogOut } from 'lucide-react';
import { getStudent } from '@apis';
import { useAdminSession, useSelectedStudent } from '@hooks';
import { components } from '@schema';

import { getAccessibleNavSections } from '@/constants/adminPermissions';
import { getAccessibleNavSections, getMostSpecificNavItem } from '@/constants/adminPermissions';
import { useSidebar } from '@/contexts/SidebarContext';
import { logout } from '@/utils';

Expand All @@ -14,27 +14,22 @@ interface NavItemProps {
icon: React.ReactNode;
label: string;
isCollapsed: boolean;
isActive: boolean;
}

const NavItem = ({ to, icon, label, isCollapsed }: NavItemProps) => {
const NavItem = ({ to, icon, label, isCollapsed, isActive }: NavItemProps) => {
return (
<Link
to={to}
activeProps={{
className: 'active',
}}>
{({ isActive }) => (
<Link to={to}>
<div
className={`relative mb-1 flex h-12 w-full cursor-pointer items-center gap-3.5 overflow-hidden rounded-2xl px-3.5 transition-all duration-300 ${
isActive ? 'bg-main/10 text-main' : 'text-gray-700 hover:bg-black/5'
} ${isCollapsed ? 'w-12 px-3.5' : ''}`}>
<div
className={`relative mb-1 flex h-12 w-full cursor-pointer items-center gap-3.5 overflow-hidden rounded-2xl px-3.5 transition-all duration-300 ${
isActive ? 'bg-main/10 text-main' : 'text-gray-700 hover:bg-black/5'
} ${isCollapsed ? 'w-12 px-3.5' : ''}`}>
<div
className={`flex h-5 w-5 flex-shrink-0 items-center justify-center transition-transform duration-300`}>
{icon}
</div>
<span className='text-sm font-semibold tracking-wide whitespace-nowrap'>{label}</span>
className={`flex h-5 w-5 flex-shrink-0 items-center justify-center transition-transform duration-300`}>
{icon}
</div>
)}
<span className='text-sm font-semibold tracking-wide whitespace-nowrap'>{label}</span>
</div>
</Link>
);
};
Expand Down Expand Up @@ -64,6 +59,8 @@ const GNB = () => {
const searchInputRef = useRef<HTMLInputElement>(null);
const session = useAdminSession();
const navSections = getAccessibleNavSections(session);
const { pathname } = useLocation();
const activeNavMenuName = getMostSpecificNavItem(pathname)?.menuName ?? null;
const studentManagementSection = navSections.find(
(section) => section.title === '개별 학생 관리'
);
Expand Down Expand Up @@ -221,6 +218,7 @@ const GNB = () => {
icon={<Icon className='h-5 w-5' />}
label={item.label}
isCollapsed={isCollapsed}
isActive={activeNavMenuName === item.menuName}
/>
);
})}
Expand All @@ -242,6 +240,7 @@ const GNB = () => {
icon={<Icon className='h-5 w-5' />}
label={item.label}
isCollapsed={isCollapsed}
isActive={activeNavMenuName === item.menuName}
/>
);
})}
Expand Down
Loading
Loading