feat: La liste des membres qui ont proposé le plus de modèles
This commit is contained in:
parent
e4cb8c3300
commit
4567285ec4
11
Makefile
11
Makefile
@ -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
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
35
back-end/src/templates/membersAndNbModels.ejs
Normal file
35
back-end/src/templates/membersAndNbModels.ejs
Normal 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>
|
@ -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>
|
||||
|
@ -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 };
|
||||
|
Loading…
x
Reference in New Issue
Block a user