-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #992 from parlemonde/VIL-83
Vil 83
- Loading branch information
Showing
29 changed files
with
777 additions
and
518 deletions.
There are no files selected for viewing
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
version: '3.7' | ||
services: | ||
backend: | ||
build: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,55 @@ | ||
import type { Request } from 'express'; | ||
|
||
import { | ||
getClassroomsInfos, | ||
getConnectedClassroomsCount, | ||
getContributedClassroomsCount, | ||
getRegisteredClassroomsCount, | ||
} from '../stats/classroomStats'; | ||
import { | ||
getAverageConnections, | ||
getAverageDuration, | ||
getMaxConnections, | ||
getMaxDuration, | ||
getMedianConnections, | ||
getMedianDuration, | ||
getMinConnections, | ||
getMinDuration, | ||
} from '../stats/sessionStats'; | ||
import { Controller } from './controller'; | ||
|
||
export const statisticsController = new Controller('/statistics'); | ||
|
||
statisticsController.get({ path: '/sessions/:phase' }, async (req: Request, res) => { | ||
const phase = req.params.phase ? parseInt(req.params.phase) : null; | ||
|
||
res.sendJSON({ | ||
minDuration: await getMinDuration(), // TODO - add phase | ||
maxDuration: await getMaxDuration(), // TODO - add phase | ||
averageDuration: await getAverageDuration(), // TODO - add phase | ||
medianDuration: await getMedianDuration(), // TODO - add phase | ||
minConnections: await getMinConnections(), // TODO - add phase | ||
maxConnections: await getMaxConnections(), // TODO - add phase | ||
averageConnections: await getAverageConnections(), // TODO - add phase | ||
medianConnections: await getMedianConnections(), // TODO - add phase | ||
registeredClassroomsCount: await getRegisteredClassroomsCount(), | ||
connectedClassroomsCount: await getConnectedClassroomsCount(), // TODO - add phase | ||
contributedClassroomsCount: await getContributedClassroomsCount(phase), | ||
}); | ||
}); | ||
|
||
statisticsController.get({ path: '/classrooms' }, async (_req, res) => { | ||
res.sendJSON({ | ||
classrooms: await getClassroomsInfos(), | ||
}); | ||
}); | ||
import type { Request } from 'express'; | ||
|
||
import { | ||
getClassroomsInfos, | ||
getConnectedClassroomsCount, | ||
getContributedClassroomsCount, | ||
getRegisteredClassroomsCount, | ||
} from '../stats/classroomStats'; | ||
import { | ||
getAverageConnections, | ||
getAverageDuration, | ||
getMaxConnections, | ||
getMaxDuration, | ||
getMedianConnections, | ||
getMedianDuration, | ||
getMinConnections, | ||
getMinDuration, | ||
} from '../stats/sessionStats'; | ||
import { getChildrenCodesCount, getFamilyAccountsCount, getConnectedFamiliesCount } from '../stats/villageStats'; | ||
import { Controller } from './controller'; | ||
|
||
export const statisticsController = new Controller('/statistics'); | ||
|
||
statisticsController.get({ path: '/sessions/:phase' }, async (req: Request, res) => { | ||
const phase = req.params.phase ? parseInt(req.params.phase) : null; | ||
|
||
res.sendJSON({ | ||
minDuration: await getMinDuration(), // TODO - add phase | ||
maxDuration: await getMaxDuration(), // TODO - add phase | ||
averageDuration: await getAverageDuration(), // TODO - add phase | ||
medianDuration: await getMedianDuration(), // TODO - add phase | ||
minConnections: await getMinConnections(), // TODO - add phase | ||
maxConnections: await getMaxConnections(), // TODO - add phase | ||
averageConnections: await getAverageConnections(), // TODO - add phase | ||
medianConnections: await getMedianConnections(), // TODO - add phase | ||
registeredClassroomsCount: await getRegisteredClassroomsCount(), | ||
connectedClassroomsCount: await getConnectedClassroomsCount(), // TODO - add phase | ||
contributedClassroomsCount: await getContributedClassroomsCount(phase), | ||
}); | ||
}); | ||
|
||
statisticsController.get({ path: '/classrooms' }, async (_req, res) => { | ||
res.sendJSON({ | ||
classrooms: await getClassroomsInfos(), | ||
}); | ||
}); | ||
|
||
statisticsController.get({ path: '/villages/:villageId' }, async (_req, res) => { | ||
const villageId = parseInt(_req.params.villageId); | ||
res.sendJSON({ | ||
familyAccountsCount: await getFamilyAccountsCount(villageId), | ||
childrenCodesCount: await getChildrenCodesCount(villageId), | ||
connectedFamiliesCount: await getConnectedFamiliesCount(villageId), | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { Student } from '../entities/student'; | ||
import { User } from '../entities/user'; | ||
import { AppDataSource } from '../utils/data-source'; | ||
|
||
const userRepository = AppDataSource.getRepository(User); | ||
const studentRepository = AppDataSource.getRepository(Student); | ||
|
||
export const getChildrenCodesCount = async (villageId: number) => { | ||
const childrenCodeCount = await studentRepository | ||
.createQueryBuilder('student') | ||
.innerJoin('student.classroom', 'classroom') | ||
.innerJoin('classroom.village', 'village') | ||
.where('classroom.villageId = :villageId', { villageId }) | ||
.getCount(); | ||
return childrenCodeCount; | ||
}; | ||
|
||
export const getFamilyAccountsCount = async (villageId: number) => { | ||
const familyAccountsCount = await userRepository | ||
.createQueryBuilder('user') | ||
.innerJoin('user.village', 'village') | ||
.innerJoin('classroom', 'classroom', 'classroom.villageId = village.id') | ||
.innerJoin('student', 'student', 'student.classroomId = classroom.id') | ||
.where('classroom.villageId = :villageId', { villageId }) | ||
.groupBy('user.id') | ||
.getCount(); | ||
return familyAccountsCount; | ||
}; | ||
|
||
export const getConnectedFamiliesCount = async (villageId: number) => { | ||
const connectedFamiliesCount = await studentRepository | ||
.createQueryBuilder('student') | ||
.innerJoin('classroom', 'classroom', 'classroom.id = student.classroomId') | ||
.where('classroom.villageId = :villageId', { villageId }) | ||
.andWhere('student.numLinkedAccount >= 1') | ||
.getCount(); | ||
|
||
return connectedFamiliesCount; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,48 @@ | ||
import { useQuery } from 'react-query'; | ||
|
||
import { axiosRequest } from 'src/utils/axiosRequest'; | ||
import type { ClassroomsStats, SessionsStats } from 'types/statistics.type'; | ||
|
||
async function getSessionsStats(phase: number | null): Promise<SessionsStats> { | ||
return ( | ||
await axiosRequest({ | ||
method: 'GET', | ||
baseURL: '/api', | ||
url: `/statistics/sessions/${phase}`, | ||
}) | ||
).data; | ||
} | ||
|
||
export const useGetSessionsStats = (phase: number | null) => { | ||
return useQuery(['sessions-stats'], () => getSessionsStats(phase)); | ||
}; | ||
|
||
async function getClassroomsStats(): Promise<ClassroomsStats[]> { | ||
return ( | ||
await axiosRequest({ | ||
method: 'GET', | ||
baseURL: '/api', | ||
url: '/statistics/classrooms', | ||
}) | ||
).data; | ||
} | ||
|
||
export const useGetClassroomsStats = () => { | ||
return useQuery(['classrooms-stats'], () => getClassroomsStats()); | ||
}; | ||
import { useQuery } from 'react-query'; | ||
|
||
import { axiosRequest } from 'src/utils/axiosRequest'; | ||
import type { ClassroomsStats, SessionsStats, VillageStats } from 'types/statistics.type'; | ||
|
||
async function getSessionsStats(phase: number | null): Promise<SessionsStats> { | ||
return ( | ||
await axiosRequest({ | ||
method: 'GET', | ||
baseURL: '/api', | ||
url: `/statistics/sessions/${phase}`, | ||
}) | ||
).data; | ||
} | ||
|
||
async function getVillagesStats(villageId: number | null): Promise<VillageStats> { | ||
return ( | ||
await axiosRequest({ | ||
method: 'GET', | ||
baseURL: '/api', | ||
url: `/statistics/villages/${villageId}`, | ||
}) | ||
).data; | ||
} | ||
|
||
export const useGetSessionsStats = (phase: number | null) => { | ||
return useQuery(['sessions-stats'], () => getSessionsStats(phase)); | ||
}; | ||
|
||
export const useGetVillagesStats = (villageId: number | null) => { | ||
return useQuery(['villages-stats', villageId], () => getVillagesStats(villageId), { | ||
enabled: villageId !== null, | ||
}); | ||
}; | ||
|
||
async function getClassroomsStats(): Promise<ClassroomsStats[]> { | ||
return ( | ||
await axiosRequest({ | ||
method: 'GET', | ||
baseURL: '/api', | ||
url: '/statistics/classrooms', | ||
}) | ||
).data; | ||
} | ||
|
||
export const useGetClassroomsStats = () => { | ||
return useQuery(['classrooms-stats'], () => getClassroomsStats()); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.