Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature presentation pelico vil 320 #936

Merged
merged 6 commits into from
Jun 5, 2024
Merged
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
2 changes: 2 additions & 0 deletions server/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import featureFlagController from './featureFlag';
import { gameController } from './game';
import { imageController } from './image';
import { languageController } from './languages';
import { pelicoController } from './pelicoPresentation';
import { storyController } from './story';
import { studentController } from './student';
import { teacherController } from './teacher';
Expand Down Expand Up @@ -41,6 +42,7 @@ const controllers = [
teacherController,
studentController,
featureFlagController,
pelicoController,
];

for (let i = 0, n = controllers.length; i < n; i++) {
Expand Down
114 changes: 114 additions & 0 deletions server/controllers/pelicoPresentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import type { JSONSchemaType } from 'ajv';
import type { NextFunction, Request, Response } from 'express';

import type { ActivityContent } from '../../types/activity.type';
import { PelicoPresentation } from '../entities/pelicoPresentation';
import { UserType } from '../entities/user';
import { AppDataSource } from '../utils/data-source';
import { ajv, sendInvalidDataError } from '../utils/jsonSchemaValidator';
import { Controller } from './controller';

const pelicoController = new Controller('/pelico-presentation'); // Défini le préfixe de route

// --- Récupérer toutes les présentations Pelico ---
pelicoController.get({ path: '', userType: UserType.OBSERVATOR }, async (_req: Request, res: Response) => {
const presentations = await AppDataSource.getRepository(PelicoPresentation).find();
res.sendJSON(presentations);
});

// --- Récupérer une présentation Pelico ---
pelicoController.get({ path: '/:id', userType: UserType.OBSERVATOR }, async (req: Request, res: Response) => {
const id = parseInt(req.params.id, 10) || 1;
const presentation = await AppDataSource.getRepository(PelicoPresentation).findOne({ where: { id } });
res.sendJSON(presentation);
});

// --- Créer une présentation Pelico ---
type CreatePelicoData = {
content: ActivityContent[];
};
const CREATE_SCHEMA: JSONSchemaType<CreatePelicoData> = {
type: 'object',
properties: {
content: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'number', nullable: false },
type: { type: 'string', nullable: false, enum: ['text', 'video', 'image', 'h5p', 'sound', 'document'] },
value: { type: 'string', nullable: false },
},
required: ['type', 'value'],
},
nullable: false,
},
},
required: ['content'],
additionalProperties: false,
};
const createValidator = ajv.compile(CREATE_SCHEMA);
pelicoController.post({ path: '', userType: UserType.ADMIN }, async (req: Request, res: Response) => {
const data = req.body;
if (!createValidator(data)) {
sendInvalidDataError(createValidator);
return;
}
const presentation = new PelicoPresentation();
presentation.content = data.content;
await AppDataSource.getRepository(PelicoPresentation).save(presentation);
res.sendJSON(presentation);
});

// --- Mettre à jour une présentation Pelico ---
type UpdatePelicoData = {
content?: ActivityContent[];
};
const UPDATE_SCHEMA: JSONSchemaType<UpdatePelicoData> = {
type: 'object',
properties: {
content: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'number', nullable: false },
type: { type: 'string', nullable: false, enum: ['text', 'video', 'image', 'h5p', 'sound', 'document'] },
value: { type: 'string', nullable: false },
},
required: ['type', 'value'],
},
nullable: true,
},
},
required: [],
additionalProperties: false,
};
const updateValidator = ajv.compile(UPDATE_SCHEMA);
pelicoController.put({ path: '/:id', userType: UserType.ADMIN }, async (req: Request, res: Response, next: NextFunction) => {
const data = req.body;
if (!updateValidator(data)) {
sendInvalidDataError(updateValidator);
return;
}
const id = parseInt(req.params.id, 10) || 0;
const presentation = await AppDataSource.getRepository(PelicoPresentation).findOne({ where: { id } });
if (!presentation) {
next();
return;
}

presentation.content = data.content || presentation.content;

await AppDataSource.getRepository(PelicoPresentation).save(presentation);
res.sendJSON(presentation);
});

