feat: La liste des membres qui ont proposé le plus de modèles

This commit is contained in:
Nemo D'ACREMONT 2024-12-02 14:57:16 +01:00
parent e4cb8c3300
commit 4567285ec4
No known key found for this signature in database
GPG Key ID: 6E5BCE8022FA8276
10 changed files with 104 additions and 12 deletions

View File

@ -6,10 +6,10 @@ all: build
build: dev
dev: $(DIR_BACK)/.env
. $(DIR_BACK)/.env && docker-compose -f docker-compose.dev.yml up
. $(DIR_BACK)/.env && docker compose -f docker-compose.dev.yml up
prod:
. $(DIR_BACK)/.env && docker-compose -f docker-compose.prod.yml up
. $(DIR_BACK)/.env && docker compose -f docker-compose.prod.yml up
$(DIR_BACK)/.env: $(DIR_BACK)/.env.example
cp $(DIR_BACK)/.env.example $(DIR_BACK)/.env
@ -17,11 +17,12 @@ $(DIR_BACK)/.env: $(DIR_BACK)/.env.example
clean:
${RM} $(DIR_BACK)/.env
${RM} -r dev-db || true
# Delete the db volume
sudo ${RM} -r dev-db || true
cd $(DIR_SQL) && make clean
docker compose -f docker-compose.dev.yml down --rmi local -v --remove-orphans || true
docker compose -f docker compose.dev.yml down --rmi local -v --remove-orphans || true
clean_prod: clean
docker compose -f docker-compose.prod.yml down --rmi local -v --remove-orphans || true
docker compose -f docker compose.prod.yml down --rmi local -v --remove-orphans || true
.PHONY: clean all prepare_dev build clean_prod

View File

@ -367,3 +367,20 @@ ALTER TABLE varier
-- ============================================================================
-- Nombre de piece par boite
CREATE OR REPLACE VIEW nb_piece_par_boite AS
(
SELECT id_boite, SUM(quantite_contenir) as nb_piece
FROM contenir
GROUP BY id_boite
);
-- nombre de modele proposés par membre
CREATE OR REPLACE VIEW nb_modele_par_membre AS
(
SELECT membres.*, COUNT(*) as nb_modele
FROM modeles
JOIN membres ON membres.id_membre = modeles.id_membre
WHERE membres.id_membre IS NOT NULL
GROUP BY membres.id_membre
);

View File

@ -59,12 +59,11 @@ CREATE OR REPLACE VIEW nb_modele_par_membre AS
-- La liste des membres qui ont proposé le plus de modèles.
SELECT id_membre, nb_modele
FROM nb_modele_par_membre
ORDER BY nb_boite
ORDER BY nb_modele
DESC
LIMIT 5
;
-- La liste des modèles, classés par note moyenne descendante.
SELECT id_modele, AVG(note_noter) as note_moyenne
FROM noter
GROUP BY id_modele

View File

@ -19,6 +19,11 @@ const allMembers: RequestHandler = async (_req, res) => {
res.render('members.ejs', { members });
};
const allMembersByNbModels: RequestHandler = async (_req, res) => {
const members = await memberService.getAllMembersByNbModels();
res.render('membersAndNbModels.ejs', { members });
};
const memberById: RequestHandler<{ id: string; }> = async (req, res) => {
const id = parseInt(req.params.id);
const memberEither = await memberService.getMember(id);
@ -37,6 +42,7 @@ const memberController = {
memberByName,
memberById,
allMembers,
allMembersByNbModels
};
export default memberController;

View File

@ -5,7 +5,9 @@ const router = express.Router();
router.get("/", memberController.allMembers);
router.get("/:name", memberController.memberByName);
router.get("/bynbmodels", memberController.allMembersByNbModels);
router.get("/byname/:name", memberController.memberByName);
router.get("/byid/:id", memberController.memberById);

View File

@ -1,5 +1,5 @@
import { new_client } from '../db/db_client';
import { Member, User } from '../types/member';
import { Member, MemberAndNbModels, User } from '../types/member';
import { Either, eitherLeft, eitherRight } from '../utils/utils';
type DBMembre = {
@ -8,7 +8,14 @@ type DBMembre = {
mdp_membre: string;
};
function db2member(data: DBMembre) {
type DBMembreAndNbModels = {
id_membre: number;
nom_membre: string;
mdp_membre: string;
nb_modele: number;
};
function db2member(data: DBMembre): Member {
const member: Member = {
id_member: data.id_membre,
name: data.nom_membre,
@ -17,6 +24,17 @@ function db2member(data: DBMembre) {
return member;
}
function db2memberAndNbModels(data: DBMembreAndNbModels): MemberAndNbModels {
const memberAndNbModels: MemberAndNbModels = {
id_member: data.id_membre,
name: data.nom_membre,
password: data.mdp_membre,
nb_models: data.nb_modele,
};
return memberAndNbModels;
}
const getMember = async (idOrName: number | string): Promise<Either<Member, string>> => {
const client = new_client();
await client.connect();
@ -44,6 +62,14 @@ const getAllMembers = async () => {
return res.rows.map(db2member);
}
const getAllMembersByNbModels = async () => {
const client = new_client();
await client.connect();
const res = await client.query("SELECT * FROM nb_modele_par_membre ORDER BY nb_modele DESC LIMIT 5;");
await client.end();
return res.rows.map(db2memberAndNbModels);
}
const createMember = async (name: string, passwd: string): Promise<Either<Member, string>> => {
const gettingMember = await getMember(name);
if (!gettingMember.hasRight) {
@ -75,6 +101,7 @@ const memberService = {
getDefaultMember,
userAdapter,
getAllMembers,
getAllMembersByNbModels,
};
export default memberService;

View File

@ -19,7 +19,7 @@
<ul>
<% members.forEach(function(member) { %>
<li>
<a href="/membres/<%=member.name%>">
<a href="/membres/byname/<%=member.name%>">
<%=member.name%>
</a>
</li>

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Liste des membres qui ont proposés le plus de modèles
</title>
<%- include('partials/links.ejs') %>
</head>
<body>
<%- include('partials/header.ejs') %>
<h1>
Liste des membres qui ont proposés le plus de modèles
</h1>
<ul>
<% members.forEach(function(member) { %>
<li>
<span>
<%= member.nb_models %>
</span>
<a href="/membres/byname/<%=member.name%>">
<%= member.name %>
</a>
</li>
<% }); %>
</ul>
</body>
</html>

View File

@ -19,6 +19,10 @@
<a href="javascript:let now = new Date();now.setUTCFullYear(now.getUTCFullYear() - 5);window.location.pathname = '/boxes/from/' + `${now.getUTCFullYear()}-${now.getUTCMonth() + 1}-${now.getUTCDate()}`;">
<p>Liste des boites ayant moins de 5 ans</p>
</a>
<a href="/membres/bynbmodels">
<p>Liste des membres qui ont proposés le plus de modèles</p>
</a>
</body>
</html>

View File

@ -4,5 +4,6 @@ type User = {
}
type Member = User & { password: string };
type MemberAndNbModels = User & { password: string } & { nb_models: number };
export { Member, User };
export { Member, User, MemberAndNbModels };