Skip to content

Commit

Permalink
feat: change admin dashboard's access (#2463)
Browse files Browse the repository at this point in the history
  • Loading branch information
valerydluski committed Apr 17, 2024
1 parent 32f1e2e commit b24a74a
Show file tree
Hide file tree
Showing 30 changed files with 58 additions and 58 deletions.
6 changes: 0 additions & 6 deletions client/src/components/Sider/data/menuItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,6 @@ export function getAdminMenuItems(session: Session): MenuItemsRenderData[] {
}

const courseManagementMenuItems: CourseManagementMenuItemsData[] = [
{
name: 'Dashboard',
key: 'courseDashboard',
getUrl: (course: Course) => `/course/admin/dashboard?course=${course.alias}`,
courseAccess: some(isCourseManager, isCourseSupervisor, isDementor),
},
{
name: 'Course Events',
key: 'courseEvents',
Expand Down
1 change: 0 additions & 1 deletion client/src/modules/AdminDashboard/index.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Bar, BarConfig } from '@ant-design/plots';
import { Flex, Image, Typography } from 'antd';
import { CountryStatDto } from 'api';
import { useCallback, useMemo } from 'react';
import { Colors } from '../data';
import { Colors } from '../../data';

type Props = {
data: CountryStatDto[];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Card, Typography } from 'antd';
import { CourseMentorsStatsDto } from 'api';
import dynamic from 'next/dynamic';
import { Colors } from '../data';
import { Colors } from '../../data';

type Props = {
mentorsStats: CourseMentorsStatsDto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Liquid, LiquidConfig } from '@ant-design/plots';
import { Colors } from '../data';
import { Colors } from '../../data';

type Props = {
count: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { Card } from 'antd';
import { CountriesStatsDto } from 'api';
import dynamic from 'next/dynamic';
import { Colors } from '../data';
import { Colors } from '../../data';

type Props = {
countriesStats: CountriesStatsDto;
activeCount: number;
};

const CountriesChart = dynamic(() => import('../CountriesChart/CountriesChart'), { ssr: false });
const CountriesChart = dynamic(() => import('../CountriesChart/CountriesChart'), {
ssr: false,
});

export const MentorsCountriesCard = ({ countriesStats, activeCount }: Props) => {
const { countries } = countriesStats;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ type Props = {
activeStudentsCount: number;
};

const CountriesChart = dynamic(() => import('../CountriesChart/CountriesChart'), { ssr: false });
const CountriesChart = dynamic(() => import('../CountriesChart/CountriesChart'), {
ssr: false,
});

export const StudentsCountriesCard = ({ studentsCountriesStats, activeStudentsCount }: Props) => {
const { countries } = studentsCountriesStats;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Card, Typography } from 'antd';
import { CourseStatsDto } from 'api';
import dynamic from 'next/dynamic';
import { Colors } from '../data';
import { Colors } from '../../data';

type Props = {
studentsStats: CourseStatsDto;
};

const { Text } = Typography;

const LiquidChart = dynamic(() => import('../LiquidChart/LiquidChart'), { ssr: false });
const LiquidChart = dynamic(() => import('../LiquidChart/LiquidChart'), {
ssr: false,
});

export const StudentsEligibleForCertificationCard = ({ studentsStats }: Props) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ type Props = {

const { Text } = Typography;

const StudentsStatsChart = dynamic(() => import('../LiquidChart/LiquidChart'), { ssr: false });
const StudentsStatsChart = dynamic(() => import('../LiquidChart/LiquidChart'), {
ssr: false,
});

export const StudentsStatsCard = ({ studentsStats }: Props) => {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Card, Typography } from 'antd';
import { CourseStatsDto } from 'api';
import dynamic from 'next/dynamic';
import { Colors } from '../data';
import { Colors } from '../../data';

type Props = {
studentsStats: CourseStatsDto;
};

const { Text } = Typography;

const LiquidChart = dynamic(() => import('../LiquidChart/LiquidChart'), { ssr: false });
const LiquidChart = dynamic(() => import('../LiquidChart/LiquidChart'), {
ssr: false,
});

export const StudentsWithCertificateCard = ({ studentsStats }: Props) => {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Card, Typography } from 'antd';
import { CourseStatsDto } from 'api';
import dynamic from 'next/dynamic';
import { Colors } from '../data';
import { Colors } from '../../data';

type Props = {
studentsStats: CourseStatsDto;
};

const { Text } = Typography;

const LiquidChart = dynamic(() => import('../LiquidChart/LiquidChart'), { ssr: false });
const LiquidChart = dynamic(() => import('../LiquidChart/LiquidChart'), {
ssr: false,
});

export const StudentsWithMentorsCard = ({ studentsStats }: Props) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useActiveCourseContext } from 'modules/Course/contexts';
import dynamic from 'next/dynamic';
import { useState } from 'react';
import { useAsync } from 'react-use';
import { Colors } from '../data';
import { Colors } from '../../data';

const courseStatsApi = new CourseStatsApi();

Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions client/src/modules/CourseStatistics/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as CourseStatistics } from './pages/CourseStatistics';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AdminPageLayout } from 'components/PageLayout';
import { PageLayout } from 'components/PageLayout';
import { useActiveCourseContext } from 'modules/Course/contexts';
import Masonry from 'react-masonry-css';
import { StudentsCountriesCard } from '../components/StudentsCountriesCard';
Expand All @@ -14,8 +14,8 @@ import { TaskPerformanceCard } from '../components/TaskPerformanceCard';

const gapSize = 24;

function AdminDashboard() {
const { course, courses } = useActiveCourseContext();
function CourseStatistic() {
const { course } = useActiveCourseContext();
const { loading, value: stats } = useCourseStats(course.id);

const masonryBreakPoints = {
Expand Down Expand Up @@ -73,13 +73,7 @@ function AdminDashboard() {
].filter(Boolean);

return (
<AdminPageLayout
courses={courses}
styles={{ background: '#e5e5e5' }}
loading={loading}
title="Dashboard"
showCourseName
>
<PageLayout loading={loading} title="Course Statistics" showCourseName background="#F0F2F5">
<Masonry
breakpointCols={masonryBreakPoints}
className={masonryClassName}
Expand All @@ -93,7 +87,7 @@ function AdminDashboard() {
</Masonry>
{masonryStyles}
{masonryColumnStyles}
</AdminPageLayout>
</PageLayout>
);
}

Expand All @@ -112,4 +106,4 @@ const { className: masonryColumnClassName, styles: masonryColumnStyles } = css.r
}
`;

export default AdminDashboard;
export default CourseStatistic;
6 changes: 6 additions & 0 deletions client/src/modules/Home/data/links.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ const links: LinkData[] = [
access: some(isCourseManager, isActiveStudent, isDementor),
courseAccess: everyCourse(isCourseNotCompleted),
},
{
name: 'Course Statistics',
icon: <AppstoreOutlined />,
getUrl: (course: Course) => `/course/stats?course=${course.alias}`,
access: anyAccess,
},
];

export function getCourseLinks(session: Session, activeCourse: Course | null): LinkRenderData[] {
Expand Down
15 changes: 0 additions & 15 deletions client/src/pages/course/admin/dashboard.tsx

This file was deleted.

14 changes: 14 additions & 0 deletions client/src/pages/course/stats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { CourseStatistics } from 'modules/CourseStatistics';
import { ActiveCourseProvider, SessionProvider } from 'modules/Course/contexts';

function Page() {
return (
<ActiveCourseProvider>
<SessionProvider>
<CourseStatistics />
</SessionProvider>
</ActiveCourseProvider>
);
}

export default Page;
15 changes: 5 additions & 10 deletions nestjs/src/courses/stats/course-stats.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import {
} from '@nestjs/common';
import { CacheInterceptor, CacheTTL } from '@nestjs/cache-manager';
import { ApiBadRequestResponse, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { CurrentRequest, DefaultGuard, RequiredRoles, Role, RoleGuard } from '../../auth';
import { CourseGuard, CurrentRequest, DefaultGuard } from '../../auth';
import { ONE_HOUR_CACHE_TTL } from '../../constants';
import { CourseAccessService } from '../course-access.service';
import { CourseStatsService } from './course-stats.service';
import { CourseStatsDto, CountriesStatsDto, CourseMentorsStatsDto, TaskPerformanceStatsDto } from './dto';
import { CourseRole } from '@entities/index';

@Controller('courses/:courseId/stats')
@ApiTags('course stats')
Expand All @@ -42,11 +41,10 @@ export class CourseStatsController {
@Get('/mentors')
@CacheTTL(ONE_HOUR_CACHE_TTL)
@UseInterceptors(CacheInterceptor)
@UseGuards(RoleGuard)
@UseGuards(DefaultGuard, CourseGuard)
@ApiOperation({ operationId: 'getCourseMentors' })
@ApiOkResponse({ type: CourseMentorsStatsDto })
@ApiBadRequestResponse()
@RequiredRoles([CourseRole.Manager, CourseRole.Supervisor, Role.Admin, CourseRole.Dementor], true)
public async getMentors(@Param('courseId', ParseIntPipe) courseId: number) {
const data = await this.courseStatsService.getMentors(courseId);
return new CourseMentorsStatsDto(data);
Expand All @@ -55,11 +53,10 @@ export class CourseStatsController {
@Get('/mentors/countries')
@CacheTTL(ONE_HOUR_CACHE_TTL)
@UseInterceptors(CacheInterceptor)
@UseGuards(RoleGuard)
@UseGuards(DefaultGuard, CourseGuard)
@ApiOperation({ operationId: 'getCourseMentorCountries' })
@ApiOkResponse({ type: CountriesStatsDto })
@ApiBadRequestResponse()
@RequiredRoles([CourseRole.Manager, CourseRole.Supervisor, Role.Admin, CourseRole.Dementor], true)
public async getMentorCountries(@Param('courseId', ParseIntPipe) courseId: number): Promise<CountriesStatsDto> {
const data = await this.courseStatsService.getMentorCountries(courseId);
return data;
Expand All @@ -68,11 +65,10 @@ export class CourseStatsController {
@Get('/students/countries')
@CacheTTL(ONE_HOUR_CACHE_TTL)
@UseInterceptors(CacheInterceptor)
@UseGuards(RoleGuard)
@UseGuards(DefaultGuard, CourseGuard)
@ApiOperation({ operationId: 'getCourseStudentCountries' })
@ApiOkResponse({ type: CountriesStatsDto })
@ApiBadRequestResponse()
@RequiredRoles([CourseRole.Manager, CourseRole.Supervisor, Role.Admin, CourseRole.Dementor], true)
public async getStudentCountries(@Param('courseId', ParseIntPipe) courseId: number): Promise<CountriesStatsDto> {
const data = await this.courseStatsService.getStudentCountries(courseId);
return data;
Expand All @@ -81,11 +77,10 @@ export class CourseStatsController {
@Get('/task/:taskId/performance')
@CacheTTL(ONE_HOUR_CACHE_TTL)
@UseInterceptors(CacheInterceptor)
@UseGuards(RoleGuard)
@UseGuards(DefaultGuard, CourseGuard)
@ApiOperation({ operationId: 'getTaskPerformance' })
@ApiOkResponse({ type: TaskPerformanceStatsDto })
@ApiBadRequestResponse()
@RequiredRoles([CourseRole.Manager, CourseRole.Supervisor, Role.Admin, CourseRole.Dementor], true)
public async getTaskPerformance(
@Param('courseId', ParseIntPipe) _courseId: number,
@Param('taskId', ParseIntPipe) taskId: number,
Expand Down

0 comments on commit b24a74a

Please sign in to comment.