// --- Supprimer une présentation Pelico ---
pelicoController.delete({ path: '/:id', userType: UserType.ADMIN }, async (req: Request, res: Response) => {
const id = parseInt(req.params.id, 10) || 0;
await AppDataSource.getRepository(PelicoPresentation).delete({ id });
res.status(204).send();
});

export { pelicoController };
12 changes: 12 additions & 0 deletions server/entities/pelicoPresentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

import type { ActivityContent } from '../../types/activity.type';

@Entity()
export class PelicoPresentation {
@PrimaryGeneratedColumn()
id: number;

@Column('json')
content: ActivityContent[];
}
29 changes: 29 additions & 0 deletions server/migrations/1715874475677-CreateTablePelicoPresentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { MigrationInterface, QueryRunner } from 'typeorm';
import { Table } from 'typeorm';

export class CreateTablePelicoPresentation1715874475677 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.createTable(
new Table({
name: 'pelico_presentation',
columns: [
{
name: 'id',
type: 'int',
isPrimary: true,
isGenerated: true,
generationStrategy: 'increment',
},
{
name: 'content',
type: 'json',
},
],
}),
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropTable('pelico_presentation');
}
}
20 changes: 20 additions & 0 deletions src/api/pelicoPresentation/pelicoPresentation.delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import axios from 'axios';
import { useMutation, useQueryClient } from 'react-query';

const BASE_URL = '/api/pelico-presentation';

// Supprimer une présentation Pelico
export const useDeletePelicoPresentation = () => {
const queryClient = useQueryClient();

return useMutation(
async (id: number) => {
await axios.delete(`${BASE_URL}/${id}`);
},
{
onSuccess: () => {
queryClient.invalidateQueries('pelicoPresentation');
},
},
);
};
38 changes: 38 additions & 0 deletions src/api/pelicoPresentation/pelicoPresentation.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import axios from 'axios';
import { useQuery } from 'react-query';

const BASE_URL = '/api/pelico-presentation';

// Récupérer une présentation Pelico spécifique
export const usePelicoPresentation = (id: number) => {
return useQuery(['pelicoPresentation', id], async () => {
const { data } = await axios.get(`${BASE_URL}/${id}`);
return data;
});
};

// Récupérer toutes les présentations Pelico
export const usePelicoPresentatations = () => {
return useQuery('pelicoPresentatation', async () => {
const { data } = await axios.get(BASE_URL);
return data;
});
};

// async function getPelicoPresentation(id: number) {
// const { data } = await axios.get(`${BASE_URL}/${id}`);
// return data;
// }

// export const useGetPelicoPresentation = (id: number) => {
// return useQuery(['pelico-presentation'], getPelicoPresentation(id));
// };

// async function getPelicoPresentations() {
// const { data } = await axios.get(`${BASE_URL}`);
// return data;
// }

// export const useGetPelicoPresentations = () => {
// return useQuery(['pelico-presentation'], getPelicoPresentations);
// };
23 changes: 23 additions & 0 deletions src/api/pelicoPresentation/pelicoPresentation.post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import axios from 'axios';
import { useMutation, useQueryClient } from 'react-query';

import type { PelicoPresentationContent } from 'types/pelicoPresentation.type';

const BASE_URL = '/api/pelico-presentation';

// Créer une nouvelle présentation Pelico
export const useCreatePelicoPresentation = () => {
const queryClient = useQueryClient();

return useMutation(
async (content: PelicoPresentationContent[]) => {
const { data } = await axios.post(BASE_URL, { content });
return data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('pelicoPresentation');
},
},
);
};
23 changes: 23 additions & 0 deletions src/api/pelicoPresentation/pelicoPresentation.put.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import axios from 'axios';
import { useMutation, useQueryClient } from 'react-query';

import type { PelicoPresentation } from 'types/pelicoPresentation.type';

const BASE_URL = '/api/pelico-presentation';

// Mettre à jour une présentation Pelico
export const useUpdatePelicoPresentation = () => {
const queryClient = useQueryClient();

return useMutation(
async ({ id, content }: PelicoPresentation) => {
const { data } = await axios.put(`${BASE_URL}/${id}`, { content });
return data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('pelicoPresentation');
},
},
);
};
Loading
Loading