Compare commits
32 commits
main
...
front-admi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d797abe90a | ||
|
|
7b7f934245 | ||
|
|
d8063a02dd | ||
|
|
ab54fdb490 | ||
|
|
925dc1c178 | ||
|
|
8c1d9cd4c7 | ||
|
|
b883bd5156 | ||
|
|
520214977e | ||
|
|
0a891e500e | ||
|
|
c55af87a23 | ||
|
|
b9c3e7d0f3 | ||
|
|
958b4898f0 | ||
|
|
03d2a28544 | ||
|
|
f1d55dfc6b | ||
|
|
65cb3ee020 | ||
|
|
0bb795cc11 | ||
| bf6f102307 | |||
| 1c729b9c8d | |||
| f00762b5fe | |||
|
|
71e34ac8c0 | ||
|
|
5024b297ec | ||
|
|
d29741f9a8 | ||
|
|
0d6cca625c | ||
|
|
b7df19e1c0 | ||
|
|
f80fee841f | ||
|
|
00df25e8ff | ||
|
|
e51fabfe64 | ||
|
|
eea9f714d6 | ||
|
|
007391f124 | ||
|
|
006e58a922 | ||
|
|
427d837b35 | ||
|
|
d62915bfe5 |
203 changed files with 440 additions and 11225 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -9,10 +9,10 @@
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
# profiling files
|
# profiling files
|
||||||
chrome-profiler-events*.json
|
chrome-profiler-events*.json
|
||||||
speed-measure-plugin*.json
|
|
||||||
|
|
||||||
# IDEs and editors
|
# IDEs and editors
|
||||||
/.idea
|
/.idea
|
||||||
|
|
@ -40,13 +40,7 @@ npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
testem.log
|
testem.log
|
||||||
/typings
|
/typings
|
||||||
*.env
|
|
||||||
|
|
||||||
# System Files
|
# System Files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
/backend/database/
|
|
||||||
/backend/node_modules/
|
|
||||||
|
|
||||||
package-lock.json
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
FROM node:current-slim
|
|
||||||
WORKDIR /app-frontend
|
|
||||||
COPY ["package.json", "package-lock.json*", "./"]
|
|
||||||
RUN npm install --NODE_ENV
|
|
||||||
RUN npm install -g @angular/cli
|
|
||||||
COPY . .
|
|
||||||
13
README.md
13
README.md
|
|
@ -1,18 +1,19 @@
|
||||||
# Frontend
|
# Admin
|
||||||
|
|
||||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.7.
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.10.
|
||||||
|
|
||||||
## Development server
|
## Development server
|
||||||
|
|
||||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||||
|
|
||||||
## Code scaffolding
|
## Code scaffolding
|
||||||
à
|
|
||||||
Run `ng generate component component-title` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||||
|
Then run `npm start`
|
||||||
|
|
||||||
## Running unit tests
|
## Running unit tests
|
||||||
|
|
||||||
|
|
@ -20,7 +21,7 @@ Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.
|
||||||
|
|
||||||
## Running end-to-end tests
|
## Running end-to-end tests
|
||||||
|
|
||||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
|
||||||
|
|
||||||
## Further help
|
## Further help
|
||||||
|
|
||||||
|
|
|
||||||
97
angular.json
97
angular.json
|
|
@ -3,11 +3,14 @@
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"newProjectRoot": "projects",
|
"newProjectRoot": "projects",
|
||||||
"projects": {
|
"projects": {
|
||||||
"frontend": {
|
"admin": {
|
||||||
"projectType": "application",
|
"projectType": "application",
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"@schematics/angular:component": {
|
"@schematics/angular:component": {
|
||||||
"style": "scss"
|
"style": "scss"
|
||||||
|
},
|
||||||
|
"@schematics/angular:application": {
|
||||||
|
"strict": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "",
|
"root": "",
|
||||||
|
|
@ -17,12 +20,12 @@
|
||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
"options": {
|
"options": {
|
||||||
"outputPath": "dist/frontend",
|
"outputPath": "dist/frontend-admin",
|
||||||
"index": "src/index.html",
|
"index": "src/index.html",
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "tsconfig.app.json",
|
"tsConfig": "tsconfig.app.json",
|
||||||
"aot": true,
|
"inlineStyleLanguage": "scss",
|
||||||
"assets": [
|
"assets": [
|
||||||
"src/favicon.ico",
|
"src/favicon.ico",
|
||||||
"src/assets"
|
"src/assets"
|
||||||
|
|
@ -32,56 +35,57 @@
|
||||||
"src/styles.scss",
|
"src/styles.scss",
|
||||||
"node_modules/bootstrap/scss/bootstrap.scss"
|
"node_modules/bootstrap/scss/bootstrap.scss"
|
||||||
],
|
],
|
||||||
"scripts": [
|
"scripts": []
|
||||||
"node_modules/jquery/dist/jquery.js",
|
|
||||||
"node_modules/bootstrap/dist/js/bootstrap.js"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "1mb",
|
||||||
|
"maximumError": "2mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "2kb",
|
||||||
|
"maximumError": "4kb"
|
||||||
|
}
|
||||||
|
],
|
||||||
"fileReplacements": [
|
"fileReplacements": [
|
||||||
{
|
{
|
||||||
"replace": "src/environments/environment.ts",
|
"replace": "src/environments/environment.ts",
|
||||||
"with": "src/environments/environment.prod.ts"
|
"with": "src/environments/environment.prod.ts"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"optimization": true,
|
"outputHashing": "all"
|
||||||
"outputHashing": "all",
|
|
||||||
"sourceMap": false,
|
|
||||||
"namedChunks": false,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"vendorChunk": false,
|
|
||||||
"buildOptimizer": true,
|
|
||||||
"budgets": [
|
|
||||||
{
|
|
||||||
"type": "initial",
|
|
||||||
"maximumWarning": "2mb",
|
|
||||||
"maximumError": "5mb"
|
|
||||||
},
|
},
|
||||||
{
|
"development": {
|
||||||
"type": "anyComponentStyle",
|
"buildOptimizer": false,
|
||||||
"maximumWarning": "6kb",
|
"optimization": false,
|
||||||
"maximumError": "10kb"
|
"vendorChunk": true,
|
||||||
}
|
"extractLicenses": false,
|
||||||
]
|
"sourceMap": true,
|
||||||
}
|
"namedChunks": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
"serve": {
|
"serve": {
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
"options": {
|
|
||||||
"browserTarget": "frontend:build"
|
|
||||||
},
|
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
"browserTarget": "frontend:build:production"
|
"browserTarget": "admin:build:production"
|
||||||
}
|
},
|
||||||
|
"development": {
|
||||||
|
"browserTarget": "admin:build:development"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"defaultConfiguration": "development"
|
||||||
|
},
|
||||||
"extract-i18n": {
|
"extract-i18n": {
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
"options": {
|
"options": {
|
||||||
"browserTarget": "frontend:build"
|
"browserTarget": "admin:build"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
|
|
@ -91,44 +95,19 @@
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "tsconfig.spec.json",
|
"tsConfig": "tsconfig.spec.json",
|
||||||
"karmaConfig": "karma.conf.js",
|
"karmaConfig": "karma.conf.js",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
"assets": [
|
"assets": [
|
||||||
"src/favicon.ico",
|
"src/favicon.ico",
|
||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"tsconfig.app.json",
|
|
||||||
"tsconfig.spec.json",
|
|
||||||
"e2e/tsconfig.json"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"e2e": {
|
|
||||||
"builder": "@angular-devkit/build-angular:protractor",
|
|
||||||
"options": {
|
|
||||||
"protractorConfig": "e2e/protractor.conf.js",
|
|
||||||
"devServerTarget": "frontend:serve"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "frontend:serve:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultProject": "frontend"
|
"defaultProject": "admin"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
const request = require("request");
|
|
||||||
const VideoCategories = require("../models/objects/video.categories.model");
|
|
||||||
|
|
||||||
function asyncRequest(uri, option){
|
|
||||||
return new Promise(function(resolve){
|
|
||||||
request(uri, option,function (error, response, body){
|
|
||||||
resolve({response: response, body: JSON.parse(body)});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
module.exports.asyncRequest = asyncRequest;
|
|
||||||
|
|
||||||
function asyncInterest(interest, source){
|
|
||||||
return new Promise(function(resolve){
|
|
||||||
for(const i in VideoCategories){
|
|
||||||
for(const j in VideoCategories[i].categories){
|
|
||||||
if((VideoCategories[i].categories[j].name === interest || VideoCategories[i].categories[j].id === interest)
|
|
||||||
&& VideoCategories[i].categories[j].source === source){
|
|
||||||
resolve(VideoCategories[i].interest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolve(null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
module.exports.asyncInterest = asyncInterest;
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
if(process.env.YOUTUBE_API_KEY === undefined ||
|
|
||||||
process.env.YOUTUBE_API_KEY === '' ||
|
|
||||||
process.env.DAILYMOTION_API_KEY === undefined ||
|
|
||||||
process.env.DAILYMOTION_API_KEY === ''){
|
|
||||||
console.log('Error Env YOUTUBE_API_KEY & DAILYMOTION_API_KEY Variables');
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Env variables YOUTUBE_API_KEY & DAILYMOTION_API_KEY received');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
youtube: {
|
|
||||||
name: "Youtube",
|
|
||||||
shortname: "yt",
|
|
||||||
baseAPIUrl: 'https://youtube.googleapis.com/youtube/v3',
|
|
||||||
baseChannelUrl: 'https://www.youtube.com/channel/',
|
|
||||||
YOUTUBE_API_KEY: process.env.YOUTUBE_API_KEY
|
|
||||||
},
|
|
||||||
dailymotion: {
|
|
||||||
name: "Dailymotion",
|
|
||||||
shortname: "dm",
|
|
||||||
baseAPIUrl: 'https://api.dailymotion.com',
|
|
||||||
baseChannelUrl: 'https://www.dailymotion.com/',
|
|
||||||
DAILYMOTION_API_KEY: process.env.DAILYMOTION_API_KEY
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
prodUrl: process.env.DATABASE,
|
|
||||||
devUrl: "mongodb://127.0.0.1:27017/polynotfound"
|
|
||||||
};
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
function sendMessage (res, successCode, data, token=null) {
|
|
||||||
res.status(200).json({ status: 'success', successCode: successCode, token: token, data: data });
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendError (res, statusCode, errorCode, reason, token=null) {
|
|
||||||
res.status(statusCode).json({ status: 'error', errorCode: errorCode, token: token, reason: reason});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { sendMessage, sendError };
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
const sessionJWTConfig = require ('jsonwebtoken');
|
|
||||||
require('dotenv').config({ path: './app-backend/.env' });
|
|
||||||
const {sendError} = require ("./response.config");
|
|
||||||
|
|
||||||
if(process.env.JWTRS256_PRIVATE_KEY === undefined || process.env.JWTRS256_PUBLIC_KEY === undefined){
|
|
||||||
console.log('Error Env JWTRS256_PRIVATE_KEY & JWTRS256_PUBLIC_KEY Variables');
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Env variables JWTRS256_PRIVATE_KEY & JWTRS256_PUBLIC_KEY received');
|
|
||||||
const JWTRS256_PRIVATE_KEY = Buffer.from(process.env.JWTRS256_PRIVATE_KEY, 'base64').toString('utf-8');
|
|
||||||
const JWTRS256_PUBLIC_KEY = Buffer.from(process.env.JWTRS256_PUBLIC_KEY, 'base64').toString('utf-8');
|
|
||||||
|
|
||||||
|
|
||||||
function createSessionJWT (id, email, profileImageUrl, role) {
|
|
||||||
return sessionJWTConfig.sign(
|
|
||||||
{
|
|
||||||
id: id,
|
|
||||||
email: email,
|
|
||||||
profileImageUrl: profileImageUrl,
|
|
||||||
role: role,
|
|
||||||
midExp: Math.floor(Date.now() / 1000) + 1800
|
|
||||||
},
|
|
||||||
JWTRS256_PRIVATE_KEY,
|
|
||||||
{
|
|
||||||
algorithm: 'RS256',
|
|
||||||
expiresIn: '1h'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createSessionCookie(req, res, payload) {
|
|
||||||
let jwtToken;
|
|
||||||
if (typeof payload.id !== 'undefined' &&
|
|
||||||
typeof payload.email !== 'undefined' &&
|
|
||||||
typeof payload.profileImageUrl !== 'undefined' &&
|
|
||||||
typeof payload.role !== 'undefined' &&
|
|
||||||
typeof payload.midExp !== 'undefined' &&
|
|
||||||
(Math.floor(Date.now() / 1000) <= payload.midExp)) {
|
|
||||||
jwtToken = req.headers.cookie;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
jwtToken = createSessionJWT(payload.id, payload.email, payload.profileImageUrl, payload.role);
|
|
||||||
}
|
|
||||||
res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false});
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeSessionCookie(sessionid) {
|
|
||||||
if (typeof sessionid === 'undefined') {
|
|
||||||
return {id: -1, email: -1, profileImageUrl: -1, role: -1};
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const token = sessionJWTConfig.verify(
|
|
||||||
sessionid,
|
|
||||||
JWTRS256_PUBLIC_KEY,
|
|
||||||
{algorithms: ['RS256']});
|
|
||||||
return {token: token};
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
return {id: -1, email: -1, profileImageUrl: -1, role: -1};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSession(sessionid) {
|
|
||||||
return decodeSessionCookie(sessionid);
|
|
||||||
}
|
|
||||||
module.exports.getSession = getSession
|
|
||||||
|
|
||||||
function setSessionCookie (req, res, session) {
|
|
||||||
createSessionCookie(req, res, session);
|
|
||||||
}
|
|
||||||
module.exports.setSessionCookie = setSessionCookie;
|
|
||||||
|
|
||||||
function getToken(session) {
|
|
||||||
if (typeof session === 'undefined' || typeof session.token === 'undefined') return -1;
|
|
||||||
return session.token;
|
|
||||||
}
|
|
||||||
module.exports.getToken = getToken;
|
|
||||||
|
|
||||||
function checkLogin(req, res, role=null){
|
|
||||||
if(typeof req.cookies !== 'undefined'){
|
|
||||||
const session = getSession(req.cookies.SESSIONID);
|
|
||||||
const token = getToken(session);
|
|
||||||
if(typeof token.email === 'undefined' ||
|
|
||||||
token.email === -1 ||
|
|
||||||
typeof token.id === 'undefined' ||
|
|
||||||
token.id === -1){
|
|
||||||
return sendError(res, 500, 102, "User not authenticated.");
|
|
||||||
} else {
|
|
||||||
token.midExp = new Date(token.midExp*1000);
|
|
||||||
token.iat = new Date(token.iat*1000);
|
|
||||||
token.exp = new Date(token.exp*1000);
|
|
||||||
if(role === null){
|
|
||||||
return token;
|
|
||||||
} else {
|
|
||||||
if(typeof token.role !== 'undefined' &&
|
|
||||||
((Array.isArray(role) && role.includes(token.role)) ||
|
|
||||||
( typeof role === 'object' && typeof token.role.permission !== 'undefined' && token.role.permission >= role.permission && token.role.isAccepted === true))){
|
|
||||||
return token;
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, 106, "User doesn't have permission.", token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, "Cookies don't exist.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module.exports.checkLogin = checkLogin;
|
|
||||||
|
|
@ -1,290 +0,0 @@
|
||||||
const db = require("../models/mongodb.model");
|
|
||||||
const {sendError, sendMessage} = require ("../config/response.config");
|
|
||||||
const {checkLogin} = require("../config/sessionJWT.config");
|
|
||||||
const ObjectId = require('mongoose').Types.ObjectId;
|
|
||||||
const roles = require("../models/objects/role.model");
|
|
||||||
const Ad = db.ads;
|
|
||||||
|
|
||||||
// Create a new Ad
|
|
||||||
exports.create = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.Advertiser);
|
|
||||||
if(token && req.body.title){
|
|
||||||
Ad.exists({title: req.body.title, userId: token.id, isActive: true}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
sendError(res, 500,100,err.message || "Some error occurred while checking if the Ad already exists.", token);
|
|
||||||
} else{
|
|
||||||
if(docs === null) {
|
|
||||||
let ad;
|
|
||||||
|
|
||||||
ad = new Ad({
|
|
||||||
userId: token.id,
|
|
||||||
title: req.body.title,
|
|
||||||
images: req.body.images ? req.body.images : undefined,
|
|
||||||
url: req.body.url ? req.body.url : undefined,
|
|
||||||
interests: req.body.interests ? req.body.interests : undefined,
|
|
||||||
comment: req.body.comment ? req.body.comment : undefined,
|
|
||||||
isVisible: req.body.isVisible ? req.body.isVisible : undefined,
|
|
||||||
isActive: req.body.isActive ? req.body.isActive : undefined
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save User in the database
|
|
||||||
ad
|
|
||||||
.save(ad)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 41, data, token)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500,100,err.message || "Some error occurred while creating the Ad.", token);
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, 104, err || `Ad ${req.body.title} already exists.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No title given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Retrieve all Ad from id if admin or session id
|
|
||||||
exports.findAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.Advertiser);
|
|
||||||
if(token){
|
|
||||||
let query = {};
|
|
||||||
let condition;
|
|
||||||
|
|
||||||
const adId = req.query.adId;
|
|
||||||
condition = adId ? adId : undefined;
|
|
||||||
query._id = condition;
|
|
||||||
|
|
||||||
let userId;
|
|
||||||
if(typeof token.role !== 'undefined' &&
|
|
||||||
typeof token.role.permission !== 'undefined' &&
|
|
||||||
typeof token.role.isAccepted !== 'undefined' &&
|
|
||||||
token.role.isAccepted === true &&
|
|
||||||
token.role.permission >= roles.Admin.permission) {
|
|
||||||
userId = req.query.userId;
|
|
||||||
} else {
|
|
||||||
userId = token.id;
|
|
||||||
}
|
|
||||||
condition = userId ? userId : undefined;
|
|
||||||
query.userId = condition;
|
|
||||||
|
|
||||||
const title = req.query.title;
|
|
||||||
condition = title ? { $regex: new RegExp(title), $options: "i" } : undefined;
|
|
||||||
query.title = condition;
|
|
||||||
|
|
||||||
const url = req.query.url;
|
|
||||||
condition = url ? { $regex: new RegExp(url), $options: "i" } : undefined;
|
|
||||||
query.url = condition;
|
|
||||||
|
|
||||||
const interests = req.query.interests;
|
|
||||||
condition = interests ? {$in: interests.split(',')} : undefined;
|
|
||||||
query["interests.interest"] = condition
|
|
||||||
|
|
||||||
const comment = req.query.comment;
|
|
||||||
condition = comment ? { $regex: new RegExp(comment), $options: "i" } : undefined;
|
|
||||||
query.comment = condition;
|
|
||||||
|
|
||||||
const isVisible = req.query.isVisible;
|
|
||||||
condition = isVisible ? isVisible : undefined;
|
|
||||||
query.isVisible = condition;
|
|
||||||
|
|
||||||
const isActive = req.query.isActive;
|
|
||||||
condition = isActive ? isActive : undefined;
|
|
||||||
query.isActive = condition;
|
|
||||||
|
|
||||||
const sort = req.query.sort;
|
|
||||||
if(sort !== 'undefined'){
|
|
||||||
switch (sort){
|
|
||||||
case 'asc':
|
|
||||||
condition = {title: 1};
|
|
||||||
break;
|
|
||||||
case 'desc':
|
|
||||||
condition = {title: -1};
|
|
||||||
break;
|
|
||||||
case 'createdAtAsc':
|
|
||||||
condition = {createdAt: 1};
|
|
||||||
break;
|
|
||||||
case 'createdAtDesc':
|
|
||||||
condition = {createdAt: -1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtAsc':
|
|
||||||
condition = {updatedAt: 1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtDesc':
|
|
||||||
condition = {updatedAt: -1};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
condition = {title: 1};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const query_sort = {sort: condition};
|
|
||||||
|
|
||||||
// Remove undefined key
|
|
||||||
Object.keys(query).forEach(key => query[key] === undefined ? delete query[key] : {});
|
|
||||||
console.log(query);
|
|
||||||
|
|
||||||
Ad.find(query, {}, query_sort)
|
|
||||||
.then(data => {
|
|
||||||
if(data){
|
|
||||||
return sendMessage(res, 42, data, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || "Some error occurred while finding the Ads.", token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find single Ad from id if admin or session id
|
|
||||||
exports.findOne = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.Advertiser);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
Ad.findById(id, {})
|
|
||||||
.then(data => {
|
|
||||||
if(data){
|
|
||||||
return sendMessage(res, 43, data, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res,404,105,`Ad not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || `Some error occurred while finding the Ad with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update a Ad with ad id
|
|
||||||
exports.update = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.Advertiser);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(typeof req.body._id !== 'undefined' || typeof req.body.id !== 'undefined'){
|
|
||||||
return sendError(res, 500, -1, `User do not have the permission to modify id or _id`, token);
|
|
||||||
} else{
|
|
||||||
let update = {};
|
|
||||||
let condition;
|
|
||||||
|
|
||||||
const title = req.body.title;
|
|
||||||
condition = title ? title : undefined;
|
|
||||||
update.title = condition;
|
|
||||||
|
|
||||||
const images = req.body.images;
|
|
||||||
condition = images ? images : undefined;
|
|
||||||
update.images = condition;
|
|
||||||
|
|
||||||
const url = req.body.url;
|
|
||||||
condition = url ? url : undefined;
|
|
||||||
update.url = condition;
|
|
||||||
|
|
||||||
let interests = req.body.interests;
|
|
||||||
condition = interests ? {interests: [...new Map(interests.map(v => [v.id, v])).values()]} : undefined;
|
|
||||||
update.$addToSet = condition;
|
|
||||||
|
|
||||||
const comment = req.body.comment;
|
|
||||||
condition = comment ? comment : undefined;
|
|
||||||
update.comment = condition;
|
|
||||||
|
|
||||||
const isVisible = req.body.isVisible;
|
|
||||||
if(typeof isVisible !== 'undefined'){
|
|
||||||
condition = isVisible;
|
|
||||||
} else{
|
|
||||||
condition = undefined;
|
|
||||||
}
|
|
||||||
update.isVisible = condition;
|
|
||||||
|
|
||||||
const isActive = req.body.isActive;
|
|
||||||
if(typeof isActive !== 'undefined'){
|
|
||||||
condition = isActive;
|
|
||||||
} else{
|
|
||||||
condition = undefined;
|
|
||||||
}
|
|
||||||
update.isActive = condition;
|
|
||||||
|
|
||||||
// Remove undefined key
|
|
||||||
Object.keys(update).forEach(key => update[key] === undefined ? delete update[key] : {});
|
|
||||||
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
Ad.updateOne({_id: id, userId: token.id}, update)
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
//Object.keys(update).forEach(key => data[key] = update[key]);
|
|
||||||
return sendMessage(res, 44, update, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, -1, `Ad not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, -1, err.message || `Some error occurred while updating the Ad with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete an Ad with ad id
|
|
||||||
exports.delete = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.Advertiser);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
let match = null;
|
|
||||||
const id = req.params.id;
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
if(typeof token.role !== 'undefined' &&
|
|
||||||
typeof token.role.permission !== 'undefined' &&
|
|
||||||
typeof token.role.isAccepted !== 'undefined' &&
|
|
||||||
token.role.isAccepted === true &&
|
|
||||||
token.role.permission >= roles.Admin.permission) {
|
|
||||||
match = {_id: id, isActive: true};
|
|
||||||
} else {
|
|
||||||
match = {_id: id, userId: token.id, isActive: true};
|
|
||||||
}
|
|
||||||
Ad.findOneAndUpdate(match, {isActive: false}, {useFindAndModify: false, new: true})
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
if(data.isActive !== true){
|
|
||||||
return sendMessage(res, 45, {message: `Ad ${id} was successfully deleted.`}, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, 105, `Ad ${id} was not deleted.`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, 105, `Ad not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, 100, err.message || `Some error occurred while deleting the Ad with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete all Ad from session id
|
|
||||||
exports.deleteAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.Advertiser);
|
|
||||||
if(token) {
|
|
||||||
Ad.updateMany({userId: {$eq: token.id}, isActive: true}, {isActive: false})
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 46, {
|
|
||||||
message: `${data.modifiedCount} Ads were deleted successfully.`
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, -1, err.message || "Some error occurred while removing all Ads.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
const {sendMessage} = require ("../config/response.config");
|
|
||||||
const interests = require("../models/objects/video.categories.model");
|
|
||||||
|
|
||||||
// Get all interests available
|
|
||||||
exports.getInterests = (req, res) => {
|
|
||||||
return sendMessage(res, 51, interests, null)
|
|
||||||
};
|
|
||||||
|
|
@ -1,407 +0,0 @@
|
||||||
const db = require("../models/mongodb.model");
|
|
||||||
const {sendError, sendMessage} = require ("../config/response.config");
|
|
||||||
const {checkLogin} = require("../config/sessionJWT.config");
|
|
||||||
const {youtube, dailymotion} = require("../config/host.config");
|
|
||||||
const {asyncRequest, asyncInterest} = require("../config/functions.config");
|
|
||||||
const ObjectId = require('mongoose').Types.ObjectId;
|
|
||||||
const Playlist = db.playlists;
|
|
||||||
const Video = db.videos;
|
|
||||||
|
|
||||||
// Create a new Playlist
|
|
||||||
exports.create = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && req.body.name){
|
|
||||||
const video = req.body.video;
|
|
||||||
if(typeof video !== 'undefined' &&
|
|
||||||
video !== null &&
|
|
||||||
typeof video.videoId !== 'undefined' &&
|
|
||||||
video.videoId !== null &&
|
|
||||||
typeof video.source !== 'undefined' &&
|
|
||||||
video.source !== null &&
|
|
||||||
typeof video.interest !== 'undefined' &&
|
|
||||||
video.interest !== null
|
|
||||||
){
|
|
||||||
Video.exists({userId: token.id, videoId: video.videoId, source: video.source, isActive: true}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
sendError(res, 500,100,err.message || "Some error occurred while checking if the Video already exists.", token);
|
|
||||||
} else{
|
|
||||||
if(docs === null) {
|
|
||||||
let video;
|
|
||||||
|
|
||||||
video = new Video({
|
|
||||||
userId: token.id,
|
|
||||||
videoId: id,
|
|
||||||
source: req.body.source,
|
|
||||||
interest: req.body.interest,
|
|
||||||
watchedDates: [new Date()]
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save Video in the database
|
|
||||||
video
|
|
||||||
.save(video)
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
Playlist.exists({name: req.body.name, isActive: true}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
sendError(res, 500,100,err.message || "Some error occurred while checking if the Playlist already exists.", token);
|
|
||||||
} else{
|
|
||||||
if(docs === null) {
|
|
||||||
let playlist;
|
|
||||||
|
|
||||||
playlist = new Playlist({
|
|
||||||
userId: token.id,
|
|
||||||
name: req.body.name,
|
|
||||||
videoIds: data._id ? [data._id] : undefined,
|
|
||||||
isActive: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save User in the database
|
|
||||||
playlist
|
|
||||||
.save(playlist)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 21, data, token)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500,100,err.message || "Some error occurred while creating the Playlist.", token);
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, 104, err || `Playlist ${req.body.name} already exists.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500,100,err.message || "Some error occurred while creating the Video.", token);
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
const id = docs._id.toString();
|
|
||||||
Playlist.exists({name: req.body.name, isActive: true}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
sendError(res, 500,100,err.message || "Some error occurred while checking if the Playlist already exists.", token);
|
|
||||||
} else{
|
|
||||||
if(docs === null) {
|
|
||||||
let playlist;
|
|
||||||
|
|
||||||
playlist = new Playlist({
|
|
||||||
userId: token.id,
|
|
||||||
name: req.body.name,
|
|
||||||
videoIds: [id],
|
|
||||||
isActive: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save User in the database
|
|
||||||
playlist
|
|
||||||
.save(playlist)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 21, data, token)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500,100,err.message || "Some error occurred while creating the Playlist.", token);
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, 104, err || `Playlist ${req.body.name} already exists.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Playlist.exists({name: req.body.name, isActive: true}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
sendError(res, 500,100,err.message || "Some error occurred while checking if the Playlist already exists.", token);
|
|
||||||
} else{
|
|
||||||
if(docs === null) {
|
|
||||||
let playlist;
|
|
||||||
|
|
||||||
playlist = new Playlist({
|
|
||||||
userId: token.id,
|
|
||||||
name: req.body.name,
|
|
||||||
videoIds: req.body.videoIds ? req.body.videoIds : undefined,
|
|
||||||
isActive: req.body.isActive ? req.body.isActive : undefined
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save User in the database
|
|
||||||
playlist
|
|
||||||
.save(playlist)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 21, data, token)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500,100,err.message || "Some error occurred while creating the Playlist.", token);
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, 104, err || `Playlist ${req.body.name} already exists.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Retrieve all Playlist from id if admin or session id
|
|
||||||
exports.findAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token){
|
|
||||||
let query = {};
|
|
||||||
let condition;
|
|
||||||
|
|
||||||
const playlistId = req.query.playlistId;
|
|
||||||
condition = playlistId ? playlistId : undefined;
|
|
||||||
query._id = condition;
|
|
||||||
|
|
||||||
const userId = token.id;
|
|
||||||
condition = userId ? userId : undefined;
|
|
||||||
query.userId = condition;
|
|
||||||
|
|
||||||
const videoIds = req.query.videoIds;
|
|
||||||
condition = videoIds ? {$in: videoIds} : undefined;
|
|
||||||
query.videoIds = condition;
|
|
||||||
|
|
||||||
const name = req.query.name;
|
|
||||||
condition = name ? { $regex: new RegExp(name), $options: "i" } : undefined;
|
|
||||||
query.name = condition;
|
|
||||||
|
|
||||||
const isActive = req.query.isActive;
|
|
||||||
condition = isActive ? isActive : undefined;
|
|
||||||
query.isActive = condition;
|
|
||||||
|
|
||||||
const sort = req.query.sort;
|
|
||||||
if(sort !== 'undefined'){
|
|
||||||
switch (sort){
|
|
||||||
case 'asc':
|
|
||||||
condition = {name: 1};
|
|
||||||
break;
|
|
||||||
case 'desc':
|
|
||||||
condition = {name: -1};
|
|
||||||
break;
|
|
||||||
case 'createdAtAsc':
|
|
||||||
condition = {createdAt: 1};
|
|
||||||
break;
|
|
||||||
case 'createdAtDesc':
|
|
||||||
condition = {createdAt: -1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtAsc':
|
|
||||||
condition = {updatedAt: 1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtDesc':
|
|
||||||
condition = {updatedAt: -1};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
condition = {name: 1};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const query_sort = {sort: condition};
|
|
||||||
|
|
||||||
// Remove undefined key
|
|
||||||
Object.keys(query).forEach(key => query[key] === undefined ? delete query[key] : {});
|
|
||||||
console.log(query);
|
|
||||||
|
|
||||||
Playlist.find(query, {}, query_sort)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 22, data, token);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || "Some error occurred while finding the Playlists.", token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find single Playlist from session id
|
|
||||||
exports.findOne = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
Playlist.aggregate([
|
|
||||||
{$match: {_id: new ObjectId(id), userId: token.id, isActive: true}},
|
|
||||||
{$unwind: '$videoIds'},
|
|
||||||
{$project: {
|
|
||||||
userId: true,
|
|
||||||
name: true,
|
|
||||||
isActive: true,
|
|
||||||
createdAt: true,
|
|
||||||
updatedAt: true,
|
|
||||||
videoIds: {$toObjectId: '$videoIds'}
|
|
||||||
}},
|
|
||||||
{$lookup: {
|
|
||||||
from: 'videos',
|
|
||||||
localField: 'videoIds',
|
|
||||||
foreignField: '_id',
|
|
||||||
as: 'videos'
|
|
||||||
}},
|
|
||||||
{$unwind: '$videos'},
|
|
||||||
{$group: {
|
|
||||||
_id: '$_id',
|
|
||||||
userId: {$first: "$userId"},
|
|
||||||
name: {$first: "$name"},
|
|
||||||
isActive: {$first: "$isActive"},
|
|
||||||
createdAt: {$first: "$createdAt"},
|
|
||||||
updatedAt: {$first: "$updatedAt"},
|
|
||||||
videos: {$push: "$videos"}
|
|
||||||
}}
|
|
||||||
])
|
|
||||||
.then(async data => {
|
|
||||||
let yt_results = [];
|
|
||||||
let dm_results = [];
|
|
||||||
let yt_videoIds = "";
|
|
||||||
let dm_videoIds = "";
|
|
||||||
|
|
||||||
for (const i in data[0].videos) {
|
|
||||||
if (data[0].videos[i].source === youtube.name) {
|
|
||||||
yt_videoIds = yt_videoIds + data[0].videos[i].videoId + ",";
|
|
||||||
} else if (data[0].videos[i].source === dailymotion.name) {
|
|
||||||
dm_videoIds = dm_videoIds + data[0].videos[i].videoId + ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (yt_videoIds !== "") {
|
|
||||||
const uri = youtube.baseAPIUrl + '/videos' + '?part=snippet&part=statistics&id=' + yt_videoIds.slice(0, -1) + '&key=' + youtube.YOUTUBE_API_KEY;
|
|
||||||
const dataVideos = await asyncRequest(uri, {});
|
|
||||||
if (dataVideos.response.statusCode === 200 && dataVideos.body.items.length > 0) {
|
|
||||||
yt_results = dataVideos.body.items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_videoIds !== "") {
|
|
||||||
const uri = dailymotion.baseAPIUrl + '/videos?ids=' + dm_videoIds.slice(0, -1) + '&fields=thumbnail_480_url%2Ctitle%2Cid';
|
|
||||||
const data = await asyncRequest(uri, {});
|
|
||||||
const response = data.response;
|
|
||||||
const jsonBody = data.body;
|
|
||||||
if (response.statusCode === 200) {
|
|
||||||
dm_results = jsonBody.list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const i in data[0].videos) {
|
|
||||||
if (data[0].videos[i].source === youtube.name) {
|
|
||||||
const obj = yt_results.filter(obj => obj.id === data[0].videos[i].videoId);
|
|
||||||
data[0].videos[i].imageUrl = obj[0].snippet.thumbnails.medium.url ? obj[0].snippet.thumbnails.medium.url : null;
|
|
||||||
data[0].videos[i].interest = obj[0].snippet.categoryId ? await asyncInterest(obj[0].snippet.categoryId, youtube.name): null;
|
|
||||||
data[0].videos[i].title = obj[0].snippet.title ? obj[0].snippet.title : null;
|
|
||||||
data[0].videos[i].views = obj[0].statistics.viewCount ? parseInt(obj[0].statistics.viewCount) : null;
|
|
||||||
data[0].videos[i].publishedAt = obj[0].snippet.publishedAt ? obj[0].snippet.publishedAt : null;
|
|
||||||
} else if (data[0].videos[i].source === dailymotion.name) {
|
|
||||||
const obj = dm_results.filter(obj => obj.id === data[0].videos[i].videoId);
|
|
||||||
data[0].videos[i].imageUrl = obj[0].thumbnail_480_url ? obj[0].thumbnail_480_url : null;
|
|
||||||
data[0].videos[i].interest = obj[0]['channel.name'] ? await asyncInterest( obj[0]['channel.name'], dailymotion.name) : null;
|
|
||||||
data[0].videos[i].title = obj[0].title ? obj[0].title : null;
|
|
||||||
data[0].videos[i].views = obj[0].views_total ? parseInt(obj[0].views_total) : null;
|
|
||||||
data[0].videos[i].publishedAt = obj[0].created_time ? new Date(obj[0].created_time * 1000) : null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sendMessage(res, 12, data[0], token)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || `Some error occurred while finding the Playlist with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update a Playlist with playlist id
|
|
||||||
exports.update = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(typeof req.body._id !== 'undefined' || typeof req.body.id !== 'undefined'){
|
|
||||||
return sendError(res, 500, -1, `User do not have the permission to modify id or _id`, token);
|
|
||||||
} else{
|
|
||||||
const ids = id.split(',');
|
|
||||||
let update = {};
|
|
||||||
let condition;
|
|
||||||
|
|
||||||
const name = req.body.name;
|
|
||||||
condition = name ? name : undefined;
|
|
||||||
update.name = condition;
|
|
||||||
|
|
||||||
const videoIds = req.body.videoIds;
|
|
||||||
condition = videoIds ? videoIds : undefined;
|
|
||||||
update.videoIds = condition;
|
|
||||||
|
|
||||||
const videoId = req.body.videoId;
|
|
||||||
if(typeof videoId !== 'undefined' && typeof videoId.id !== 'undefined' && typeof videoId.action !== 'undefined'){
|
|
||||||
if(videoId.action === 'add'){
|
|
||||||
condition = videoId.id ? {videoIds: videoId.id} : undefined;
|
|
||||||
update.$addToSet = condition;
|
|
||||||
} else if(videoId.action === 'delete'){
|
|
||||||
condition = videoId.id ? {videoIds: videoId.id} : undefined;
|
|
||||||
update.$pull = condition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const isActive = req.body.isActive;
|
|
||||||
if(typeof isActive !== 'undefined'){
|
|
||||||
condition = isActive;
|
|
||||||
} else{
|
|
||||||
condition = undefined;
|
|
||||||
}
|
|
||||||
update.isActive = condition;
|
|
||||||
|
|
||||||
// Remove undefined key
|
|
||||||
Object.keys(update).forEach(key => update[key] === undefined ? delete update[key] : {});
|
|
||||||
|
|
||||||
Playlist.updateMany({_id: {$in: ids}, userId: token.id, isActive: true}, update, {new: false})
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
if(data.modifiedCount > 0){
|
|
||||||
return sendMessage(res, 24, update, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Video in Playlist ${data} already exists.`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, -1, `Playlist not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, -1, err.message || `Some error occurred while updating the Playlist with id=${id}`, token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete a Playlist with playlist id
|
|
||||||
exports.delete = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
Playlist.findByIdAndUpdate(id, {isActive: false}, {useFindAndModify: false})
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
return sendMessage(res, 25, {message: `Playlist ${id} was successfully deleted.`}, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, 105, `Playlist not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, 100, err.message || `Some error occurred while deleting the Playlist with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete all Playlists from session id
|
|
||||||
exports.deleteAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token) {
|
|
||||||
Playlist.updateMany({userId: {$eq: token.id}, isActive: true}, {isActive: false})
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 26, {
|
|
||||||
message: `${data.modifiedCount} Playlists were deleted successfully.`
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, -1, err.message || "Some error occurred while removing all Playlists.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,546 +0,0 @@
|
||||||
const db = require("../models/mongodb.model");
|
|
||||||
const {sendError, sendMessage} = require ("../config/response.config");
|
|
||||||
const {checkLogin, setSessionCookie} = require("../config/sessionJWT.config");
|
|
||||||
const ObjectId = require('mongoose').Types.ObjectId;
|
|
||||||
const roles = require("../models/objects/role.model");
|
|
||||||
const {youtube, dailymotion} = require("../config/host.config");
|
|
||||||
const {asyncRequest} = require("../config/functions.config");
|
|
||||||
const User = db.users;
|
|
||||||
const Video = db.videos;
|
|
||||||
const Ad = db.ads;
|
|
||||||
|
|
||||||
// Authenticate a User
|
|
||||||
exports.auth = (req, res) => {
|
|
||||||
// Validate request
|
|
||||||
if (!req.body.email || !req.body.hashPass) {
|
|
||||||
sendError(res, 400,-1,"Content can not be empty . (email and hashPass needed)");
|
|
||||||
} else{
|
|
||||||
// Check User in the database
|
|
||||||
User
|
|
||||||
.findOne({email: req.body.email, hashPass: req.body.hashPass, isActive: true, "role.isAccepted": true}, {role: true, profileImageUrl: true})
|
|
||||||
.then(data => {
|
|
||||||
if (data !== null){
|
|
||||||
User.findByIdAndUpdate(data._id.toString(), {lastConnexion: new Date()}, {useFindAndModify: false},
|
|
||||||
function (err) {
|
|
||||||
if (err){
|
|
||||||
return sendError(res, 400, 100,err.message || "Some error occurred while updating the User.");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
const dataRes = {id: data._id.toString(), email: req.body.email, profileImageUrl: data.profileImageUrl, role: data.role};
|
|
||||||
setSessionCookie(req, res, dataRes);
|
|
||||||
return sendMessage(res, 1, dataRes);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setSessionCookie(req, res, {id: -1, email: -1, profileImageUrl: -1, role: -1});
|
|
||||||
return sendError(res, 500, 101, "Invalid login or password.");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 400, 100,err.message || "Some error occurred while authenticating the User.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Logout a User
|
|
||||||
exports.logout = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token){
|
|
||||||
setSessionCookie(req, res, {id: -1, email: -1, profileImageUrl: -1, role: -1});
|
|
||||||
return sendMessage(res, 2, {message: "User disconnected"});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Request password reset with email
|
|
||||||
exports.resetPass = (req, res) => {
|
|
||||||
return sendError(res, 501, -1, "User.resetPass not Implemented", null);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create and Save a new User
|
|
||||||
exports.create = (req, res) => {
|
|
||||||
// Validate request
|
|
||||||
if (!req.body.email || !req.body.hashPass || !req.body.login) {
|
|
||||||
sendError(res, 400,-1,"Content can not be empty . (email, hashPass and login needed");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
User.exists({email: req.body.email}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
sendError(res, 500,100,err.message || "Some error occurred while checking if the User already exists.");
|
|
||||||
} else{
|
|
||||||
if(docs === null) {
|
|
||||||
let user;
|
|
||||||
let var_role;
|
|
||||||
if(typeof req.body.role !== 'undefined'){
|
|
||||||
switch(req.body.role){
|
|
||||||
case 'admin':
|
|
||||||
var_role = roles.Admin;
|
|
||||||
break;
|
|
||||||
case 'advertiser':
|
|
||||||
var_role = roles.Advertiser;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
var_role = roles.User;
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
var_role = roles.User;
|
|
||||||
}
|
|
||||||
|
|
||||||
user = new User({
|
|
||||||
email: req.body.email,
|
|
||||||
hashPass: req.body.hashPass,
|
|
||||||
login: req.body.login,
|
|
||||||
role: var_role,
|
|
||||||
company: req.body.company ? req.body.company : null,
|
|
||||||
dateOfBirth: req.body.dateOfBirth ? req.body.dateOfBirth : null,
|
|
||||||
gender: req.body.gender ? req.body.gender : null,
|
|
||||||
interests: req.body.interests ? req.body.interests : null,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save User in the database
|
|
||||||
user
|
|
||||||
.save(user)
|
|
||||||
.then(data => {
|
|
||||||
data.hashPass = undefined; // Hiding hashPass on return
|
|
||||||
return sendMessage(res, 4, data)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500,100,err.message || "Some error occurred while creating the User.");
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, 104, err || `Email ${req.body.email} already exists.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Retrieve all Users from the database if at least admin.
|
|
||||||
exports.findAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.Admin);
|
|
||||||
if(token){
|
|
||||||
let query = {};
|
|
||||||
let condition;
|
|
||||||
|
|
||||||
const ids = req.query.userId;
|
|
||||||
condition = ids ? {$in: ids} : undefined;
|
|
||||||
query._id = condition;
|
|
||||||
|
|
||||||
const email = req.query.email;
|
|
||||||
condition = email ? { $regex: new RegExp(email), $options: "i" } : undefined;
|
|
||||||
query.email = condition;
|
|
||||||
|
|
||||||
const login = req.query.login;
|
|
||||||
condition = login ? { $regex: new RegExp(login), $options: "i" } : undefined;
|
|
||||||
query.login = condition;
|
|
||||||
|
|
||||||
const role = req.query.role;
|
|
||||||
condition = role ? role : undefined;
|
|
||||||
query["role.name"] = condition;
|
|
||||||
|
|
||||||
const company = req.query.company;
|
|
||||||
condition = company ? { $regex: new RegExp(company), $options: "i" } : undefined;
|
|
||||||
query.company = condition;
|
|
||||||
|
|
||||||
const dateOfBirth = req.query.dateOfBirth;
|
|
||||||
condition = dateOfBirth ? new Date(dateOfBirth) : undefined;
|
|
||||||
query.dateOfBirth = condition;
|
|
||||||
|
|
||||||
const gender = req.query.gender;
|
|
||||||
condition = gender ? gender : undefined;
|
|
||||||
query.gender = condition;
|
|
||||||
|
|
||||||
const isActive = req.query.isActive;
|
|
||||||
condition = isActive ? isActive : undefined;
|
|
||||||
query.isActive = condition;
|
|
||||||
|
|
||||||
const isAccepted = req.query.isAccepted;
|
|
||||||
if(isAccepted !== 'undefined'){
|
|
||||||
switch (isAccepted){
|
|
||||||
case 'true':
|
|
||||||
condition = true;
|
|
||||||
break;
|
|
||||||
case 'false':
|
|
||||||
condition = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
query["role.isAccepted"] = condition;
|
|
||||||
|
|
||||||
const sort = req.query.sort;
|
|
||||||
if(sort !== 'undefined'){
|
|
||||||
switch (sort){
|
|
||||||
case 'asc':
|
|
||||||
condition = {email: 1};
|
|
||||||
break;
|
|
||||||
case 'desc':
|
|
||||||
condition = {email: -1};
|
|
||||||
break;
|
|
||||||
case 'lastConnexionAsc':
|
|
||||||
condition = {lastConnexion: 1};
|
|
||||||
break;
|
|
||||||
case 'lastConnexionDesc':
|
|
||||||
condition = {lastConnexion: -1};
|
|
||||||
break;
|
|
||||||
case 'createdAtAsc':
|
|
||||||
condition = {createdAt: 1};
|
|
||||||
break;
|
|
||||||
case 'createdAtDesc':
|
|
||||||
condition = {createdAt: -1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtAsc':
|
|
||||||
condition = {updatedAt: 1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtDesc':
|
|
||||||
condition = {updatedAt: -1};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
condition = {email: 1};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const query_sort = {sort: condition};
|
|
||||||
|
|
||||||
// Remove undefined key
|
|
||||||
Object.keys(query).forEach(key => query[key] === undefined ? delete query[key] : {});
|
|
||||||
console.log(query);
|
|
||||||
|
|
||||||
User.find(query, {hashPass: false}, query_sort)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 5, data, token);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || "Some error occurred while retrieving users.", token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find a single User by session id
|
|
||||||
exports.findOne = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
let id = null;
|
|
||||||
if(typeof token.id !== 'undefined' && token.id === req.params.id){
|
|
||||||
id = req.params.id;
|
|
||||||
} else {
|
|
||||||
if(typeof token.role !== 'undefined' &&
|
|
||||||
typeof token.role.permission !== 'undefined' &&
|
|
||||||
typeof token.role.isAccepted !== 'undefined' &&
|
|
||||||
token.role.isAccepted === true &&
|
|
||||||
token.role.permission >= roles.Admin.permission) {
|
|
||||||
id = req.params.id;
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, 106, `User do not have the permission.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
User.findById(id, {hashPass: false})
|
|
||||||
.then(data => {
|
|
||||||
if(data){
|
|
||||||
return sendMessage(res, 6, data, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res,404,105,`User not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || `Some error occurred while finding the User with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update a User by the id in the request
|
|
||||||
exports.update = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
let id = null;
|
|
||||||
if(typeof token.id !== 'undefined' && token.id === req.params.id){
|
|
||||||
id = req.params.id;
|
|
||||||
} else {
|
|
||||||
if(typeof token.role !== 'undefined' &&
|
|
||||||
typeof token.role.permission !== 'undefined' &&
|
|
||||||
typeof token.role.isAccepted !== 'undefined' &&
|
|
||||||
token.role.isAccepted === true &&
|
|
||||||
token.role.permission >= roles.Admin.permission) {
|
|
||||||
id = req.params.id;
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, 106, `User do not have the permission.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
let update = null;
|
|
||||||
if(typeof req.body._id !== 'undefined' || typeof req.body.id !== 'undefined'){
|
|
||||||
return sendError(res, 500, -1, `User do not have the permission to modify id or _id`, token);
|
|
||||||
} else{
|
|
||||||
if(typeof req.body.role !== 'undefined' ||
|
|
||||||
typeof req.body.isActive !== 'undefined' ||
|
|
||||||
typeof req.body.lastConnexion !== 'undefined' ||
|
|
||||||
typeof req.body.createdAt !== 'undefined'||
|
|
||||||
typeof req.body.updatedAt !== 'undefined'){
|
|
||||||
if(typeof token.role !== 'undefined' &&
|
|
||||||
typeof token.role.permission !== 'undefined' &&
|
|
||||||
typeof token.role.isAccepted !== 'undefined' &&
|
|
||||||
token.role.isAccepted === true &&
|
|
||||||
token.role.permission >= roles.Admin.permission) {
|
|
||||||
update = true;
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, 106, `User do not have the permission to modify these keys.`, token);
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(update === true){
|
|
||||||
User.findByIdAndUpdate(id, req.body, {useFindAndModify: false})
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
data.hashPass = undefined;
|
|
||||||
Object.keys(req.body).forEach(key => data[key] = req.body[key]);
|
|
||||||
sendMessage(res, 7, data, token);
|
|
||||||
} else {
|
|
||||||
sendError(res, 404, -1, `User not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
sendError(res, 500, -1, err.message || `Some error occurred while updating the User with id=${id}`, token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Delete a User with the specified id in the request
|
|
||||||
exports.delete = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
let id = null;
|
|
||||||
if(typeof token.id !== 'undefined' && token.id === req.params.id){
|
|
||||||
id = req.params.id;
|
|
||||||
} else {
|
|
||||||
if(typeof token.role !== 'undefined' &&
|
|
||||||
typeof token.role.permission !== 'undefined' &&
|
|
||||||
typeof token.role.isAccepted !== 'undefined' &&
|
|
||||||
token.role.isAccepted === true &&
|
|
||||||
token.role.permission >= roles.Admin.permission) {
|
|
||||||
id = req.params.id;
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, 106, `User do not have the permission.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
User.findByIdAndUpdate(id, {isActive: false}, {useFindAndModify: false})
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
return sendMessage(res, 8, {message: `User ${id} was successfully deleted.`}, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, 105, `User not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, 100, err.message || `Some error occurred while deleting the User with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete all Users from the database except superAdmin
|
|
||||||
exports.deleteAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res, roles.SuperAdmin);
|
|
||||||
if(token) {
|
|
||||||
User.deleteMany({login: {$ne: "superAdmin"}})
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 9, {
|
|
||||||
message: `${data.deletedCount} Users were deleted successfully.`
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, 100, err.message || "Some error occurred while removing all Users.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get all Roles depending on the role of the User
|
|
||||||
exports.roles = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token){
|
|
||||||
return sendMessage(res, 10, roles, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get 1 or multiple ad adapted to the User session id
|
|
||||||
exports.ad = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.query.quantity !== 'undefined'){
|
|
||||||
const id = token.id;
|
|
||||||
const quantity = req.query.quantity;
|
|
||||||
// Interests from the user and from last 20 videos viewed if no ad matches -> find x ad from these interests + add date view to the ad
|
|
||||||
let interests = [];
|
|
||||||
const maxInterests = 20;
|
|
||||||
let limit = maxInterests;
|
|
||||||
User.findById(id, {_id: false, interests: true})
|
|
||||||
.then(data => {
|
|
||||||
if(typeof data.interests !== 'undefined' && data.interests !== null){
|
|
||||||
interests = interests.concat(data.interests);
|
|
||||||
limit = maxInterests-data.interests.length;
|
|
||||||
}
|
|
||||||
Video.aggregate([
|
|
||||||
{$match: {userId: id}},
|
|
||||||
{$project: {_id: false, interest: true}},
|
|
||||||
{$sort: {watchedDates: -1}},
|
|
||||||
{$limit: limit},
|
|
||||||
{$unwind: '$interest'},
|
|
||||||
{$group: {_id: null, interests: {$push: '$interest'}}}
|
|
||||||
])
|
|
||||||
.then(data => {
|
|
||||||
if(typeof data[0] !== 'undefined' &&
|
|
||||||
typeof data[0].interests !== 'undefined' &&
|
|
||||||
data[0].interests !== [] &&
|
|
||||||
data[0].interests !== null){
|
|
||||||
interests = interests.concat(data[0].interests);
|
|
||||||
}
|
|
||||||
let match, pick;
|
|
||||||
if(interests.length > 0){
|
|
||||||
match = {$match: {isVisible: true, isActive: true, interests: {$elemMatch: {interest: {$in: interests}}}}};
|
|
||||||
pick = {$limit: parseInt(quantity, 10)}
|
|
||||||
} else {
|
|
||||||
match = {$match: {isVisible: true, isActive: true}};
|
|
||||||
pick = {$sample: {size: parseInt(quantity, 10)}};
|
|
||||||
}
|
|
||||||
|
|
||||||
Ad.aggregate([
|
|
||||||
match,
|
|
||||||
pick
|
|
||||||
])
|
|
||||||
.then(data => {
|
|
||||||
if(data.length > 0){
|
|
||||||
let ids = []
|
|
||||||
for(const i in data){ids.push(data[i]._id);}
|
|
||||||
Ad.updateMany({_id: {$in: ids}}, {$push: {views: [new Date()]}})
|
|
||||||
.then(dataUpdate => {
|
|
||||||
if(dataUpdate && dataUpdate.modifiedCount > 0){
|
|
||||||
return sendMessage(res, 11, data, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res,500,101,`Some error occurred while updating ${quantity} ad(s) for the User.`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,101,err.message || `Some error occurred while updating ${quantity} ad(s) for the User.`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Ad.aggregate([{$match: {isVisible: true, isActive: true}}, {$sample: {size: parseInt(quantity, 10)}}])
|
|
||||||
.then(data => {
|
|
||||||
let ids = []
|
|
||||||
for(const i in data){ids.push(data[i]._id);}
|
|
||||||
Ad.updateMany({_id: {$in: ids}}, {$push: {views: [new Date()]}})
|
|
||||||
.then(dataUpdate => {
|
|
||||||
if(dataUpdate && dataUpdate.modifiedCount > 0){
|
|
||||||
return sendMessage(res, 11, data, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res,500,101,`Some error occurred while updating ${quantity} ad(s) for the User.`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,101,err.message || `Some error occurred while updating ${quantity} ad(s) for the User.`, token);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,101,err.message || `Some error occurred while getting ${quantity} ad(s) for the User.`, token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,101,err.message || `Some error occurred while getting ${quantity} ad(s) for the User.`, token);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,102,err.message || `Some error occurred while getting ${quantity} ad(s) for the User.`, token);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || `Some error occurred while getting ${quantity} ad(s) for the User.`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendError(res, 500, -1, `No quantity given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get History
|
|
||||||
exports.history = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token){
|
|
||||||
const id = token.id;
|
|
||||||
|
|
||||||
Video.aggregate([
|
|
||||||
{$match: {userId: id, $expr: {$gt: [{$size: "$watchedDates"}, 0]}}},
|
|
||||||
{$limit: 300},
|
|
||||||
{$project: {
|
|
||||||
videoId: true,
|
|
||||||
source: true,
|
|
||||||
tags: true,
|
|
||||||
interest: true,
|
|
||||||
views: {$size: '$watchedDates'},
|
|
||||||
watchedDate: {$arrayElemAt: ["$watchedDates", -1]},
|
|
||||||
createdAt: true,
|
|
||||||
updatedAt: true
|
|
||||||
}},
|
|
||||||
{$sort: {watchedDate: -1}}])
|
|
||||||
.then(async data => {
|
|
||||||
let yt_results = [];
|
|
||||||
let dm_results = [];
|
|
||||||
let yt_videoIds = "";
|
|
||||||
let dm_videoIds = "";
|
|
||||||
|
|
||||||
for(const i in data) {
|
|
||||||
if(data[i].source === youtube.name) {
|
|
||||||
yt_videoIds = yt_videoIds + data[i].videoId + ",";
|
|
||||||
} else if (data[i].source === dailymotion.name) {
|
|
||||||
dm_videoIds = dm_videoIds + data[i].videoId + ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(yt_videoIds !== ""){
|
|
||||||
const uri = youtube.baseAPIUrl + '/videos' + '?part=snippet&part=statistics&id=' + yt_videoIds.slice(0, -1) + '&key=' + youtube.YOUTUBE_API_KEY;
|
|
||||||
const dataVideos = await asyncRequest(uri, {});
|
|
||||||
if (dataVideos.response.statusCode === 200 && dataVideos.body.items.length > 0) {
|
|
||||||
yt_results = dataVideos.body.items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dm_videoIds !== ""){
|
|
||||||
const uri = dailymotion.baseAPIUrl + '/videos?ids='+dm_videoIds.slice(0, -1)+'&fields=thumbnail_480_url%2Ctitle%2Cid';
|
|
||||||
const data = await asyncRequest(uri, {});
|
|
||||||
const response = data.response;
|
|
||||||
const jsonBody = data.body;
|
|
||||||
if(response.statusCode === 200){
|
|
||||||
dm_results = jsonBody.list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(const i in data) {
|
|
||||||
if(data[i].source === youtube.name) {
|
|
||||||
const obj = yt_results.filter(obj => obj.id === data[i].videoId);
|
|
||||||
data[i].imageUrl = obj[0].snippet.thumbnails.medium.url ? obj[0].snippet.thumbnails.medium.url : null;
|
|
||||||
data[i].title = obj[0].snippet.title ? obj[0].snippet.title : null;
|
|
||||||
} else if (data[i].source === dailymotion.name) {
|
|
||||||
const obj = dm_results.filter(obj => obj.id === data[i].videoId);
|
|
||||||
data[i].imageUrl = obj[0].thumbnail_480_url ? obj[0].thumbnail_480_url : null;
|
|
||||||
data[i].title = obj[0].title ? obj[0].title : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sendMessage(res, 12, data, token)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || "Some error occurred while getting the User history.", token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,473 +0,0 @@
|
||||||
const db = require("../models/mongodb.model");
|
|
||||||
const request = require('request');
|
|
||||||
const {sendError, sendMessage} = require ("../config/response.config");
|
|
||||||
const {checkLogin} = require("../config/sessionJWT.config");
|
|
||||||
const {youtube, dailymotion} = require("../config/host.config");
|
|
||||||
const {asyncRequest, asyncInterest} = require("../config/functions.config");
|
|
||||||
const ObjectId = require('mongoose').Types.ObjectId;
|
|
||||||
const Video = db.videos;
|
|
||||||
|
|
||||||
|
|
||||||
// Search Videos
|
|
||||||
exports.search = async (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.query.q !== 'undefined'){
|
|
||||||
const query = req.query.q;
|
|
||||||
const maxResults = req.query.maxResults ? req.query.maxResults : 45;
|
|
||||||
const pageToken = req.query.pageToken ? req.query.pageToken : undefined;
|
|
||||||
let sources;
|
|
||||||
if(typeof req.query.sources !== 'undefined' && req.query.sources !== ''){
|
|
||||||
sources = req.query.sources.split(',');
|
|
||||||
} else {
|
|
||||||
sources = ["yt", "dm"];
|
|
||||||
}
|
|
||||||
let yt_results = [];
|
|
||||||
let dm_results = [];
|
|
||||||
for(const i in sources){
|
|
||||||
if(sources[i] === youtube.shortname){
|
|
||||||
if(youtube.YOUTUBE_API_KEY !== 'undefined' && youtube.YOUTUBE_API_KEY !== ''){
|
|
||||||
let uri;
|
|
||||||
if(query !== ''){
|
|
||||||
if(typeof pageToken !== 'undefined'){
|
|
||||||
uri = youtube.baseAPIUrl+'/search'+'?part=snippet&maxResults='+maxResults+'&q='+query+'&pageToken='+pageToken+'&key='+youtube.YOUTUBE_API_KEY;
|
|
||||||
} else{
|
|
||||||
uri = youtube.baseAPIUrl+'/search'+'?part=snippet&maxResults='+maxResults+'&q='+query+'&key='+youtube.YOUTUBE_API_KEY;
|
|
||||||
}
|
|
||||||
const dataIds = await asyncRequest(uri, {});
|
|
||||||
if(dataIds.response.statusCode === 200 && dataIds.body.items.length > 0){
|
|
||||||
let yt_videoIds = "";
|
|
||||||
dataIds.body.items.forEach(item => yt_videoIds = yt_videoIds+item.id.videoId+",");
|
|
||||||
uri = youtube.baseAPIUrl+'/videos'+'?part=snippet&part=statistics&id='+yt_videoIds.slice(0, -1)+'&key='+youtube.YOUTUBE_API_KEY;
|
|
||||||
const dataVideos = await asyncRequest(uri, {});
|
|
||||||
if(dataVideos.response.statusCode === 200 && dataVideos.body.items.length > 0){
|
|
||||||
yt_results = dataVideos.body.items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uri = youtube.baseAPIUrl+'/videos'+'?part=snippet&part=statistics&chart=mostPopular&maxResults='+maxResults+'&key='+youtube.YOUTUBE_API_KEY;
|
|
||||||
const dataVideos = await asyncRequest(uri, {});
|
|
||||||
if(dataVideos.response.statusCode === 200 && dataVideos.body.items.length > 0){
|
|
||||||
yt_results = dataVideos.body.items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, `Error Env Variable DAILYMOTION_API_KEY missing, please contact the admin.`, token);
|
|
||||||
}
|
|
||||||
} else if(sources[i] === dailymotion.shortname){
|
|
||||||
if(dailymotion.DAILYMOTION_API_KEY !== 'undefined' && dailymotion.DAILYMOTION_API_KEY !== '') {
|
|
||||||
let uri;
|
|
||||||
if(query !== ''){
|
|
||||||
uri = dailymotion.baseAPIUrl + '/videos?limit='+maxResults+'&search='+query+'&fields=created_time%2Cdescription%2Cthumbnail_480_url%2Clikes_total%2Ctitle%2Cid%2Cembed_url%2Cviews_total%2Cowner.username%2Cowner.id%2Cchannel.name';
|
|
||||||
} else {
|
|
||||||
uri = dailymotion.baseAPIUrl + '/videos?limit='+maxResults+'&sort=trending&fields=created_time%2Cdescription%2Cthumbnail_480_url%2Clikes_total%2Ctitle%2Cid%2Cembed_url%2Cviews_total%2Cowner.username%2Cowner.id%2Cchannel.name';
|
|
||||||
}
|
|
||||||
const data = await asyncRequest(uri, {});
|
|
||||||
const response = data.response;
|
|
||||||
const jsonBody = data.body;
|
|
||||||
if(response.statusCode === 200){
|
|
||||||
dm_results = jsonBody.list;
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, `Error Env Variable DAILYMOTION_API_KEY missing, please contact the admin.`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let results = [];
|
|
||||||
for(let i = 0; i < Math.max(dm_results.length, yt_results.length); i++){
|
|
||||||
|
|
||||||
// Youtube
|
|
||||||
if(yt_results.length > i){
|
|
||||||
const yt_data = {
|
|
||||||
videoId: yt_results[i].id,
|
|
||||||
source: youtube.name,
|
|
||||||
imageUrl: yt_results[i].snippet.thumbnails.medium.url ? yt_results[i].snippet.thumbnails.medium.url : null,
|
|
||||||
title: yt_results[i].snippet.title ? yt_results[i].snippet.title : null,
|
|
||||||
channelTitle: yt_results[i].snippet.channelTitle ? yt_results[i].snippet.channelTitle : null,
|
|
||||||
channelUrl: youtube.baseChannelUrl+yt_results[i].snippet.channelId ? yt_results[i].snippet.channelId : null,
|
|
||||||
description: yt_results[i].snippet.description ? yt_results[i].snippet.description : null,
|
|
||||||
embedUrl: 'https://www.youtube.com/embed/'+yt_results[i].id,
|
|
||||||
interest: await asyncInterest(yt_results[i].snippet.categoryId, youtube.name),
|
|
||||||
views: yt_results[i].statistics.viewCount ? parseInt(yt_results[i].statistics.viewCount) : null,
|
|
||||||
likes: yt_results[i].statistics.likeCount ? parseInt(yt_results[i].statistics.likeCount) : null,
|
|
||||||
dislikes: yt_results[i].statistics.dislikeCount ? parseInt(yt_results[i].statistics.dislikeCount) : null,
|
|
||||||
publishedAt: yt_results[i].snippet.publishedAt ? yt_results[i].snippet.publishedAt : null
|
|
||||||
};
|
|
||||||
results.push(yt_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dailymotion
|
|
||||||
if(dm_results.length > i) {
|
|
||||||
const channelTitle = dm_results[i]['owner.username'] ? dm_results[i]['owner.username'] : null;
|
|
||||||
const dm_data = {
|
|
||||||
videoId: dm_results[i].id ? dm_results[i].id : null,
|
|
||||||
source: dailymotion.name,
|
|
||||||
imageUrl: dm_results[i].thumbnail_480_url ? dm_results[i].thumbnail_480_url : null,
|
|
||||||
title: dm_results[i].title ? dm_results[i].title : null,
|
|
||||||
channelTitle: channelTitle.charAt(0).toUpperCase() + channelTitle.slice(1),
|
|
||||||
channelUrl: dailymotion.baseChannelUrl + channelTitle,
|
|
||||||
description: dm_results[i].description ? dm_results[i].description : null,
|
|
||||||
embedUrl: dm_results[i].embed_url ? dm_results[i].embed_url : null,
|
|
||||||
interest: await asyncInterest(dm_results[i]['channel.name'], dailymotion.name),
|
|
||||||
views: dm_results[i].views_total ? parseInt(dm_results[i].views_total) : null,
|
|
||||||
likes: dm_results[i].likes_total ? parseInt(dm_results[i].likes_total) : null,
|
|
||||||
dislikes: null,
|
|
||||||
publishedAt: dm_results[i].created_time ? new Date(dm_results[i].created_time * 1000) : null
|
|
||||||
};
|
|
||||||
results.push(dm_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sendMessage(res, 31, results, token);
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, `No q given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get Video with id of source
|
|
||||||
exports.get = (req, res) => {
|
|
||||||
if(typeof req.query.source !== 'undefined' && typeof req.params.id !== 'undefined'){
|
|
||||||
const source = req.query.source;
|
|
||||||
const id = req.params.id;
|
|
||||||
if(source === youtube.shortname){
|
|
||||||
if(youtube.YOUTUBE_API_KEY !== 'undefined' && youtube.YOUTUBE_API_KEY !== ''){
|
|
||||||
const uri = youtube.baseAPIUrl+'/videos'+'?part=snippet&part=statistics&id='+id+'&key='+youtube.YOUTUBE_API_KEY;
|
|
||||||
request(uri,{},async function (error, response, body){
|
|
||||||
if(typeof body !== 'undefined'){
|
|
||||||
const jsonBody = JSON.parse(body);
|
|
||||||
if(jsonBody.items.length !== 0 &&
|
|
||||||
typeof jsonBody.items[0] !== 'undefined' &&
|
|
||||||
typeof jsonBody.items[0].id !== 'undefined' &&
|
|
||||||
jsonBody.items[0].id === id){
|
|
||||||
const imageUrl = jsonBody.items[0].snippet.thumbnails.standard.url ? jsonBody.items[0].snippet.thumbnails.standard.url : null;
|
|
||||||
const title = jsonBody.items[0].snippet.title ? jsonBody.items[0].snippet.title : null;
|
|
||||||
const channelId = jsonBody.items[0].snippet.channelId ? jsonBody.items[0].snippet.channelId : null;
|
|
||||||
const channelTitle = jsonBody.items[0].snippet.channelTitle ? jsonBody.items[0].snippet.channelTitle : null;
|
|
||||||
const description = jsonBody.items[0].snippet.description ? jsonBody.items[0].snippet.description : null;
|
|
||||||
//const embedUrl = jsonBody.embed_url ? jsonBody.embed_url : null;
|
|
||||||
const publishedAt = jsonBody.items[0].snippet.publishedAt ? jsonBody.items[0].snippet.publishedAt : null;
|
|
||||||
const interest = jsonBody.items[0].snippet.categoryId ? await asyncInterest(jsonBody.items[0].snippet.categoryId, youtube.name): null;
|
|
||||||
const views = jsonBody.items[0].statistics.viewCount ? parseInt(jsonBody.items[0].statistics.viewCount) : null;
|
|
||||||
const likes = jsonBody.items[0].statistics.likeCount ? parseInt(jsonBody.items[0].statistics.likeCount) : null;
|
|
||||||
const dislikes = jsonBody.items[0].statistics.dislikeCount ? parseInt(jsonBody.items[0].statistics.dislikeCount) : null;
|
|
||||||
const data = {
|
|
||||||
videoId: id,
|
|
||||||
source: youtube.name,
|
|
||||||
imageUrl: imageUrl,
|
|
||||||
title: title,
|
|
||||||
channelTitle: channelTitle,
|
|
||||||
channelUrl: youtube.baseChannelUrl+channelId,
|
|
||||||
description: description,
|
|
||||||
embedUrl: 'https://www.youtube.com/embed/'+id,
|
|
||||||
interest: interest,
|
|
||||||
views: views,
|
|
||||||
likes: likes,
|
|
||||||
dislikes: dislikes,
|
|
||||||
publishedAt: publishedAt
|
|
||||||
};
|
|
||||||
return sendMessage(res, 32, data);
|
|
||||||
} else{
|
|
||||||
return sendError(res, 404, -1, `No result`);
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, `Error Env Variable YOUTUBE_API_KEY missing, please contact the admin.`);
|
|
||||||
}
|
|
||||||
} else if(source === dailymotion.shortname){
|
|
||||||
if(dailymotion.DAILYMOTION_API_KEY !== 'undefined' && dailymotion.DAILYMOTION_API_KEY !== ''){
|
|
||||||
const uri = dailymotion.baseAPIUrl+'/video/'+id+'?fields=created_time%2Cdescription%2Cthumbnail_480_url%2Clikes_total%2Ctitle%2Cid%2Cembed_url%2Cviews_total%2Cowner.username%2Cowner.id%2Cchannel.name';
|
|
||||||
request(uri,{},async function (error, response, body) {
|
|
||||||
if (typeof body !== 'undefined') {
|
|
||||||
const jsonBody = JSON.parse(body);
|
|
||||||
if(response.statusCode === 200 &&
|
|
||||||
typeof jsonBody.id !== 'undefined' &&
|
|
||||||
jsonBody.id === id){
|
|
||||||
const imageUrl = jsonBody.thumbnail_480_url ? jsonBody.thumbnail_480_url : null;
|
|
||||||
const title = jsonBody.title ? jsonBody.title : null;
|
|
||||||
//const channelId = jsonBody['owner.id'] ? jsonBody['owner.id'] : null;
|
|
||||||
const channelTitle = jsonBody['owner.username'] ? jsonBody['owner.username'] : null;
|
|
||||||
const description = jsonBody.description ? jsonBody.description : null;
|
|
||||||
const embedUrl = jsonBody.embed_url ? jsonBody.embed_url : null;
|
|
||||||
const publishedAt = jsonBody.created_time ? new Date(jsonBody.created_time * 1000) : null;
|
|
||||||
const interest = jsonBody['channel.name'] ? await asyncInterest(jsonBody['channel.name'], dailymotion.name) : null;
|
|
||||||
const views = jsonBody.views_total ? parseInt(jsonBody.views_total) : null;
|
|
||||||
const likes = jsonBody.likes_total ? parseInt(jsonBody.likes_total) : null;
|
|
||||||
const dislikes = null;
|
|
||||||
const data = {
|
|
||||||
videoId: id,
|
|
||||||
source: dailymotion.name,
|
|
||||||
imageUrl: imageUrl,
|
|
||||||
title: title,
|
|
||||||
channelTitle: channelTitle.charAt(0).toUpperCase() + channelTitle.slice(1),
|
|
||||||
channelUrl: dailymotion.baseChannelUrl+channelTitle,
|
|
||||||
description: description,
|
|
||||||
embedUrl: embedUrl,
|
|
||||||
interest: interest,
|
|
||||||
views: views,
|
|
||||||
likes: likes,
|
|
||||||
dislikes: dislikes,
|
|
||||||
publishedAt: publishedAt
|
|
||||||
};
|
|
||||||
return sendMessage(res, 32, data);
|
|
||||||
} else{
|
|
||||||
return sendError(res, 404, -1, jsonBody.error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, `Error Env Variable DAILYMOTION_API_KEY missing, please contact the admin.`);
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, `Wrong source name`);
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
return sendError(res, 500, -1, `No source or/and id given`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a new Video
|
|
||||||
exports.create = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token &&
|
|
||||||
typeof req.body.source !== 'undefined' &&
|
|
||||||
typeof req.body.interest !== 'undefined' &&
|
|
||||||
typeof req.params.id !== 'undefined'){
|
|
||||||
const id = req.params.id;
|
|
||||||
Video.exists({userId: token.id, videoId: id, source: req.body.source, isActive: true}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
sendError(res, 500,100,err.message || "Some error occurred while checking if the Video already exists.", token);
|
|
||||||
} else{
|
|
||||||
if(docs === null) {
|
|
||||||
let video;
|
|
||||||
|
|
||||||
video = new Video({
|
|
||||||
userId: token.id,
|
|
||||||
videoId: id,
|
|
||||||
source: req.body.source,
|
|
||||||
interest: req.body.interest,
|
|
||||||
watchedDates: [new Date()]
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save Video in the database
|
|
||||||
video
|
|
||||||
.save(video)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 33, data, token)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500,100,err.message || "Some error occurred while creating the Video.", token);
|
|
||||||
});
|
|
||||||
} else{
|
|
||||||
const id = docs._id.toString();
|
|
||||||
Video.findByIdAndUpdate(id, {$push: {watchedDates: [new Date()]}}, {useFindAndModify: false, new: true})
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
return sendMessage(res, 33, data, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, 105, `Video not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, 100, err.message || `Some error occurred while updating the Video with id=${id}`, token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No source or interest or id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Retrieve all Videos
|
|
||||||
exports.findAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token){
|
|
||||||
let query = {};
|
|
||||||
let condition;
|
|
||||||
|
|
||||||
const userId = req.query.userId;
|
|
||||||
condition = userId ? userId : undefined;
|
|
||||||
query.userId = condition;
|
|
||||||
|
|
||||||
const videoId = req.query.videoId;
|
|
||||||
condition = videoId ? videoId : undefined;
|
|
||||||
query.videoId = condition;
|
|
||||||
|
|
||||||
const source = req.query.source;
|
|
||||||
condition = source ? source : undefined;
|
|
||||||
query.source = condition;
|
|
||||||
|
|
||||||
const interests = req.query.interests;
|
|
||||||
condition = interests ? {$in: interests} : undefined;
|
|
||||||
query["interests.interest"] = condition
|
|
||||||
|
|
||||||
const isActive = req.query.isActive;
|
|
||||||
condition = isActive ? isActive : undefined;
|
|
||||||
query.isActive = condition;
|
|
||||||
|
|
||||||
const sort = req.query.sort;
|
|
||||||
if(sort !== 'undefined'){
|
|
||||||
switch (sort){
|
|
||||||
case 'asc':
|
|
||||||
condition = {videoId: 1};
|
|
||||||
break;
|
|
||||||
case 'desc':
|
|
||||||
condition = {videoId: -1};
|
|
||||||
break;
|
|
||||||
case 'createdAtAsc':
|
|
||||||
condition = {createdAt: 1};
|
|
||||||
break;
|
|
||||||
case 'createdAtDesc':
|
|
||||||
condition = {createdAt: -1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtAsc':
|
|
||||||
condition = {updatedAt: 1};
|
|
||||||
break;
|
|
||||||
case 'updatedAtDesc':
|
|
||||||
condition = {updatedAt: -1};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
condition = {createdAt: -1};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const query_sort = {sort: condition};
|
|
||||||
|
|
||||||
// Remove undefined key
|
|
||||||
Object.keys(query).forEach(key => query[key] === undefined ? delete query[key] : {});
|
|
||||||
console.log(query);
|
|
||||||
|
|
||||||
Video.find(query, {}, query_sort)
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 34, data, token);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || "Some error occurred while finding the Videos.", token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find single Video with id
|
|
||||||
exports.findOne = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
Video.findById(id, {})
|
|
||||||
.then(data => {
|
|
||||||
if(data){
|
|
||||||
return sendMessage(res, 35, data, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res,404,105,`Video not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res,500,100,err.message || `Some error occurred while finding the Video with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update Video with id
|
|
||||||
exports.update = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(typeof req.body._id !== 'undefined' || typeof req.body.id !== 'undefined'){
|
|
||||||
return sendError(res, 500, -1, `User do not have the permission to modify id or _id`, token);
|
|
||||||
} else{
|
|
||||||
let update = {};
|
|
||||||
let condition;
|
|
||||||
|
|
||||||
const watchedDate = req.body.watchedDate;
|
|
||||||
if(typeof watchedDate !== 'undefined'){
|
|
||||||
if(watchedDate){
|
|
||||||
condition = {watchedDates: [new Date()]}
|
|
||||||
} else {
|
|
||||||
condition = undefined;
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
condition = undefined;
|
|
||||||
}
|
|
||||||
update.$push = condition;
|
|
||||||
|
|
||||||
const watchedDates = req.body.watchedDates ? req.body.watchedDates : undefined;
|
|
||||||
update.watchedDates = watchedDates;
|
|
||||||
|
|
||||||
const isActive = req.body.isActive;
|
|
||||||
if(typeof isActive !== 'undefined'){
|
|
||||||
condition = isActive;
|
|
||||||
} else{
|
|
||||||
condition = undefined;
|
|
||||||
}
|
|
||||||
update.isActive = condition;
|
|
||||||
|
|
||||||
// Remove undefined key
|
|
||||||
Object.keys(update).forEach(key => update[key] === undefined ? delete update[key] : {});
|
|
||||||
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
Video.updateOne({_id: id, userId: token.id, isActive: true}, update)
|
|
||||||
.then(data => {
|
|
||||||
if(data) {
|
|
||||||
return sendMessage(res, 36, update, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, -1, `Video not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, -1, err.message || `Some error occurred while updating the Video with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete Video with id
|
|
||||||
exports.delete = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token && typeof req.params.id !== 'undefined') {
|
|
||||||
const id = req.params.id;
|
|
||||||
if(id && ObjectId.isValid(id)){
|
|
||||||
Video.updateOne({_id: id, userId: token.id, isActive: true}, {isActive: false}, {useFindAndModify: false})
|
|
||||||
.then(data => {
|
|
||||||
if(data.modifiedCount > 0) {
|
|
||||||
return sendMessage(res, 37, {message: `Video ${id} was successfully deleted.`}, token);
|
|
||||||
} else {
|
|
||||||
return sendError(res, 404, 105, `Video not found with id=${id}`, token);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, 100, err.message || `Some error occurred while deleting the Video with id=${id}`, token);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `Error id is not valid`, token);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return sendError(res, 500, -1, `No id given`, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delete all Videos
|
|
||||||
exports.deleteAll = (req, res) => {
|
|
||||||
const token = checkLogin(req, res);
|
|
||||||
if(token) {
|
|
||||||
Video.updateMany({userId: {$eq: token.id}, isActive: true}, {isActive: false})
|
|
||||||
.then(data => {
|
|
||||||
return sendMessage(res, 38, {
|
|
||||||
message: `${data.modifiedCount} Videos were deleted successfully.`,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
return sendError(res, 500, 100, err.message || "Some error occurred while removing all Videos.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
-----BEGIN PUBLIC KEY-----
|
|
||||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtW31Xj62sjbJVBxnn0G2
|
|
||||||
Habc22q7/pFIBdfn8+OsajdNVnmtfRNOsSXZP8sNhXt1QLPSgxZ/wogG0fLXIX2+
|
|
||||||
ewzPgqrwTnr+quJ1DZ6RqOY3G1PGOibgk25aHkIXJ/gTPk1yTT6pjUmKiaGKM8pt
|
|
||||||
M2wGwugCdEH5Wndgby8Jej30v/PPzyPxTSXrIWDeaSMX+jQyFZTGgEdgL7JvjkTj
|
|
||||||
qLtfWKIAcEeO4PzOlRXVvbzBoYphBiZqkbzEeuOjSLPxgy4cQdbqVMlJ/lZt0SBO
|
|
||||||
MLiIUBTufLcJS3ApesiZWWfUCq+pFFdhEABc9qrtVumzhmzWAv2rKVrHRXbguxc/
|
|
||||||
eHKlRjAE4qmnNnTP2fsAuQIPkXVHOPWdXM1IBwnhXVB+XhxEHSANx/2oeKS6fO/e
|
|
||||||
1oNJCiVkHin9gC8vkU9seEN73lNKZ5wPXMqTYUGA65dCY+8li+n/1pveJOJozFk7
|
|
||||||
amkmOAPTi44lBJmxRm88XBHC3TXz6tFqX3phMqFDcQs2D9s3/2UylK0dSH5MSLnb
|
|
||||||
9x24/ykO4RlPRVCC90vwlxzbnb0rfQVlT4dKcE6OIyXw3UsqIqFnXWmm+hnGu4QH
|
|
||||||
Ysr+i1VIhPOs9YdZwlqhzcPTuNcdxmxy9ZfZ8KlLIWbAMbSH+obwm4w+HYTZjspe
|
|
||||||
2MwrKGgzpl4YW7ct/ViqeQMCAwEAAQ==
|
|
||||||
-----END PUBLIC KEY-----
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key -q -N ""
|
|
||||||
openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub
|
|
||||||
#rm .env
|
|
||||||
echo "JWTRS256_PRIVATE_KEY='`cat ./jwtRS256.key | base64 -w 0`'" >> .env
|
|
||||||
echo "JWTRS256_PUBLIC_KEY='`cat ./jwtRS256.key.pub | base64 -w 0`'" >> .env
|
|
||||||
source .env
|
|
||||||
rm jwtRS256.key
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
module.exports = mongoose => {
|
|
||||||
let schema = mongoose.Schema({
|
|
||||||
userId: String,
|
|
||||||
title: String,
|
|
||||||
images: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
url: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
interests: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
comment: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
views: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
isVisible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
isActive: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ timestamps: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
schema.method("toJSON", function() {
|
|
||||||
const { __v, _id, ...object } = this.toObject();
|
|
||||||
object.id = _id;
|
|
||||||
return object;
|
|
||||||
});
|
|
||||||
|
|
||||||
return mongoose.model("ads", schema);
|
|
||||||
};
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
module.exports = mongoose => {
|
|
||||||
let schema = mongoose.Schema({
|
|
||||||
userId: String,
|
|
||||||
videoIds: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
name: String,
|
|
||||||
isActive: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ timestamps: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
schema.method("toJSON", function() {
|
|
||||||
const { __v, _id, ...object } = this.toObject();
|
|
||||||
object.id = _id;
|
|
||||||
return object;
|
|
||||||
});
|
|
||||||
|
|
||||||
return mongoose.model("playlists", schema);
|
|
||||||
};
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
const roles = require("../objects/role.model");
|
|
||||||
|
|
||||||
module.exports = mongoose => {
|
|
||||||
let schema = mongoose.Schema({
|
|
||||||
email: String,
|
|
||||||
hashPass: String, // WARNING: We don't want to send back the hashPass
|
|
||||||
login: String,
|
|
||||||
role: {
|
|
||||||
type: Object,
|
|
||||||
default: roles.User
|
|
||||||
},
|
|
||||||
company: String,
|
|
||||||
profileImageUrl: {
|
|
||||||
type: String,
|
|
||||||
default: "https://www.handiclubnimois.fr/wp-content/uploads/2020/10/blank-profile-picture-973460_1280.png"
|
|
||||||
},
|
|
||||||
dateOfBirth: {
|
|
||||||
type: Date,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
gender: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
interests: {
|
|
||||||
type: Array,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
isActive: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
lastConnexion: {
|
|
||||||
type: Date,
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ timestamps: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
schema.method("toJSON", function() {
|
|
||||||
const { __v, _id, ...object } = this.toObject();
|
|
||||||
object.id = _id;
|
|
||||||
return object;
|
|
||||||
});
|
|
||||||
|
|
||||||
return mongoose.model("users", schema);
|
|
||||||
};
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
module.exports = mongoose => {
|
|
||||||
let schema = mongoose.Schema({
|
|
||||||
userId: String,
|
|
||||||
videoId: String,
|
|
||||||
source: String,
|
|
||||||
interest: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
watchedDates: {
|
|
||||||
type: Array,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
isActive: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ timestamps: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
schema.method("toJSON", function() {
|
|
||||||
const { __v, _id, ...object } = this.toObject();
|
|
||||||
object.id = _id;
|
|
||||||
return object;
|
|
||||||
});
|
|
||||||
|
|
||||||
return mongoose.model("videos", schema);
|
|
||||||
};
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
const dbConfig = require("../config/mongodb.config");
|
|
||||||
const mongoose = require("mongoose");
|
|
||||||
mongoose.Promise = global.Promise;
|
|
||||||
|
|
||||||
const db = {};
|
|
||||||
db.mongoose = mongoose;
|
|
||||||
|
|
||||||
if(typeof process.env.NODE_ENV !== 'undefined' && process.env.NODE_ENV === 'production'){
|
|
||||||
db.url = dbConfig.prodUrl;
|
|
||||||
} else {
|
|
||||||
db.url = dbConfig.devUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
db.users = require("./database/users.model")(mongoose);
|
|
||||||
db.playlists = require("./database/playlists.model")(mongoose);
|
|
||||||
db.videos = require("./database/videos.model")(mongoose);
|
|
||||||
db.ads = require("./database/ads.model")(mongoose);
|
|
||||||
|
|
||||||
module.exports = db;
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
class Image {
|
|
||||||
constructor(base64, url, description, type){
|
|
||||||
this.base64 = base64;
|
|
||||||
this.url = url;
|
|
||||||
this.description = description;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Image;
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
User: {
|
|
||||||
name: "user",
|
|
||||||
permission: 0,
|
|
||||||
isAccepted: true
|
|
||||||
},
|
|
||||||
Advertiser: {
|
|
||||||
name: "advertiser",
|
|
||||||
permission: 5,
|
|
||||||
isAccepted: false
|
|
||||||
},
|
|
||||||
Admin: {
|
|
||||||
name: "admin",
|
|
||||||
permission: 10,
|
|
||||||
isAccepted: false
|
|
||||||
},
|
|
||||||
SuperAdmin: {
|
|
||||||
name: "superAdmin",
|
|
||||||
permission: 1000,
|
|
||||||
isAccepted: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
const {youtube, dailymotion} = require('../../config/host.config');
|
|
||||||
module.exports = [
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
interest: "Actualités",
|
|
||||||
categories: [
|
|
||||||
{id: "news", name: "News", source: dailymotion.name},
|
|
||||||
{id: "25", name: "News & Politics", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
interest: "Animaux",
|
|
||||||
categories: [
|
|
||||||
{id: "animals", name: "animaux", source: dailymotion.name},
|
|
||||||
{id: "15", name: "Pets & Animals", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
interest: "Arts",
|
|
||||||
categories: [
|
|
||||||
{id: "creation", name: "Art", source: dailymotion.name},
|
|
||||||
{id: "", name: "", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
interest: "Autos",
|
|
||||||
categories: [
|
|
||||||
{id: "auto", name: "Auto-Moto", source: dailymotion.name},
|
|
||||||
{id: "2", name: "Autos & Vehicles", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
interest: "Divertissements",
|
|
||||||
categories: [
|
|
||||||
{id: "tv", name: "TV", source: dailymotion.name},
|
|
||||||
{id: "fun", name: "Humour & Divertissement", source: dailymotion.name},
|
|
||||||
{id: "webcam", name: "Webcam", source: dailymotion.name},
|
|
||||||
{id: "23", name: "Comedy", source: youtube.name},
|
|
||||||
{id: "24", name: "Entertainment", source: youtube.name},
|
|
||||||
{id: "43", name: "Shows", source: youtube.name}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
interest: "Éducation",
|
|
||||||
categories: [
|
|
||||||
{id: "school", name: "Éducation", source: dailymotion.name},
|
|
||||||
{id: "27", name: "Education", source: youtube.name}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
interest: "Événements",
|
|
||||||
categories: [
|
|
||||||
{id: "", name: "", source: dailymotion.name},
|
|
||||||
{id: "19", name: "Travel & Events", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
interest: "Films",
|
|
||||||
categories: [
|
|
||||||
{id: "shortfilms", name: "Cinéma", source: dailymotion.name},
|
|
||||||
{id: "1", name: "Film & Animation", source: youtube.name},
|
|
||||||
{id: "18", name: "Short Movies", source: youtube.name},
|
|
||||||
{id: "30", name: "Movies", source: youtube.name},
|
|
||||||
{id: "31", name: "Anime/Animation", source: youtube.name},
|
|
||||||
{id: "32", name: "Action/Adventure", source: youtube.name},
|
|
||||||
{id: "33", name: "Comedy", source: youtube.name},
|
|
||||||
{id: "35", name: "Documentary", source: youtube.name},
|
|
||||||
{id: "36", name: "Drama", source: youtube.name},
|
|
||||||
{id: "39", name: "Horror", source: youtube.name},
|
|
||||||
{id: "40", name: "Sci-Fi/Fantasy", source: youtube.name},
|
|
||||||
{id: "41", name: "Thriller", source: youtube.name},
|
|
||||||
{id: "42", name: "Shorts", source: youtube.name},
|
|
||||||
{id: "44", name: "Trailers", source: youtube.name}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 8,
|
|
||||||
interest: "Jeux vidéo",
|
|
||||||
categories: [
|
|
||||||
{id: "videogames", name: "Jeux vidéo", source: dailymotion.name},
|
|
||||||
{id: "20", name: "Gaming", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 9,
|
|
||||||
interest: "Kids",
|
|
||||||
categories: [
|
|
||||||
{id: "kids", name: "Kids", source: dailymotion.name},
|
|
||||||
{id: "", name: "", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10,
|
|
||||||
interest: "Modes de vie",
|
|
||||||
categories: [
|
|
||||||
{id: "lifestyle", name: "Lifestyle & Tutoriels", source: dailymotion.name},
|
|
||||||
{id: "26", name: "Howto & Style", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 11,
|
|
||||||
interest: "Musiques",
|
|
||||||
categories: [
|
|
||||||
{id: "music", name: "Musique", source: dailymotion.name},
|
|
||||||
{id: "10", name: "Music", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 12,
|
|
||||||
interest: "People",
|
|
||||||
categories: [
|
|
||||||
{id: "people", name: "Amis & Famille", source: dailymotion.name},
|
|
||||||
{id: "21", name: "Videoblogging", source: youtube.name},
|
|
||||||
{id: "22", name: "People & Blogs", source: youtube.name},
|
|
||||||
{id: "37", name: "Family", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 13,
|
|
||||||
interest: "Science et Technologie",
|
|
||||||
categories: [
|
|
||||||
{id: "tech", name: "Tech", source: dailymotion.name},
|
|
||||||
{id: "28", name: "Science & Technology", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 14,
|
|
||||||
interest: "Sports",
|
|
||||||
categories: [
|
|
||||||
{id: "sport", name: "Sport", source: dailymotion.name},
|
|
||||||
{id: "17", name: "Sports", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 15,
|
|
||||||
interest: "Voyages",
|
|
||||||
categories: [
|
|
||||||
{id: "travel", name: "Voyages", source: dailymotion.name},
|
|
||||||
{id: "38", name: "Foreign", source: youtube.name},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 16,
|
|
||||||
interest: "Autres",
|
|
||||||
categories: [
|
|
||||||
{id: "29", name: "Nonprofits & Activism", source: youtube.name},
|
|
||||||
{id: "33", name: "Classics", source: youtube.name}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
const ads = require("../controllers/ad.controller");
|
|
||||||
module.exports = app => {
|
|
||||||
let router = require("express").Router();
|
|
||||||
|
|
||||||
// Create a new Ad
|
|
||||||
router.post("/ad/create", ads.create);
|
|
||||||
|
|
||||||
// Retrieve all Ad from id if admin or session id
|
|
||||||
router.get("/ad/findAll", ads.findAll);
|
|
||||||
|
|
||||||
// Find single Ad from id if admin or session id
|
|
||||||
router.get("/ad/findOne/:id", ads.findOne);
|
|
||||||
|
|
||||||
// Update a Ad with ad id
|
|
||||||
router.put("/ad/update/:id", ads.update);
|
|
||||||
|
|
||||||
// Delete a Ad with ad id
|
|
||||||
router.delete("/ad/delete/:id", ads.delete);
|
|
||||||
|
|
||||||
// Delete all Ad from id if admin or session id
|
|
||||||
router.delete("/ad/deleteAll", ads.deleteAll);
|
|
||||||
|
|
||||||
app.use('/api', router);
|
|
||||||
};
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
const misc = require("../controllers/misc.controller");
|
|
||||||
module.exports = app => {
|
|
||||||
let router = require("express").Router();
|
|
||||||
|
|
||||||
// Get all interests available
|
|
||||||
router.get("/misc/getInterests", misc.getInterests);
|
|
||||||
|
|
||||||
app.use('/api', router);
|
|
||||||
};
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
const playlists = require("../controllers/playlist.controller");
|
|
||||||
module.exports = app => {
|
|
||||||
let router = require("express").Router();
|
|
||||||
|
|
||||||
// Create a new Playlist
|
|
||||||
router.post("/playlist/create", playlists.create);
|
|
||||||
|
|
||||||
// Retrieve all Playlist from id if admin or session id
|
|
||||||
router.get("/playlist/findAll", playlists.findAll);
|
|
||||||
|
|
||||||
// Find single Playlist from id if admin or session id
|
|
||||||
router.get("/playlist/findOne/:id", playlists.findOne);
|
|
||||||
|
|
||||||
// Update a Playlist with playlist id
|
|
||||||
router.put("/playlist/update/:id", playlists.update);
|
|
||||||
|
|
||||||
// Delete a Playlist with playlist id
|
|
||||||
router.delete("/playlist/delete/:id", playlists.delete);
|
|
||||||
|
|
||||||
// Delete all Playlists from id if admin or session id
|
|
||||||
router.delete("/playlist/deleteAll", playlists.deleteAll);
|
|
||||||
|
|
||||||
app.use('/api', router);
|
|
||||||
};
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
const users = require("../controllers/user.controller");
|
|
||||||
module.exports = app => {
|
|
||||||
let router = require("express").Router();
|
|
||||||
|
|
||||||
// Authenticate a User
|
|
||||||
router.post("/user/auth", users.auth);
|
|
||||||
|
|
||||||
// Logout a User
|
|
||||||
router.delete("/user/logout", users.logout);
|
|
||||||
|
|
||||||
// Request password reset with email
|
|
||||||
router.post("/user/resetPass", users.resetPass);
|
|
||||||
|
|
||||||
// Create and Save a new User
|
|
||||||
router.post("/user/create", users.create);
|
|
||||||
|
|
||||||
// Retrieve all Users if admin
|
|
||||||
router.get("/user/findAll", users.findAll);
|
|
||||||
|
|
||||||
// Find single User from id if admin or session id
|
|
||||||
router.get("/user/findOne/:id", users.findOne);
|
|
||||||
|
|
||||||
// Update a User from id if admin or session id
|
|
||||||
router.put("/user/update/:id", users.update);
|
|
||||||
|
|
||||||
// Delete a User from id if admin or session id
|
|
||||||
router.delete("/user/delete/:id", users.delete);
|
|
||||||
|
|
||||||
// Delete all Users if superAdmin
|
|
||||||
router.delete("/user/deleteAll", users.deleteAll);
|
|
||||||
|
|
||||||
// Get all Roles depending on the User session id
|
|
||||||
router.get("/user/roles", users.roles);
|
|
||||||
|
|
||||||
// Get 1 or multiple ad adapted to the User session id
|
|
||||||
router.get("/user/ad", users.ad);
|
|
||||||
|
|
||||||
// Get History
|
|
||||||
router.get("/user/history", users.history);
|
|
||||||
|
|
||||||
app.use('/api', router);
|
|
||||||
};
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
const videos = require("../controllers/video.controller");
|
|
||||||
module.exports = app => {
|
|
||||||
let router = require("express").Router();
|
|
||||||
|
|
||||||
// Search Videos
|
|
||||||
router.get("/video/search", videos.search);
|
|
||||||
|
|
||||||
// Get Video with id of source
|
|
||||||
router.get("/video/get/:id", videos.get);
|
|
||||||
|
|
||||||
// Create a new Video
|
|
||||||
router.post("/video/create/:id", videos.create);
|
|
||||||
|
|
||||||
// Retrieve all Videos
|
|
||||||
router.get("/video/findAll", videos.findAll);
|
|
||||||
|
|
||||||
// Find single Video with id
|
|
||||||
router.get("/video/findOne/:id", videos.findOne);
|
|
||||||
|
|
||||||
// Update Video with id
|
|
||||||
router.put("/video/update/:id", videos.update);
|
|
||||||
|
|
||||||
// Delete Video with id
|
|
||||||
router.delete("/video/delete/:id", videos.delete);
|
|
||||||
|
|
||||||
// Delete all Videos
|
|
||||||
router.delete("/video/deleteAll", videos.deleteAll);
|
|
||||||
|
|
||||||
app.use('/api', router);
|
|
||||||
};
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
frontend:
|
|
||||||
container_name: frontend
|
|
||||||
build: .
|
|
||||||
command: ng serve --host 0.0.0.0
|
|
||||||
volumes:
|
|
||||||
- ./src:/data/frontend/
|
|
||||||
- ./node_modules:/data/frontend/node_modules
|
|
||||||
ports:
|
|
||||||
- 4200:4200
|
|
||||||
depends_on:
|
|
||||||
- backend
|
|
||||||
links:
|
|
||||||
- backend
|
|
||||||
|
|
||||||
backend:
|
|
||||||
container_name: backend
|
|
||||||
build: ./backend
|
|
||||||
command: node server.js
|
|
||||||
volumes:
|
|
||||||
- ./backend:/data/backend
|
|
||||||
- ./backend/node_modules:/data/backend/node_modules
|
|
||||||
- ./backend/app:/data/backend/app
|
|
||||||
ports:
|
|
||||||
- 3000:3000
|
|
||||||
depends_on:
|
|
||||||
- mongodb
|
|
||||||
links:
|
|
||||||
- mongodb
|
|
||||||
environment:
|
|
||||||
NODE_ENV: development
|
|
||||||
|
|
||||||
mongodb:
|
|
||||||
image: mongo
|
|
||||||
container_name: mongodb
|
|
||||||
volumes:
|
|
||||||
- ./backend/database:/data/db
|
|
||||||
ports:
|
|
||||||
- 27017:27017
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
module.exports = function (config) {
|
module.exports = function (config) {
|
||||||
config.set({
|
config.set({
|
||||||
basePath: '',
|
basePath: 'admin',
|
||||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||||
plugins: [
|
plugins: [
|
||||||
require('karma-jasmine'),
|
require('karma-jasmine'),
|
||||||
|
|
@ -25,7 +25,7 @@ module.exports = function (config) {
|
||||||
suppressAll: true // removes the duplicated traces
|
suppressAll: true // removes the duplicated traces
|
||||||
},
|
},
|
||||||
coverageReporter: {
|
coverageReporter: {
|
||||||
dir: require('path').join(__dirname, './coverage/frontend'),
|
dir: require('path').join(__dirname, './coverage/admin'),
|
||||||
subdir: '.',
|
subdir: '.',
|
||||||
reporters: [
|
reporters: [
|
||||||
{ type: 'html' },
|
{ type: 'html' },
|
||||||
|
|
|
||||||
70
package.json
70
package.json
|
|
@ -1,67 +1,45 @@
|
||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend-admin",
|
||||||
"version": "1.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"dev": "ng serve",
|
"build": "ng build",
|
||||||
"build": "ng build --configuration production",
|
"watch": "ng build --watch --configuration development",
|
||||||
"test": "ng test",
|
"test": "ng test"
|
||||||
"lint": "ng lint",
|
|
||||||
"e2e": "ng e2e"
|
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^12.2.11",
|
"@angular/animations": "~12.2.0",
|
||||||
"@angular/cdk": "^12.2.11",
|
"@angular/cdk": "^13.1.1",
|
||||||
"@angular/cli": "~12.2.11",
|
"@angular/common": "~12.2.0",
|
||||||
"@angular/common": "^12.2.11",
|
"@angular/compiler": "~12.2.0",
|
||||||
"@angular/compiler": "^12.2.11",
|
"@angular/core": "~12.2.0",
|
||||||
"@angular/compiler-cli": "~12.2.11",
|
"@angular/forms": "~12.2.0",
|
||||||
"@angular/core": "^12.2.11",
|
"@angular/material": "^13.1.1",
|
||||||
"@angular/forms": "^12.2.11",
|
"@angular/platform-browser": "~12.2.0",
|
||||||
"@angular/material": "^12.2.11",
|
"@angular/platform-browser-dynamic": "~12.2.0",
|
||||||
"@angular/platform-browser": "^12.2.11",
|
"@angular/router": "~12.2.0",
|
||||||
"@angular/platform-browser-dynamic": "^12.2.11",
|
|
||||||
"@angular/router": "^12.2.11",
|
|
||||||
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
|
|
||||||
"angular-responsive-carousel": "^2.1.2",
|
|
||||||
"body-parser": "^1.19.0",
|
|
||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.1.3",
|
||||||
"chart.js": "^2.9.3",
|
|
||||||
"cookie-parser": "^1.4.5",
|
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^10.0.0",
|
|
||||||
"express": "^4.17.1",
|
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
|
||||||
"mongoose": "^6.0.12",
|
|
||||||
"ng2-charts": "^2.2.3",
|
|
||||||
"popper": "^1.0.1",
|
"popper": "^1.0.1",
|
||||||
"request": "^2.88.2",
|
|
||||||
"rxjs": "~6.6.0",
|
"rxjs": "~6.6.0",
|
||||||
"tslib": "^2.0.0",
|
"tslib": "^2.3.0",
|
||||||
"typescript": "~4.3.5",
|
"zone.js": "~0.11.4"
|
||||||
"zone.js": "~0.11.3"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "~12.2.11",
|
"@angular-devkit/build-angular": "~12.2.10",
|
||||||
"@angular/cli": "~12.2.11",
|
"@angular/cli": "~12.2.10",
|
||||||
"@angular/compiler-cli": "~12.2.11",
|
"@angular/compiler-cli": "~12.2.0",
|
||||||
"@angular/localize": "^12.2.11",
|
"@types/jasmine": "~3.8.0",
|
||||||
"@types/jasmine": "~3.6.0",
|
|
||||||
"@types/node": "^12.11.1",
|
"@types/node": "^12.11.1",
|
||||||
"codelyzer": "^6.0.0",
|
"jasmine-core": "~3.8.0",
|
||||||
"jasmine-core": "~3.6.0",
|
"karma": "~6.3.0",
|
||||||
"jasmine-spec-reporter": "~5.0.0",
|
|
||||||
"karma": "~6.3.5",
|
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
"karma-coverage": "~2.0.3",
|
"karma-coverage": "~2.0.3",
|
||||||
"karma-jasmine": "~4.0.0",
|
"karma-jasmine": "~4.0.0",
|
||||||
"karma-jasmine-html-reporter": "^1.5.0",
|
"karma-jasmine-html-reporter": "~1.7.0",
|
||||||
"protractor": "~7.0.0",
|
|
||||||
"ts-node": "~8.3.0",
|
|
||||||
"tslint": "~6.1.0",
|
|
||||||
"typescript": "~4.3.5"
|
"typescript": "~4.3.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
75
server.js
75
server.js
|
|
@ -3,80 +3,9 @@ const express = require('express');
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = process.env.PORT || 3000;
|
const port = process.env.PORT || 3000;
|
||||||
|
|
||||||
const cookieParser = require('cookie-parser');
|
app.use(express.static(__dirname + '/dist/frontend-admin'));
|
||||||
app.use(cookieParser());
|
|
||||||
|
|
||||||
const bodyParser = require('body-parser');
|
|
||||||
app.use(bodyParser.urlencoded({extended:true}));
|
|
||||||
app.use(bodyParser.json());
|
|
||||||
|
|
||||||
const cors = require('cors');
|
|
||||||
app.use(cors({origin: 'http://127.0.0.1:4200', credentials: true}));
|
|
||||||
|
|
||||||
const db = require("./app-backend/models/mongodb.model");
|
|
||||||
console.log("Db Url: ",db.url);
|
|
||||||
db.mongoose
|
|
||||||
.connect(db.url, {
|
|
||||||
useNewUrlParser: true,
|
|
||||||
useUnifiedTopology: true
|
|
||||||
}, function (err){
|
|
||||||
const admin = new db.mongoose.mongo.Admin(db.mongoose.connection.db);
|
|
||||||
admin.buildInfo(function (err, info) {
|
|
||||||
console.log("MongoDB Version: "+info.version);
|
|
||||||
});
|
|
||||||
if(err){
|
|
||||||
console.log("Cannot connect to the database!", err);
|
|
||||||
process.exit();
|
|
||||||
} else{
|
|
||||||
console.log("Connected to the database!", db.url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
require("./app-backend/routes/user.routes")(app);
|
|
||||||
require("./app-backend/routes/playlist.routes")(app);
|
|
||||||
require("./app-backend/routes/video.routes")(app);
|
|
||||||
require("./app-backend/routes/ad.routes")(app);
|
|
||||||
require("./app-backend/routes/misc.routes")(app);
|
|
||||||
|
|
||||||
const roles = require("./app-backend/models/objects/role.model");
|
|
||||||
const User = db.users;
|
|
||||||
const login = 'superAdmin';
|
|
||||||
const hashPass = 'hashPassSuperAdmin';
|
|
||||||
const mail = 'superAdmin@email.admin';
|
|
||||||
|
|
||||||
User.exists({role: roles.SuperAdmin}, function (err, docs){
|
|
||||||
if(err){
|
|
||||||
console.log("Some error occurred while checking if superAdmin already exists.");
|
|
||||||
} else{
|
|
||||||
if(docs === null){
|
|
||||||
const user = new User({
|
|
||||||
login: login,
|
|
||||||
hashPass: hashPass,
|
|
||||||
email: mail,
|
|
||||||
role: roles.SuperAdmin
|
|
||||||
});
|
|
||||||
user
|
|
||||||
.save(user)
|
|
||||||
.then(data => {
|
|
||||||
data.hashPass = undefined; // Hiding hashPass on return
|
|
||||||
console.log(data);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err.message || "Some error occurred while creating superAdmin.");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log("superAdmin already exist !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/*all', function(req,res) {
|
|
||||||
res.sendFile(path.join(__dirname+ '/dist/index.html'));
|
|
||||||
});
|
|
||||||
|
|
||||||
app.use(express.static(__dirname + '/dist/frontend'));
|
|
||||||
app.get('/*', function(req,res) {
|
app.get('/*', function(req,res) {
|
||||||
res.sendFile(path.join(__dirname+ '/dist/frontend/index.html'));
|
res.sendFile(path.join(__dirname+ '/dist/frontend-admin/index.html'));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(port, '0.0.0.0',() => {
|
app.listen(port, '0.0.0.0',() => {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
<!-- filtre textuelle-->
|
<!-- filtre textuelle-->
|
||||||
<div style="margin: 10px 0px 20px 2%;">
|
<div style="margin: 10px 0px 20px 2%;">
|
||||||
<input class="textFilter" (keyup)="applyFilter($event)" placeholder="Rechercher par mots-clés...">
|
<input class="textFilter" [(ngModel)]="filteredText" (ngModelChange)="onFilter()" placeholder="Rechercher par mots-clés...">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- visible + interests + période -->
|
<!-- visible + interests + période -->
|
||||||
|
|
@ -50,30 +50,30 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- période -->
|
<!-- période -->
|
||||||
<div class="col-6" style="text-align: right;">
|
<div class="col-6" style="text-align: right; font-size: small;">
|
||||||
Période de création:
|
<mat-form-field appearance="fill">
|
||||||
<mat-form-field appearance="fill" style="width: 140px; font-size: small;">
|
<mat-label>Période de date de création</mat-label>
|
||||||
<mat-label>Date de début</mat-label>
|
<mat-date-range-input
|
||||||
<input matInput type="date"
|
[formGroup]="campaignOne"
|
||||||
style="font-size: small; width: 140px;"
|
[rangePicker]="campaignOnePicker">
|
||||||
[ngModel] ="startDate | date:'yyyy-MM-dd'"
|
<input matStartDate placeholder="Start date" formControlName="start" style="font-size: small;">
|
||||||
(ngModelChange)="onNewStartDate($event); onFilter();">
|
<input matEndDate placeholder="End date" formControlName="end" style="font-size: small;">
|
||||||
</mat-form-field>
|
</mat-date-range-input>
|
||||||
-
|
<mat-datepicker-toggle matSuffix [for]="campaignOnePicker"></mat-datepicker-toggle>
|
||||||
<mat-form-field appearance="fill" style="width: 140px; font-size: small;">
|
<mat-date-range-picker #campaignOnePicker></mat-date-range-picker>
|
||||||
<mat-label>Date de fin</mat-label>
|
|
||||||
<input matInput type="date"
|
|
||||||
style="font-size: small; width: 140px;"
|
|
||||||
[ngModel] ="endDate | date:'yyyy-MM-dd'"
|
|
||||||
(ngModelChange)="onNewEndDate($event); onFilter();">
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<button mat-icon-button (click)="onFilter()">
|
||||||
|
<mat-icon>keyboard_tab</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button (click)="onEffacerDate()">
|
||||||
|
<mat-icon>close</mat-icon>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- table -->
|
<!-- table -->
|
||||||
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Advertiser Column -->
|
<!-- company Column -->
|
||||||
<ng-container matColumnDef="company">
|
<ng-container matColumnDef="company">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Entreprise </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Entreprise </th>
|
||||||
<td mat-cell *matCellDef="let advert">
|
<td mat-cell *matCellDef="let advert">
|
||||||
|
|
@ -93,6 +93,14 @@
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- email Column -->
|
||||||
|
<ng-container matColumnDef="email">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
|
||||||
|
<td mat-cell *matCellDef="let advert">
|
||||||
|
{{advert.email}}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<!-- Tags Column -->
|
<!-- Tags Column -->
|
||||||
<ng-container matColumnDef="interests">
|
<ng-container matColumnDef="interests">
|
||||||
<th mat-header-cell *matHeaderCellDef> Sujets </th>
|
<th mat-header-cell *matHeaderCellDef> Sujets </th>
|
||||||
|
|
@ -153,9 +161,6 @@
|
||||||
<!-- Directives -->
|
<!-- Directives -->
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
<tr class="mat-row" *matNoDataRow>
|
|
||||||
<td class="mat-cell" colspan="4"> Aucune vidéo ne correspond au filtre: "{{input.value}}" </td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<div style="width: 94%; margin: auto auto">
|
<div style="width: 94%; margin: auto auto">
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ td {
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 30%;
|
//width: 30%;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import {AfterViewInit, Component, ViewChild} from '@angular/core';
|
import {AfterViewInit, Component, ViewChild} from '@angular/core';
|
||||||
import {MatSort} from "@angular/material/sort";
|
import {MatSort} from "@angular/material/sort";
|
||||||
import {MatPaginator} from "@angular/material/paginator";
|
import {MatPaginator} from "@angular/material/paginator";
|
||||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
import {Advert} from "../../../utils/interfaces/advert";
|
|
||||||
import {PopupDeleteAdAdminComponent} from "../popup-delete-ad-admin/popup-delete-ad-admin.component";
|
import {PopupDeleteAdAdminComponent} from "../popup-delete-ad-admin/popup-delete-ad-admin.component";
|
||||||
import {PopupVisualizeImagesAdminComponent} from "../popup-visualize-images-admin/popup-visualize-images-admin.component";
|
import {PopupVisualizeImagesAdminComponent} from "../popup-visualize-images-admin/popup-visualize-images-admin.component";
|
||||||
import {FormControl} from "@angular/forms";
|
import {FormControl, FormGroup} from "@angular/forms";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
import {HttpParams} from "@angular/common/http";
|
import {HttpParams} from "@angular/common/http";
|
||||||
|
import {ThemeService} from "../../../utils/theme/theme.service";
|
||||||
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
|
import {DatePipe} from "@angular/common";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@ export interface AdvertWithCountViewsAndCompany {
|
||||||
id: string,
|
id: string,
|
||||||
userId: string,
|
userId: string,
|
||||||
company: string,
|
company: string,
|
||||||
|
email: string,
|
||||||
title: string,
|
title: string,
|
||||||
url: string,
|
url: string,
|
||||||
images: {
|
images: {
|
||||||
|
|
@ -35,7 +36,6 @@ export interface AdvertWithCountViewsAndCompany {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-page-ad-list-admin',
|
selector: 'app-page-ad-list-admin',
|
||||||
templateUrl: './page-ad-list-admin.component.html',
|
templateUrl: './page-ad-list-admin.component.html',
|
||||||
|
|
@ -45,15 +45,18 @@ export class PageAdListAdminComponent implements AfterViewInit
|
||||||
{
|
{
|
||||||
tabAdvertWithCountViews: AdvertWithCountViewsAndCompany[] = [];
|
tabAdvertWithCountViews: AdvertWithCountViewsAndCompany[] = [];
|
||||||
tabAdvertiser: any[];
|
tabAdvertiser: any[];
|
||||||
displayedColumns: string[] = [ 'title', 'company', 'interests', 'createdAt', 'updatedAt', 'countViews', 'isVisible', 'actions' ];
|
displayedColumns: string[] = [ 'title', 'company', 'email', 'interests', 'createdAt', 'updatedAt', 'countViews', 'isVisible', 'actions' ];
|
||||||
dataSource ;
|
dataSource ;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
|
|
||||||
|
filteredText: string = "" ;
|
||||||
visible: boolean = true;
|
visible: boolean = true;
|
||||||
noVisible: boolean = true;
|
noVisible: boolean = true;
|
||||||
startDate: Date = null;
|
campaignOne = new FormGroup({
|
||||||
endDate: Date = null;
|
start: new FormControl(null),
|
||||||
|
end: new FormControl(null),
|
||||||
|
});
|
||||||
formControlInterests = new FormControl();
|
formControlInterests = new FormControl();
|
||||||
allInterests: string[] = [];
|
allInterests: string[] = [];
|
||||||
|
|
||||||
|
|
@ -102,7 +105,7 @@ export class PageAdListAdminComponent implements AfterViewInit
|
||||||
else {
|
else {
|
||||||
this.tabAdvertiser = retour.data.filter(x => x.role.name === "advertiser");
|
this.tabAdvertiser = retour.data.filter(x => x.role.name === "advertiser");
|
||||||
for(let advert of tabAdvert) this.tabAdvertWithCountViews.push(this.advertToAdvertWithCountViewsAndCompany(advert));
|
for(let advert of tabAdvert) this.tabAdvertWithCountViews.push(this.advertToAdvertWithCountViewsAndCompany(advert));
|
||||||
this.dataSource = new MatTableDataSource<Advert>();
|
this.dataSource = new MatTableDataSource<any>();
|
||||||
this.onFilter();
|
this.onFilter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -120,13 +123,6 @@ export class PageAdListAdminComponent implements AfterViewInit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
applyFilter(event: Event): void
|
|
||||||
{
|
|
||||||
const filterValue = (event.target as HTMLInputElement).value;
|
|
||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onVisualizeImages(advert: AdvertWithCountViewsAndCompany)
|
onVisualizeImages(advert: AdvertWithCountViewsAndCompany)
|
||||||
{
|
{
|
||||||
if(advert.images.length !== 0)
|
if(advert.images.length !== 0)
|
||||||
|
|
@ -178,29 +174,42 @@ export class PageAdListAdminComponent implements AfterViewInit
|
||||||
|
|
||||||
onFilter(): void
|
onFilter(): void
|
||||||
{
|
{
|
||||||
|
const startDate = this.campaignOne.get("start").value;
|
||||||
|
const endDate = this.campaignOne.get("end").value;
|
||||||
|
|
||||||
this.dataSource.data = [];
|
this.dataSource.data = [];
|
||||||
for(let advert of this.tabAdvertWithCountViews)
|
for(let advert of this.tabAdvertWithCountViews)
|
||||||
{
|
{
|
||||||
let valide: boolean = true;
|
// filtre textuelle
|
||||||
|
let valide: boolean = this.isTextFiltrationValid(advert);;
|
||||||
|
|
||||||
|
// filtre actif
|
||||||
|
if(valide)
|
||||||
|
{
|
||||||
if(advert.isVisible && this.visible) valide = true;
|
if(advert.isVisible && this.visible) valide = true;
|
||||||
else if((!advert.isVisible) && this.noVisible) valide = true;
|
else if((!advert.isVisible) && this.noVisible) valide = true;
|
||||||
else valide = false;
|
else valide = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filtre date
|
||||||
if(valide)
|
if(valide)
|
||||||
{
|
{
|
||||||
if ((advert.createdAt === null) && (this.startDate !== null)) valide = false;
|
if ((advert.createdAt === null) && (startDate !== null)) valide = false;
|
||||||
else if ((advert.createdAt === null) && (this.endDate !== null)) valide = false;
|
else if ((advert.createdAt === null) && (endDate !== null)) valide = false;
|
||||||
else if (this.startDate !== null)
|
else if (startDate !== null)
|
||||||
{
|
{
|
||||||
if(this.startDate.getTime() > advert.createdAt.getTime()) valide = false;
|
let timeCreatedAt = 0;
|
||||||
else if (this.endDate !== null)
|
if(advert.createdAt !== null) timeCreatedAt = (new Date(advert.createdAt)).getTime();
|
||||||
|
|
||||||
|
if(startDate.getTime() > timeCreatedAt) valide = false;
|
||||||
|
else if (endDate !== null)
|
||||||
{
|
{
|
||||||
if(this.endDate.getTime() < advert.createdAt.getTime()) valide = false;
|
if(endDate.getTime() < timeCreatedAt) valide = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filtre interests
|
||||||
if(valide) {
|
if(valide) {
|
||||||
if(this.formControlInterests.value !== null) {
|
if(this.formControlInterests.value !== null) {
|
||||||
for (let interest of this.formControlInterests.value) {
|
for (let interest of this.formControlInterests.value) {
|
||||||
|
|
@ -221,22 +230,30 @@ export class PageAdListAdminComponent implements AfterViewInit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onNewStartDate(event): void {
|
isTextFiltrationValid(advert): boolean
|
||||||
this.startDate = new Date(event);
|
{
|
||||||
}
|
let datePipe = new DatePipe('en-GB');
|
||||||
|
if(advert.title.includes(this.filteredText)) return true;
|
||||||
onNewEndDate(event): void {
|
if(advert.company.includes(this.filteredText)) return true;
|
||||||
this.endDate = new Date(event);
|
if(advert.email.includes(this.filteredText)) return true;
|
||||||
|
const createdAt = datePipe.transform(new Date(advert.createdAt), 'dd/MM/yyyy à HH:mm:ss');
|
||||||
|
if(createdAt.includes(this.filteredText)) return true;
|
||||||
|
const updatedAt = datePipe.transform(new Date(advert.updatedAt), 'dd/MM/yyyy à HH:mm:ss');
|
||||||
|
if(updatedAt.includes(this.filteredText)) return true;
|
||||||
|
if(advert.countViews.toString().includes(this.filteredText)) return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
advertToAdvertWithCountViewsAndCompany(advert): AdvertWithCountViewsAndCompany
|
advertToAdvertWithCountViewsAndCompany(advert): AdvertWithCountViewsAndCompany
|
||||||
{
|
{
|
||||||
let company0 = "company" ;
|
let company0 = "company" ;
|
||||||
|
let email0 = "email" ;
|
||||||
for(let advertiser of this.tabAdvertiser)
|
for(let advertiser of this.tabAdvertiser)
|
||||||
{
|
{
|
||||||
if(advert.userId === advertiser.id) {
|
if(advert.userId === advertiser.id) {
|
||||||
company0 = advertiser.company;
|
company0 = advertiser.company;
|
||||||
|
email0 = advertiser.email;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -246,6 +263,7 @@ export class PageAdListAdminComponent implements AfterViewInit
|
||||||
userId: advert.userId,
|
userId: advert.userId,
|
||||||
title: advert.title,
|
title: advert.title,
|
||||||
company: company0,
|
company: company0,
|
||||||
|
email: email0,
|
||||||
url: advert.url,
|
url: advert.url,
|
||||||
images: advert.images,
|
images: advert.images,
|
||||||
interests: advert.interests,
|
interests: advert.interests,
|
||||||
|
|
@ -259,4 +277,10 @@ export class PageAdListAdminComponent implements AfterViewInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onEffacerDate(): void {
|
||||||
|
this.campaignOne.setValue({start: null, end: null });
|
||||||
|
this.onFilter();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-popup-delete-ad-admin',
|
selector: 'app-popup-delete-ad-admin',
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-popup-visualize-images-admin',
|
selector: 'app-popup-visualize-images-admin',
|
||||||
templateUrl: './popup-visualize-images-admin.component.html',
|
templateUrl: './popup-visualize-images-admin.component.html',
|
||||||
styleUrls: ['./popup-visualize-images-admin.component.scss']
|
styleUrls: ['./popup-visualize-images-admin.component.scss']
|
||||||
})
|
})
|
||||||
export class PopupVisualizeImagesAdminComponent implements OnInit
|
export class PopupVisualizeImagesAdminComponent implements OnInit {
|
||||||
{
|
|
||||||
tabImages = [];
|
tabImages = [];
|
||||||
index: number = 0;
|
index: number = 0;
|
||||||
nbImage: number = 0;
|
nbImage: number = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import {User} from "../../../utils/interfaces/user";
|
import {ThemeService} from "../../../utils/theme/theme.service";
|
||||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
|
import {ProfilService} from "../../../utils/profil/profil.service";
|
||||||
import {PopupUpdateAdminComponent} from "../popup-update-admin/popup-update-admin.component";
|
import {PopupUpdateAdminComponent} from "../popup-update-admin/popup-update-admin.component";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
import {ProfilService} from "../../../utils/services/profil/profil.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-page-profil-admin',
|
selector: 'app-page-profil-admin',
|
||||||
|
|
@ -16,7 +13,7 @@ import {ProfilService} from "../../../utils/services/profil/profil.service";
|
||||||
})
|
})
|
||||||
export class PageProfilAdminComponent implements OnInit
|
export class PageProfilAdminComponent implements OnInit
|
||||||
{
|
{
|
||||||
admin: User = {
|
admin = {
|
||||||
_id: "",
|
_id: "",
|
||||||
login: "",
|
login: "",
|
||||||
hashPass: "",
|
hashPass: "",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {User} from "../../../utils/interfaces/user";
|
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
import {ProfilService} from "../../../utils/services/profil/profil.service";
|
import {ProfilService} from "../../../utils/profil/profil.service";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
@ -13,7 +11,7 @@ import {ProfilService} from "../../../utils/services/profil/profil.service";
|
||||||
})
|
})
|
||||||
export class PopupUpdateAdminComponent implements OnInit
|
export class PopupUpdateAdminComponent implements OnInit
|
||||||
{
|
{
|
||||||
adminCopy: User;
|
adminCopy;
|
||||||
newPassword: string = "";
|
newPassword: string = "";
|
||||||
confirmNewPassword: string = "" ;
|
confirmNewPassword: string = "" ;
|
||||||
changePassword: boolean = false ;
|
changePassword: boolean = false ;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} f
|
||||||
import {COMMA, ENTER} from "@angular/cdk/keycodes";
|
import {COMMA, ENTER} from "@angular/cdk/keycodes";
|
||||||
import {FormControl} from "@angular/forms";
|
import {FormControl} from "@angular/forms";
|
||||||
import {Observable} from "rxjs";
|
import {Observable} from "rxjs";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
import {map, startWith} from "rxjs/operators";
|
import {map, startWith} from "rxjs/operators";
|
||||||
import {MatChipInputEvent} from "@angular/material/chips";
|
import {MatChipInputEvent} from "@angular/material/chips";
|
||||||
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
|
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
|
||||||
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
<!-- filtre textuelle-->
|
<!-- filtre textuelle-->
|
||||||
<div style="margin: 10px 0px 20px 2%;">
|
<div style="margin: 10px 0px 20px 2%;">
|
||||||
<input class="textFilter" (keyup)="applyFilter($event)" placeholder="Rechercher par mots-clés...">
|
<input class="textFilter" [(ngModel)]="filteredText" (ngModelChange)="onFilter()" placeholder="Rechercher par mots-clés...">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- role + actif + période -->
|
<!-- role + actif + période -->
|
||||||
|
|
@ -52,20 +52,23 @@
|
||||||
|
|
||||||
<!-- période -->
|
<!-- période -->
|
||||||
<div class="col-8" style="text-align: right;">
|
<div class="col-8" style="text-align: right;">
|
||||||
Période de dernière connexion:
|
<mat-form-field appearance="fill">
|
||||||
<mat-form-field appearance="fill" style="width: 140px;">
|
<mat-label>Période de dernière connexion</mat-label>
|
||||||
<mat-label>Date de début</mat-label>
|
<mat-date-range-input
|
||||||
<input matInput type="date"
|
[formGroup]="campaignOne"
|
||||||
[ngModel] ="startDate | date:'yyyy-MM-dd'"
|
[rangePicker]="campaignOnePicker">
|
||||||
(ngModelChange)="onNewStartDate($event); onFilter();">
|
<input matStartDate placeholder="Start date" formControlName="start">
|
||||||
</mat-form-field>
|
<input matEndDate placeholder="End date" formControlName="end">
|
||||||
-
|
</mat-date-range-input>
|
||||||
<mat-form-field appearance="fill" style="width: 140px;">
|
<mat-datepicker-toggle matSuffix [for]="campaignOnePicker"></mat-datepicker-toggle>
|
||||||
<mat-label>Date de fin</mat-label>
|
<mat-date-range-picker #campaignOnePicker></mat-date-range-picker>
|
||||||
<input matInput type="date"
|
|
||||||
[ngModel] ="endDate | date:'yyyy-MM-dd'"
|
|
||||||
(ngModelChange)="onNewEndDate($event); onFilter();">
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<button mat-icon-button (click)="onFilter()">
|
||||||
|
<mat-icon>keyboard_tab</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button (click)="onEffacerDate()">
|
||||||
|
<mat-icon>close</mat-icon>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -114,6 +117,14 @@
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Company Column -->
|
||||||
|
<ng-container matColumnDef="company">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Entreprise </th>
|
||||||
|
<td mat-cell *matCellDef="let user">
|
||||||
|
{{user.company}}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<!-- DateOfBirth Column -->
|
<!-- DateOfBirth Column -->
|
||||||
<ng-container matColumnDef="dateOfBirth">
|
<ng-container matColumnDef="dateOfBirth">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date de naissance </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date de naissance </th>
|
||||||
|
|
@ -179,9 +190,6 @@
|
||||||
<!-- Directives -->
|
<!-- Directives -->
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
<tr class="mat-row" *matNoDataRow>
|
|
||||||
<td class="mat-cell" colspan="4"> Aucune vidéo ne correspond au filtre: "{{input.value}}" </td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<div style="width: 94%; margin: auto auto">
|
<div style="width: 94%; margin: auto auto">
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
import {AfterViewInit, Component, ViewChild} from '@angular/core';
|
import {AfterViewInit, Component, ViewChild} from '@angular/core';
|
||||||
import {MatSort} from "@angular/material/sort";
|
import {MatSort} from "@angular/material/sort";
|
||||||
import {MatPaginator} from "@angular/material/paginator";
|
import {MatPaginator} from "@angular/material/paginator";
|
||||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
import {PopupDeleteUserComponent} from "../popup-delete-user/popup-delete-user.component";
|
|
||||||
import {PopupCreateUserComponent} from "../popup-create-user/popup-create-user.component";
|
import {PopupCreateUserComponent} from "../popup-create-user/popup-create-user.component";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
import {ThemeService} from "../../../utils/theme/theme.service";
|
||||||
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
|
import {FormControl, FormGroup} from "@angular/forms";
|
||||||
|
import {DatePipe} from "@angular/common";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,7 +21,7 @@ export class PageUserListComponent implements AfterViewInit
|
||||||
{
|
{
|
||||||
displayedColumns: string[];
|
displayedColumns: string[];
|
||||||
displayedColumnsUser: string[] = [ 'isActive', 'login', 'email', 'dateOfBirth', 'age', 'sexe', 'interests', 'createdAt', 'lastConnexion' ];
|
displayedColumnsUser: string[] = [ 'isActive', 'login', 'email', 'dateOfBirth', 'age', 'sexe', 'interests', 'createdAt', 'lastConnexion' ];
|
||||||
displayedColumnsAdvertiser: string[] = [ 'isActive', 'login', 'email', 'createdAt', 'lastConnexion', 'isAccepted' ];
|
displayedColumnsAdvertiser: string[] = [ 'isActive', 'login', 'email', 'company', 'createdAt', 'lastConnexion', 'isAccepted' ];
|
||||||
displayedColumnsAdmin: string[] = [ 'isActive', 'login', 'email', 'createdAt', 'lastConnexion' ];
|
displayedColumnsAdmin: string[] = [ 'isActive', 'login', 'email', 'createdAt', 'lastConnexion' ];
|
||||||
|
|
||||||
tabUser: any[] = [];
|
tabUser: any[] = [];
|
||||||
|
|
@ -32,10 +33,14 @@ export class PageUserListComponent implements AfterViewInit
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
|
|
||||||
|
filteredText: string = "" ;
|
||||||
active: boolean = true;
|
active: boolean = true;
|
||||||
noActive: boolean = false;
|
noActive: boolean = false;
|
||||||
startDate: Date = null;
|
campaignOne = new FormGroup({
|
||||||
endDate: Date = null;
|
start: new FormControl(null),
|
||||||
|
end: new FormControl(null),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor( public themeService: ThemeService,
|
constructor( public themeService: ThemeService,
|
||||||
|
|
@ -62,6 +67,7 @@ export class PageUserListComponent implements AfterViewInit
|
||||||
{
|
{
|
||||||
if(person.role.name === "user") {
|
if(person.role.name === "user") {
|
||||||
person["age"] = this.getAge(person.dateOfBirth);
|
person["age"] = this.getAge(person.dateOfBirth);
|
||||||
|
delete person.profileImageUrl;
|
||||||
this.tabUser.push(person);
|
this.tabUser.push(person);
|
||||||
}
|
}
|
||||||
else if(person.role.name === "advertiser") this.tabAdvertiser.push(person);
|
else if(person.role.name === "advertiser") this.tabAdvertiser.push(person);
|
||||||
|
|
@ -72,40 +78,6 @@ export class PageUserListComponent implements AfterViewInit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
applyFilter(event: Event): void
|
|
||||||
{
|
|
||||||
const filterValue = (event.target as HTMLInputElement).value;
|
|
||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onDelete(user: any): void
|
|
||||||
{
|
|
||||||
const config = {
|
|
||||||
data: { user: user }
|
|
||||||
};
|
|
||||||
this.dialog
|
|
||||||
.open(PopupDeleteUserComponent, config)
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe( retour => {
|
|
||||||
|
|
||||||
const config = { duration: 1000, panelClass: "custom-class" };
|
|
||||||
let message = "" ;
|
|
||||||
if((retour === undefined) || (retour === null)) {
|
|
||||||
message = "Opération annulée" ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const index = this.dataSource.data.findIndex( elt => (elt.id === user.id));
|
|
||||||
this.dataSource.data.splice(index, 1);
|
|
||||||
this.dataSource.data = this.dataSource.data;
|
|
||||||
this.dataSource = this.dataSource;
|
|
||||||
message = user.login + " a bien été supprimée ✔" ;
|
|
||||||
}
|
|
||||||
this.snackBar.open(message, "", config);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onCreateUser(): void
|
onCreateUser(): void
|
||||||
{
|
{
|
||||||
const config = { width: '50%' };
|
const config = { width: '50%' };
|
||||||
|
|
@ -177,6 +149,9 @@ export class PageUserListComponent implements AfterViewInit
|
||||||
|
|
||||||
onFilter(): void
|
onFilter(): void
|
||||||
{
|
{
|
||||||
|
const startDate = this.campaignOne.get("start").value;
|
||||||
|
const endDate = this.campaignOne.get("end").value;
|
||||||
|
|
||||||
let tab1 = [];
|
let tab1 = [];
|
||||||
if(this.roleName === "user") {
|
if(this.roleName === "user") {
|
||||||
this.displayedColumns = this.displayedColumnsUser;
|
this.displayedColumns = this.displayedColumnsUser;
|
||||||
|
|
@ -194,21 +169,31 @@ export class PageUserListComponent implements AfterViewInit
|
||||||
let tab2 = [];
|
let tab2 = [];
|
||||||
for(let user of tab1)
|
for(let user of tab1)
|
||||||
{
|
{
|
||||||
let valide: boolean = true;
|
// filtre textuelle
|
||||||
|
let valide: boolean = this.isTextFiltrationValid(user);;
|
||||||
|
|
||||||
|
// filtre actif
|
||||||
|
if(valide)
|
||||||
|
{
|
||||||
if(user.isActive && this.active) valide = true;
|
if(user.isActive && this.active) valide = true;
|
||||||
else if((!user.isActive) && this.noActive) valide = true;
|
else if((!user.isActive) && this.noActive) valide = true;
|
||||||
else valide = false;
|
else valide = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filtre date
|
||||||
if(valide)
|
if(valide)
|
||||||
{
|
{
|
||||||
if ((user.lastConnexion === null) && (this.startDate !== null)) valide = false;
|
if ((user.lastConnexion === null) && (startDate !== null)) valide = false;
|
||||||
else if ((user.lastConnexion === null) && (this.endDate !== null)) valide = false;
|
else if ((user.lastConnexion === null) && (endDate !== null)) valide = false;
|
||||||
else if (this.startDate !== null)
|
else if (startDate !== null)
|
||||||
{
|
{
|
||||||
if(this.startDate.getTime() > user.lastConnexion.getTime()) valide = false;
|
let timeLastConnexion = 0;
|
||||||
else if (this.endDate !== null)
|
if(user.lastConnexion !== null) timeLastConnexion = (new Date(user.lastConnexion)).getTime();
|
||||||
|
|
||||||
|
if(startDate.getTime() > timeLastConnexion) valide = false;
|
||||||
|
else if (endDate !== null)
|
||||||
{
|
{
|
||||||
if(this.endDate.getTime() < user.lastConnexion.getTime()) valide = false;
|
if(endDate.getTime() < timeLastConnexion) valide = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -222,12 +207,36 @@ export class PageUserListComponent implements AfterViewInit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onNewStartDate(event): void {
|
isTextFiltrationValid(user): boolean
|
||||||
this.startDate = new Date(event);
|
{
|
||||||
|
let datePipe = new DatePipe('en-GB');
|
||||||
|
if(user.login.includes(this.filteredText)) return true;
|
||||||
|
if(user.email.includes(this.filteredText)) return true;
|
||||||
|
const createdAt = datePipe.transform(new Date(user.createdAt), 'dd/MM/yyyy à HH:mm:ss');
|
||||||
|
if(createdAt.includes(this.filteredText)) return true;
|
||||||
|
const lastConnexion = datePipe.transform(new Date(user.lastConnexion), 'dd/MM/yyyy à HH:mm:ss');
|
||||||
|
if(lastConnexion.includes(this.filteredText)) return true;
|
||||||
|
|
||||||
|
if(this.roleName === 'user')
|
||||||
|
{
|
||||||
|
const dateOfBirth = datePipe.transform(new Date(user.dateOfBirth), 'dd/MM/yyyy à HH:mm:ss');
|
||||||
|
if(dateOfBirth.includes(this.filteredText)) return true;
|
||||||
|
if(user.age.toString().includes(this.filteredText)) return true;
|
||||||
|
if((user.sexe === 'man') && (this.filteredText === 'M')) return true;
|
||||||
|
if((user.sexe === 'woman') && (this.filteredText === 'F')) return true;
|
||||||
|
if(user.interests.toString().includes(this.filteredText)) return true;
|
||||||
|
}
|
||||||
|
else if(this.roleName === 'advertiser')
|
||||||
|
{
|
||||||
|
if(user.company.includes(this.filteredText)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onNewEndDate(event): void {
|
|
||||||
this.endDate = new Date(event);
|
onEffacerDate(): void {
|
||||||
|
this.campaignOne.setValue({start: null, end: null });
|
||||||
|
this.onFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-popup-create-user',
|
selector: 'app-popup-create-user',
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<mat-dialog-content class="mat-typography">
|
|
||||||
Êtes-vous sûr de vouloir supprimer <i>{{user.login}}</i> ?
|
|
||||||
</mat-dialog-content>
|
|
||||||
|
|
||||||
<mat-dialog-actions align="end">
|
|
||||||
<button mat-button (click)="dialogRef.close();">Annuler</button>
|
|
||||||
<button mat-button (click)="onValidate()" cdkFocusInitial>Valider</button>
|
|
||||||
</mat-dialog-actions>
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PopupDeleteUserComponent } from './popup-delete-user.component';
|
|
||||||
|
|
||||||
describe('PopupDeleteUserComponent', () => {
|
|
||||||
let component: PopupDeleteUserComponent;
|
|
||||||
let fixture: ComponentFixture<PopupDeleteUserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PopupDeleteUserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PopupDeleteUserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-popup-delete-user',
|
|
||||||
templateUrl: './popup-delete-user.component.html',
|
|
||||||
styleUrls: ['./popup-delete-user.component.scss']
|
|
||||||
})
|
|
||||||
export class PopupDeleteUserComponent implements OnInit
|
|
||||||
{
|
|
||||||
user;
|
|
||||||
|
|
||||||
constructor( public dialogRef: MatDialogRef<PopupDeleteUserComponent>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data,
|
|
||||||
private messageService: MessageService ) { }
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
this.user = this.data.user;
|
|
||||||
}
|
|
||||||
|
|
||||||
onValidate(): void
|
|
||||||
{
|
|
||||||
// --- FAUX CODE ---
|
|
||||||
this.dialogRef.close(true);
|
|
||||||
|
|
||||||
// --- VRAI CODE ---
|
|
||||||
/*
|
|
||||||
this.messageService
|
|
||||||
.sendMessage("user/delete", {"advert": this.advert})
|
|
||||||
.subscribe( retour => {
|
|
||||||
|
|
||||||
if(retour.status === "error") {
|
|
||||||
console.log(retour);
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.dialogRef.close(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import {Component} from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {ProfilService} from "../../../utils/services/profil/profil.service";
|
import {ProfilService} from "../../../utils/profil/profil.service";
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
import {MessageService} from "../../../utils/message/message.service";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-navbar-admin',
|
selector: 'app-navbar-admin',
|
||||||
|
|
@ -35,6 +33,7 @@ export class NavbarAdminComponent
|
||||||
onDeconnexionCallback(retour: any): void
|
onDeconnexionCallback(retour: any): void
|
||||||
{
|
{
|
||||||
if(retour.status !== "success") console.log(retour);
|
if(retour.status !== "success") console.log(retour);
|
||||||
|
this.profilService.setId("");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
<div title="bobo" class="container" appDragAndDrop (fileDropped)="onFileDropped($event)">
|
|
||||||
<input type="file" #fileDropRef id="fileDropRef" multiple (change)="fileBrowseHandler($event.target.files)" />
|
|
||||||
<div style="font-weight: bold">Images</div>
|
|
||||||
<img src="/assets/uploadFile.png" width="50" height="50" style="margin-top: 5px">
|
|
||||||
<div style="font-style: italic; margin-top: 10px">Glisser déposer</div>
|
|
||||||
<div style="font-style: italic">ou</div>
|
|
||||||
<div style="font-style: italic" for="fileDropRef">Cliquer pour selectionner</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="text-align: center;">
|
|
||||||
<mat-icon [title]=info_image>info</mat-icon>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="files-list">
|
|
||||||
<div class="single-file" *ngFor="let file of files; let i = index">
|
|
||||||
<img src="/assets/uploadFile.png" width="45px" alt="file">
|
|
||||||
<div class="info">
|
|
||||||
<h4 class="name">
|
|
||||||
{{ file?.name }}
|
|
||||||
</h4>
|
|
||||||
<p class="size">
|
|
||||||
{{ formatBytes(file?.size) }}
|
|
||||||
</p>
|
|
||||||
<div class="progress-cont">
|
|
||||||
<div class="progress" [style.width]="file?.progress + '%'">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button mat-icon-button class="delete" width="20px" alt="file" (click)="deleteFile(i)">
|
|
||||||
<mat-icon>delete</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
.container {
|
|
||||||
width: 450px;
|
|
||||||
height: 180px;
|
|
||||||
padding: 20px 0px 20px 0px;
|
|
||||||
text-align: center;
|
|
||||||
border: dashed 1px #979797;
|
|
||||||
position: relative;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.fileover {
|
|
||||||
animation: shake 1s;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.files-list {
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
|
|
||||||
.single-file {
|
|
||||||
display: flex;
|
|
||||||
padding: 0.5rem;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
border: dashed 1px #979797;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
|
|
||||||
img.delete {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
align-self: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #353f4a;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.size {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #a4a4a4;
|
|
||||||
margin: 0;
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info {
|
|
||||||
width: 100%
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shake animation */
|
|
||||||
@keyframes shake {
|
|
||||||
0% {
|
|
||||||
transform: translate(1px, 1px) rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
10% {
|
|
||||||
transform: translate(-1px, -2px) rotate(-1deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
20% {
|
|
||||||
transform: translate(-3px, 0px) rotate(1deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
30% {
|
|
||||||
transform: translate(3px, 2px) rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
40% {
|
|
||||||
transform: translate(1px, -1px) rotate(1deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translate(-1px, 2px) rotate(-1deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
60% {
|
|
||||||
transform: translate(-3px, 1px) rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
70% {
|
|
||||||
transform: translate(3px, 1px) rotate(-1deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
80% {
|
|
||||||
transform: translate(-1px, -1px) rotate(1deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
90% {
|
|
||||||
transform: translate(1px, 2px) rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(1px, -2px) rotate(-1deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.progress-cont {
|
|
||||||
height: 7px;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: #d0d0d0;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.progress {
|
|
||||||
width: 0;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: #4c97cb;
|
|
||||||
transition: 0.5s all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { DragAndDropComponent } from './drag-and-drop.component';
|
|
||||||
|
|
||||||
describe('DragAndDropComponent', () => {
|
|
||||||
let component: DragAndDropComponent;
|
|
||||||
let fixture: ComponentFixture<DragAndDropComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ DragAndDropComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(DragAndDropComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
import {Component, ElementRef, EventEmitter, OnInit, Output, ViewChild} from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-drag-and-drop',
|
|
||||||
templateUrl: './drag-and-drop.component.html',
|
|
||||||
styleUrls: ['./drag-and-drop.component.scss']
|
|
||||||
})
|
|
||||||
export class DragAndDropComponent
|
|
||||||
{
|
|
||||||
@ViewChild("fileDropRef", { static: false }) fileDropEl: ElementRef;
|
|
||||||
info_image = "Vos annonces seront affichées dans un rectangle de rapport 1/5 avec: \n • 1 la largeur du rectangle \n • 5 la hauteur du rectangle" ;
|
|
||||||
files: any[] = [];
|
|
||||||
@Output() eventEmitter = new EventEmitter<any>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* on file drop handler
|
|
||||||
*/
|
|
||||||
onFileDropped($event) {
|
|
||||||
this.prepareFilesList($event);
|
|
||||||
this.eventEmitter.emit(this.files);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle file from browsing
|
|
||||||
*/
|
|
||||||
fileBrowseHandler(files) {
|
|
||||||
this.prepareFilesList(files);
|
|
||||||
this.eventEmitter.emit(this.files);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete file from files list
|
|
||||||
* @param index (File index)
|
|
||||||
*/
|
|
||||||
deleteFile(index: number) {
|
|
||||||
if (this.files[index].progress < 100) {
|
|
||||||
console.log("Upload in progress.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.files.splice(index, 1);
|
|
||||||
this.eventEmitter.emit(this.files);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulate the upload process
|
|
||||||
*/
|
|
||||||
uploadFilesSimulator(index: number) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (index === this.files.length) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const progressInterval = setInterval(() => {
|
|
||||||
if (this.files[index].progress === 100) {
|
|
||||||
clearInterval(progressInterval);
|
|
||||||
this.uploadFilesSimulator(index + 1);
|
|
||||||
} else {
|
|
||||||
this.files[index].progress += 5;
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert Files list to normal array list
|
|
||||||
* @param files (Files List)
|
|
||||||
*/
|
|
||||||
prepareFilesList(files: Array<any>) {
|
|
||||||
for (const item of files) {
|
|
||||||
item.progress = 0;
|
|
||||||
this.files.push(item);
|
|
||||||
}
|
|
||||||
this.fileDropEl.nativeElement.value = "";
|
|
||||||
this.uploadFilesSimulator(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* format bytes
|
|
||||||
* @param bytes (File size in bytes)
|
|
||||||
* @param decimals (Decimals point)
|
|
||||||
*/
|
|
||||||
formatBytes(bytes, decimals = 2) {
|
|
||||||
if (bytes === 0) {
|
|
||||||
return "0 Bytes";
|
|
||||||
}
|
|
||||||
const k = 1024;
|
|
||||||
const dm = decimals <= 0 ? 0 : decimals;
|
|
||||||
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
<mat-form-field class="example-chip-list" appearance="fill">
|
|
||||||
|
|
||||||
<!-- ------------------------------------------------------------------------------------ -->
|
|
||||||
|
|
||||||
<mat-label>Sujets</mat-label>
|
|
||||||
|
|
||||||
<!-- ------------------------------------------------------------------------------------ -->
|
|
||||||
|
|
||||||
<mat-chip-list #chipList aria-label="Fruit selection">
|
|
||||||
|
|
||||||
<mat-chip
|
|
||||||
*ngFor="let interest of myInterests"
|
|
||||||
[selectable]="selectable"
|
|
||||||
[removable]="removable"
|
|
||||||
(removed)="remove(interest)">
|
|
||||||
{{interest}}
|
|
||||||
<button matChipRemove *ngIf="removable">
|
|
||||||
<mat-icon>cancel</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-chip>
|
|
||||||
|
|
||||||
<input
|
|
||||||
placeholder="Tapez un centre d'intérêt et pressez 'Entrer' pour l'inserer"
|
|
||||||
#tagInput
|
|
||||||
[formControl]="formControl"
|
|
||||||
[matAutocomplete]="auto"
|
|
||||||
[matChipInputFor]="chipList"
|
|
||||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
|
||||||
(matChipInputTokenEnd)="add($event)">
|
|
||||||
|
|
||||||
</mat-chip-list>
|
|
||||||
|
|
||||||
<!-- ------------------------------------------------------------------------------------ -->
|
|
||||||
|
|
||||||
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
|
|
||||||
<mat-option *ngFor="let interest of filteredInterests | async" [value]="interest">
|
|
||||||
{{interest}}
|
|
||||||
</mat-option>
|
|
||||||
</mat-autocomplete>
|
|
||||||
|
|
||||||
<!-- ------------------------------------------------------------------------------------ -->
|
|
||||||
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
mat-form-field {
|
|
||||||
width: 100%;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat-chip-list {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat-chip {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { InputInterestsAdComponent } from './input-interests-ad.component';
|
|
||||||
|
|
||||||
describe('BarTagsComponent', () => {
|
|
||||||
let component: InputInterestsAdComponent;
|
|
||||||
let fixture: ComponentFixture<InputInterestsAdComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ InputInterestsAdComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(InputInterestsAdComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
|
|
||||||
import {COMMA, ENTER} from "@angular/cdk/keycodes";
|
|
||||||
import {FormControl} from "@angular/forms";
|
|
||||||
import {Observable} from "rxjs";
|
|
||||||
import {map, startWith} from "rxjs/operators";
|
|
||||||
import {MatChipInputEvent} from "@angular/material/chips";
|
|
||||||
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-input-interests-ad',
|
|
||||||
templateUrl: './input-interests-ad.component.html',
|
|
||||||
styleUrls: ['./input-interests-ad.component.scss']
|
|
||||||
})
|
|
||||||
export class InputInterestsAdComponent implements OnInit
|
|
||||||
{
|
|
||||||
selectable = true;
|
|
||||||
removable = true;
|
|
||||||
separatorKeysCodes: number[] = [ENTER, COMMA];
|
|
||||||
formControl = new FormControl();
|
|
||||||
filteredInterests: Observable<string[]>;
|
|
||||||
@Input() myInterests: string[] = [];
|
|
||||||
allInterests: string[] = [];
|
|
||||||
@Output() eventEmitter = new EventEmitter<string[]>();
|
|
||||||
@ViewChild('tagInput') tagInput: ElementRef<HTMLInputElement>;
|
|
||||||
interestsNotSelected: string[] = [];
|
|
||||||
|
|
||||||
|
|
||||||
constructor( private messageService: MessageService ) {}
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
this.filteredInterests = this.formControl.valueChanges.pipe(
|
|
||||||
startWith(null),
|
|
||||||
map((fruit: string | null) => fruit ? this._filter(fruit) : this.interestsNotSelected.slice()));
|
|
||||||
|
|
||||||
this.messageService
|
|
||||||
.get("misc/getInterests")
|
|
||||||
.subscribe( retour => {
|
|
||||||
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.allInterests = [];
|
|
||||||
for(let elt of retour.data)
|
|
||||||
{
|
|
||||||
this.allInterests.push(elt.interest);
|
|
||||||
this.interestsNotSelected.push(elt.interest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
add(event: MatChipInputEvent): void
|
|
||||||
{
|
|
||||||
const value = (event.value || '').trim();
|
|
||||||
const index = this.interestsNotSelected.indexOf(value);
|
|
||||||
if (value && (index !== -1) && (!this.myInterests.includes(value)))
|
|
||||||
{
|
|
||||||
this.myInterests.push(value);
|
|
||||||
event.chipInput!.clear();
|
|
||||||
this.formControl.setValue(null);
|
|
||||||
this.eventEmitter.emit(this.myInterests);
|
|
||||||
this.interestsNotSelected.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
remove(interest: string): void
|
|
||||||
{
|
|
||||||
// supprimer 'interest' de 'myInterest'
|
|
||||||
const index = this.myInterests.indexOf(interest);
|
|
||||||
if (index >= 0) this.myInterests.splice(index, 1);
|
|
||||||
this.eventEmitter.emit(this.myInterests);
|
|
||||||
|
|
||||||
// remmettre 'interest' dans 'interestsNotSelected'
|
|
||||||
if(!this.interestsNotSelected.includes(interest))
|
|
||||||
{
|
|
||||||
const indexOfAutres = this.interestsNotSelected.indexOf("Autres");
|
|
||||||
if(indexOfAutres !== -1)
|
|
||||||
{
|
|
||||||
this.interestsNotSelected.splice(indexOfAutres, 1);
|
|
||||||
if(interest !== "Autres") this.interestsNotSelected.push(interest);
|
|
||||||
this.interestsNotSelected.sort();
|
|
||||||
this.interestsNotSelected.push("Autres");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.interestsNotSelected.push(interest);
|
|
||||||
if(interest !== "Autres") this.interestsNotSelected.sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
selected(event: MatAutocompleteSelectedEvent): void
|
|
||||||
{
|
|
||||||
const value = event.option.viewValue;
|
|
||||||
if(!this.myInterests.includes(value))
|
|
||||||
{
|
|
||||||
this.myInterests.push(value);
|
|
||||||
const index = this.interestsNotSelected.indexOf(value);
|
|
||||||
this.interestsNotSelected.splice(index, 1);
|
|
||||||
}
|
|
||||||
this.tagInput.nativeElement.value = '';
|
|
||||||
this.formControl.setValue(null);
|
|
||||||
this.eventEmitter.emit(this.myInterests);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private _filter(value: string): string[]
|
|
||||||
{
|
|
||||||
const filterValue = value.toLowerCase();
|
|
||||||
return this.interestsNotSelected.filter(fruit => fruit.toLowerCase().includes(filterValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,185 +0,0 @@
|
||||||
<div [class]="themeService.getClassTheme()">
|
|
||||||
<div class="myContainer">
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Navbar -->
|
|
||||||
<app-navbar-advertiser></app-navbar-advertiser><br><br>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- filtre + btnAddUser -->
|
|
||||||
<div class="row" style="margin: 20px 3% 20px 3%">
|
|
||||||
|
|
||||||
<!-- filtre -->
|
|
||||||
<div class="col-10" style="padding: 0px 0px 0px 0px;">
|
|
||||||
<div class="filtersContainer mat-elevation-z8">
|
|
||||||
|
|
||||||
<!-- titre -->
|
|
||||||
<div style="font-weight: bold; margin-bottom: 10px;">
|
|
||||||
Filtre
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<mat-divider></mat-divider>
|
|
||||||
|
|
||||||
<!-- filtre textuelle-->
|
|
||||||
<div style="margin: 10px 0px 20px 2%;">
|
|
||||||
<input class="textFilter" (keyup)="applyFilter($event)" placeholder="filtre...">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- role + actif + période -->
|
|
||||||
<div class="row myRow">
|
|
||||||
|
|
||||||
|
|
||||||
<!-- visible -->
|
|
||||||
<div class="col-2">
|
|
||||||
<mat-checkbox [(ngModel)]="visible" (change)="onFilter()">visible</mat-checkbox><br>
|
|
||||||
<mat-checkbox [(ngModel)]="noVisible" (change)="onFilter()">non visible</mat-checkbox>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- sujets -->
|
|
||||||
<div class="col-4">
|
|
||||||
<mat-form-field appearance="fill">
|
|
||||||
<mat-label>Sujets</mat-label>
|
|
||||||
<mat-select [formControl]="formControlInterests" multiple>
|
|
||||||
<mat-select-trigger>
|
|
||||||
{{formControlInterests.value ? formControlInterests.value[0] : ''}}
|
|
||||||
<span *ngIf="formControlInterests.value?.length > 1">
|
|
||||||
(+{{formControlInterests.value.length - 1}} {{formControlInterests.value?.length === 2 ? 'autre' : 'autres'}})
|
|
||||||
</span>
|
|
||||||
</mat-select-trigger>
|
|
||||||
<mat-option *ngFor="let topping of allInterests" [value]="topping">{{topping}}</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
<button mat-icon-button (click)="onFilter()">
|
|
||||||
<mat-icon>keyboard_tab</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- période -->
|
|
||||||
<div class="col-6" style="text-align: right;">
|
|
||||||
Période de création:
|
|
||||||
<mat-form-field appearance="fill" style="width: 140px;">
|
|
||||||
<mat-label>Date de début</mat-label>
|
|
||||||
<input matInput type="date"
|
|
||||||
style="font-size: small; width: 140px;"
|
|
||||||
[ngModel] ="startDate | date:'yyyy-MM-dd'"
|
|
||||||
(ngModelChange)="onNewStartDate($event); onFilter();">
|
|
||||||
</mat-form-field>
|
|
||||||
-
|
|
||||||
<mat-form-field appearance="fill" style="width: 140px;">
|
|
||||||
<mat-label>Date de fin</mat-label>
|
|
||||||
<input matInput type="date"
|
|
||||||
style="font-size: small; width: 140px;"
|
|
||||||
[ngModel] ="endDate | date:'yyyy-MM-dd'"
|
|
||||||
(ngModelChange)="onNewEndDate($event); onFilter();">
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- btnAdd -->
|
|
||||||
<div class="col-2" style="text-align: right; position: relative;">
|
|
||||||
<button mat-button class="btnAjouter" (click)="onAdd()" style="position: absolute; bottom: 0; right: 0;">
|
|
||||||
<mat-icon>add_circle</mat-icon> Ajouter une annonce
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Table -->
|
|
||||||
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
|
||||||
|
|
||||||
<!-- IsActive Column -->
|
|
||||||
<ng-container matColumnDef="isVisible">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>
|
|
||||||
<mat-icon>power_settings_new</mat-icon>
|
|
||||||
</th>
|
|
||||||
<td mat-cell *matCellDef="let advert">
|
|
||||||
<mat-slide-toggle [(ngModel)]="advert.isVisible" (click)="onSliderIsVisible(advert)"></mat-slide-toggle>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- Title Column -->
|
|
||||||
<ng-container matColumnDef="title">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Titre </th>
|
|
||||||
<td mat-cell *matCellDef="let advert">
|
|
||||||
{{advert.title}}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- Subject Column -->
|
|
||||||
<ng-container matColumnDef="interests">
|
|
||||||
<th mat-header-cell *matHeaderCellDef> Sujets </th>
|
|
||||||
<td mat-cell *matCellDef="let advert">
|
|
||||||
<span *ngFor="let interest of advert.interests; let isLast = last;">
|
|
||||||
<span *ngIf="!isLast"> {{interest}}, </span>
|
|
||||||
<span *ngIf="isLast"> {{interest}} </span>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- CreatedAt Column -->
|
|
||||||
<ng-container matColumnDef="createdAt">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date de création </th>
|
|
||||||
<td mat-cell *matCellDef="let advert">
|
|
||||||
{{ advert.createdAt | date:'dd/LL/YYYY à HH:mm:ss' }}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- LastUpdate Column -->
|
|
||||||
<ng-container matColumnDef="updatedAt">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Dernière modification </th>
|
|
||||||
<td mat-cell *matCellDef="let advert">
|
|
||||||
{{ advert.updatedAt | date:'dd/LL/YYYY à HH:mm:ss' }}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- Views Column -->
|
|
||||||
<ng-container matColumnDef="countViews">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Vues </th>
|
|
||||||
<td mat-cell *matCellDef="let advert">
|
|
||||||
{{advert.countViews}}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- Actions Column -->
|
|
||||||
<ng-container matColumnDef="actions">
|
|
||||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
|
||||||
<td mat-cell *matCellDef="let advert">
|
|
||||||
<button mat-icon-button (click)="onVisualizeImages(advert)">
|
|
||||||
<mat-icon> insert_photo</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button mat-icon-button (click)="onUpdate(advert)">
|
|
||||||
<mat-icon>edit</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button mat-icon-button (click)="onDelete(advert)">
|
|
||||||
<mat-icon>delete</mat-icon>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- Directives -->
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
|
||||||
<tr class="mat-row" *matNoDataRow>
|
|
||||||
<td class="mat-cell" colspan="4"> Aucune vidéo ne correspond au filtre: "{{input.value}}" </td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
<div style="width: 94%; margin: auto auto">
|
|
||||||
<mat-paginator [pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons aria-label="Select page of periodic elements"></mat-paginator>
|
|
||||||
</div>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
.myContainer {
|
|
||||||
max-width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
overflow-x: hidden;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
.filtersContainer {
|
|
||||||
width: 95%;
|
|
||||||
background-color: white;
|
|
||||||
padding: 10px 10px 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.myRow {
|
|
||||||
margin-left: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textFilter {
|
|
||||||
width: 50%;
|
|
||||||
font-size: medium;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btnAjouter {
|
|
||||||
background-color: white;
|
|
||||||
border: solid 1px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
table {
|
|
||||||
margin: 0 auto;
|
|
||||||
width: 94%;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
.darkTheme table { border: solid 2px white; }
|
|
||||||
|
|
||||||
th.mat-sort-header-sorted {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
width: 30%;
|
|
||||||
font-size: large;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// rong gauche
|
|
||||||
::ng-deep .mat-slide-toggle-thumb {
|
|
||||||
background-color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trait droite
|
|
||||||
::ng-deep .mat-slide-toggle-bar {
|
|
||||||
background-color: gray !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rond droite
|
|
||||||
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
|
|
||||||
background-color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trait gauche
|
|
||||||
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
|
|
||||||
background-color: cornflowerblue !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
::ng-deep .mat-pseudo-checkbox-checked {
|
|
||||||
background-color: black !important;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PageAdListAdvertiserComponent } from './page-ad-list-advertiser.component';
|
|
||||||
|
|
||||||
describe('PageAdvertiserComponent', () => {
|
|
||||||
let component: PageAdListAdvertiserComponent;
|
|
||||||
let fixture: ComponentFixture<PageAdListAdvertiserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PageAdListAdvertiserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PageAdListAdvertiserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,309 +0,0 @@
|
||||||
import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
|
|
||||||
import {MatSort} from "@angular/material/sort";
|
|
||||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
|
||||||
import {AdvertWithCountViews} from "../../../utils/interfaces/advert";
|
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
|
||||||
import {PopupAddOrUpdateAdComponent} from "../popup-add-or-update-ad/popup-add-or-update-ad.component";
|
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
|
||||||
import {PopupDeleteAdAdvertiserComponent} from "../popup-delete-ad-advertiser/popup-delete-ad-advertiser.component";
|
|
||||||
import {MatPaginator} from "@angular/material/paginator";
|
|
||||||
import {PopupVisualizeImagesAdvertiserComponent} from "../popup-visualize-images-advertiser/popup-visualize-images-advertiser.component";
|
|
||||||
import {FictitiousAdvertsService} from "../../../utils/services/fictitiousDatas/fictitiousAdverts/fictitious-adverts.service";
|
|
||||||
import {FormControl} from "@angular/forms";
|
|
||||||
import {FictitiousUtilsService} from "../../../utils/services/fictitiousDatas/fictitiousUtils/fictitious-utils.service";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
import {HttpParams} from "@angular/common/http";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-page-ad-list-advertiser',
|
|
||||||
templateUrl: './page-ad-list-advertiser.component.html',
|
|
||||||
styleUrls: ['./page-ad-list-advertiser.component.scss']
|
|
||||||
})
|
|
||||||
export class PageAdListAdvertiserComponent implements AfterViewInit
|
|
||||||
{
|
|
||||||
displayedColumns: string[] = [ 'isVisible', 'title', 'interests', 'createdAt', 'updatedAt', 'countViews', 'actions' ];
|
|
||||||
tabAdvertWithCountViews: AdvertWithCountViews[] = [];
|
|
||||||
dataSource;
|
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
|
||||||
|
|
||||||
visible: boolean = true;
|
|
||||||
noVisible: boolean = true;
|
|
||||||
startDate: Date = null;
|
|
||||||
endDate: Date = null;
|
|
||||||
formControlInterests = new FormControl();
|
|
||||||
|
|
||||||
allVideoCategorie = [];
|
|
||||||
allInterests: string[] = [];
|
|
||||||
|
|
||||||
|
|
||||||
constructor( public themeService: ThemeService,
|
|
||||||
private fictitiousAdvertsService: FictitiousAdvertsService,
|
|
||||||
private fictitiousUtilsService: FictitiousUtilsService,
|
|
||||||
public dialog: MatDialog,
|
|
||||||
private snackBar: MatSnackBar,
|
|
||||||
private messageService: MessageService ) { }
|
|
||||||
|
|
||||||
|
|
||||||
ngAfterViewInit(): void
|
|
||||||
{
|
|
||||||
// Ask interests
|
|
||||||
this.messageService
|
|
||||||
.get("misc/getInterests")
|
|
||||||
.subscribe(ret => this.afterReceivingInterests(ret), err => this.afterReceivingInterests(err) );
|
|
||||||
|
|
||||||
// Ask ads
|
|
||||||
let params = new HttpParams();
|
|
||||||
params = params.append("isActive", true);
|
|
||||||
this.messageService
|
|
||||||
.get("ad/findAll", params)
|
|
||||||
.subscribe(ret => this.afterReceivingAds(ret), err => this.afterReceivingAds(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
afterReceivingInterests(retour: any): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log("afterReceivingInterests");
|
|
||||||
console.log(retour);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.allVideoCategorie = retour.data;
|
|
||||||
this.allInterests = retour.data.map(x => x.interest);
|
|
||||||
this.allInterests.sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
afterReceivingAds(retour: any): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(retour.data.length !== 0)
|
|
||||||
{
|
|
||||||
for(let advert of retour.data) this.tabAdvertWithCountViews.push(this.advertToAdvertWithCountViews(advert));
|
|
||||||
this.dataSource = new MatTableDataSource<AdvertWithCountViews>();
|
|
||||||
this.onFilter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
applyFilter(event: Event): void
|
|
||||||
{
|
|
||||||
const filterValue = (event.target as HTMLInputElement).value;
|
|
||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onVisualizeImages(advert: AdvertWithCountViews)
|
|
||||||
{
|
|
||||||
if(advert.images.length !== 0)
|
|
||||||
{
|
|
||||||
const config = {
|
|
||||||
width: '30%',
|
|
||||||
height: '90%',
|
|
||||||
data: { images: advert.images }
|
|
||||||
};
|
|
||||||
this.dialog
|
|
||||||
.open(PopupVisualizeImagesAdvertiserComponent, config)
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe(retour => {});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const config = { duration: 2000, panelClass: "custom-class" };
|
|
||||||
const message = "Cette annonce ne contient aucune image" ;
|
|
||||||
this.snackBar.open( message, "", config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onAdd(): void
|
|
||||||
{
|
|
||||||
const config = {
|
|
||||||
width: '75%',
|
|
||||||
//height: '80%',
|
|
||||||
panelClass: 'custom-dialog-container',
|
|
||||||
data: {
|
|
||||||
action: "add",
|
|
||||||
advert: null,
|
|
||||||
allVideoCategorie: this.allVideoCategorie,
|
|
||||||
allTitle: this.tabAdvertWithCountViews.map(x => x.title)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.dialog
|
|
||||||
.open(PopupAddOrUpdateAdComponent, config)
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe( advertAdded => {
|
|
||||||
|
|
||||||
const config = { duration: 1000, panelClass: "custom-class" };
|
|
||||||
let message = "" ;
|
|
||||||
if((advertAdded === undefined) || (advertAdded === null)) {
|
|
||||||
message = "Opération annulée" ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.tabAdvertWithCountViews.push(this.advertToAdvertWithCountViews(advertAdded));
|
|
||||||
this.onFilter();
|
|
||||||
message = "L'annonce a bien été ajoutée ✔" ;
|
|
||||||
}
|
|
||||||
this.snackBar.open( message, "", config);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onUpdate(advertToUpdate: AdvertWithCountViews): void
|
|
||||||
{
|
|
||||||
const config = {
|
|
||||||
width: '75%',
|
|
||||||
//height: '80%',
|
|
||||||
panelClass: 'custom-dialog-container',
|
|
||||||
data: {
|
|
||||||
action: "update",
|
|
||||||
advert: advertToUpdate,
|
|
||||||
allVideoCategorie: this.allVideoCategorie,
|
|
||||||
allTitle: this.tabAdvertWithCountViews.map(x => x.title)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.dialog
|
|
||||||
.open(PopupAddOrUpdateAdComponent, config)
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe( advertUpdated => {
|
|
||||||
|
|
||||||
const config = { duration: 1000, panelClass: "custom-class" };
|
|
||||||
let message = "" ;
|
|
||||||
if((advertUpdated === undefined) || (advertUpdated === null)) {
|
|
||||||
message = "Opération annulée" ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const index = this.tabAdvertWithCountViews.findIndex(elt => (elt.id === advertToUpdate.id));
|
|
||||||
this.tabAdvertWithCountViews.splice(index, 1, this.advertToAdvertWithCountViews(advertUpdated));
|
|
||||||
this.onFilter();
|
|
||||||
message = "L'annonce a bien été modifiée ✔" ;
|
|
||||||
}
|
|
||||||
this.snackBar.open( message, "", config);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onDelete(advert: AdvertWithCountViews): void
|
|
||||||
{
|
|
||||||
const config = {
|
|
||||||
data: { advert: advert }
|
|
||||||
};
|
|
||||||
this.dialog
|
|
||||||
.open(PopupDeleteAdAdvertiserComponent, config)
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe( retour => {
|
|
||||||
|
|
||||||
const config = { duration: 1000, panelClass: "custom-class" };
|
|
||||||
let message = "" ;
|
|
||||||
if((retour === undefined) || (retour === null)) {
|
|
||||||
message = "Opération annulée" ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const index = this.dataSource.data.findIndex( elt => (elt.id === advert.id));
|
|
||||||
this.dataSource.data.splice(index, 1);
|
|
||||||
this.dataSource.data = this.dataSource.data;
|
|
||||||
this.dataSource = this.dataSource;
|
|
||||||
message = advert.title + " a bien été supprimée ✔" ;
|
|
||||||
}
|
|
||||||
this.snackBar.open( message, "", config);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onFilter(): void
|
|
||||||
{
|
|
||||||
if(this.dataSource === null || this.dataSource === undefined) this.dataSource = new MatTableDataSource();
|
|
||||||
this.dataSource.data = [];
|
|
||||||
for(let advert of this.tabAdvertWithCountViews)
|
|
||||||
{
|
|
||||||
let valide: boolean = true;
|
|
||||||
|
|
||||||
if(advert.isVisible && this.visible) valide = true;
|
|
||||||
else if((!advert.isVisible) && this.noVisible) valide = true;
|
|
||||||
else valide = false;
|
|
||||||
|
|
||||||
if(valide)
|
|
||||||
{
|
|
||||||
if ((advert.createdAt === null) && (this.startDate !== null)) valide = false;
|
|
||||||
else if ((advert.createdAt === null) && (this.endDate !== null)) valide = false;
|
|
||||||
else if (this.startDate !== null)
|
|
||||||
{
|
|
||||||
if(this.startDate.getTime() > advert.createdAt.getTime()) valide = false;
|
|
||||||
else if (this.endDate !== null)
|
|
||||||
{
|
|
||||||
if(this.endDate.getTime() < advert.createdAt.getTime()) valide = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(valide) {
|
|
||||||
if(this.formControlInterests.value !== null) {
|
|
||||||
for (let interest of this.formControlInterests.value) {
|
|
||||||
if (advert.interests.indexOf(interest) === -1) {
|
|
||||||
valide = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(valide) this.dataSource.data.push(advert);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dataSource = new MatTableDataSource(this.dataSource.data);
|
|
||||||
this.dataSource.sort = this.sort;
|
|
||||||
this.dataSource.paginator = this.paginator;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onNewStartDate(event): void {
|
|
||||||
this.startDate = new Date(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
onNewEndDate(event): void {
|
|
||||||
this.endDate = new Date(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onSliderIsVisible(advert: any): void
|
|
||||||
{
|
|
||||||
// il faut envoyer la négation de user.isActive
|
|
||||||
this.messageService
|
|
||||||
.put("ad/update/"+advert.id, { isVisible: !advert.isVisible })
|
|
||||||
.subscribe(
|
|
||||||
ret => {},
|
|
||||||
err => {
|
|
||||||
console.log("onSliderIsVisible");
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
advertToAdvertWithCountViews(advert): AdvertWithCountViews
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
id: advert.id,
|
|
||||||
userId: advert.userId,
|
|
||||||
title: advert.title,
|
|
||||||
url: advert.url,
|
|
||||||
images: advert.images,
|
|
||||||
interests: advert.interests.map(x => x.interest),
|
|
||||||
comment: advert.comment,
|
|
||||||
views: advert.views,
|
|
||||||
countViews: advert.views.length,
|
|
||||||
isVisible: advert.isVisible,
|
|
||||||
isActive: advert.isActive,
|
|
||||||
createdAt: advert.createdAt,
|
|
||||||
updatedAt: advert.updatedAt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
<div class="myContainer1">
|
|
||||||
<div class="myContainer2">
|
|
||||||
|
|
||||||
<!-- titre popup -->
|
|
||||||
<h1 mat-dialog-title>{{title}}</h1>
|
|
||||||
|
|
||||||
|
|
||||||
<mat-divider></mat-divider><br>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- tous les champs -->
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<!-- title + interests + comments + isVisible -->
|
|
||||||
<div class="col-6">
|
|
||||||
|
|
||||||
<!-- Title -->
|
|
||||||
<mat-form-field class="titleContainer" appearance="fill">
|
|
||||||
<mat-label> Titre annonce </mat-label>
|
|
||||||
<input matInput type="text" [(ngModel)]="advert.title" required>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<!-- Interests -->
|
|
||||||
<app-input-interests-ad [myInterests]="advert.interests" (eventEmitter)="onEventInputTags($event)"></app-input-interests-ad>
|
|
||||||
|
|
||||||
<!-- Comments -->
|
|
||||||
<mat-form-field class="commentContainer" appearance="fill">
|
|
||||||
<mat-label> Commentaire </mat-label>
|
|
||||||
<textarea matInput [(ngModel)]="advert.comment" rows="5" style="resize: none;"></textarea>
|
|
||||||
</mat-form-field><br>
|
|
||||||
|
|
||||||
<!-- url -->
|
|
||||||
<mat-form-field class="commentContainer" appearance="fill">
|
|
||||||
<mat-label> URL </mat-label>
|
|
||||||
<input matInput [(ngModel)]="advert.url">
|
|
||||||
</mat-form-field><br>
|
|
||||||
|
|
||||||
<!-- IsVisible -->
|
|
||||||
<mat-checkbox [(ngModel)]="advert.isVisible"> Visible </mat-checkbox><br><br>
|
|
||||||
|
|
||||||
<!-- Images déjà présentes -->
|
|
||||||
<div *ngIf="advert.images.length !== 0">
|
|
||||||
<div style="font-weight: bold; margin-bottom: 5px;">
|
|
||||||
Images déjà associées:
|
|
||||||
</div>
|
|
||||||
<div style="margin-left: 20px; padding-left: 2px; border-left: solid 1px #a4a4a4">
|
|
||||||
<div *ngFor="let image of advert.images" style="padding: 2px 0px 2px 0px;">
|
|
||||||
<mat-chip [selectable]="true" [removable]="true" style="font-size: small;">
|
|
||||||
{{image.description}}
|
|
||||||
<button matChipRemove (click)="onRemoveImgAlreadyPresent(image)">
|
|
||||||
<mat-icon>cancel</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-chip>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- nouvelles images -->
|
|
||||||
<div class="col-6" style="overflow-x: hidden; overflow-y: scroll; max-height: 70vh;">
|
|
||||||
<app-drag-and-drop (eventEmitter)="onReceiveNewImages($event)"></app-drag-and-drop>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<br><mat-divider></mat-divider>
|
|
||||||
|
|
||||||
<!-- message d'erreur -->
|
|
||||||
<div *ngIf="hasError" style="text-align: center; margin-bottom: 20px;">
|
|
||||||
<span class="mat-error">{{errorMessage}}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Actions -->
|
|
||||||
<mat-dialog-actions align="end">
|
|
||||||
<button mat-button (click)="dialogRef.close()">Annuler</button>
|
|
||||||
<button mat-button (click)="onValidate()">Valider</button>
|
|
||||||
</mat-dialog-actions>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
.myContainer1 {
|
|
||||||
padding: 10px 10px 0px 25px;
|
|
||||||
margin: 0px 0px 0px 0px;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.myContainer2 {
|
|
||||||
padding: 0px 0px 0px 0px;
|
|
||||||
margin: 0px 0px 0px 0px;
|
|
||||||
overflow-y: hidden;
|
|
||||||
overflow-x: hidden;
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
scrollbar-width: none;
|
|
||||||
}
|
|
||||||
.myContainer2::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: large;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-6, .col-8 {
|
|
||||||
border-left: solid 1px #a4a4a4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.titleContainer {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.commentContainer {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.imageContainer {
|
|
||||||
border: solid 1px grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat-dialog-actions {
|
|
||||||
margin-bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// --- LightTheme ---
|
|
||||||
|
|
||||||
// aura
|
|
||||||
.lightTheme ::ng-deep .mat-checkbox-ripple .mat-ripple-element {
|
|
||||||
background-color: grey !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contenu coche
|
|
||||||
.lightTheme ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
|
|
||||||
background-color: black !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// indeterminate
|
|
||||||
.lightTheme ::ng-deep .mat-checkbox .mat-checkbox-frame {
|
|
||||||
border-color: black !important;
|
|
||||||
background-color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- DarkTheme ---
|
|
||||||
|
|
||||||
// aura
|
|
||||||
.darTheme ::ng-deep .mat-checkbox-ripple .mat-ripple-element {
|
|
||||||
background-color: grey !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contenu coche
|
|
||||||
.darkTheme ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
|
|
||||||
background-color: black !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// indeterminate
|
|
||||||
.darkTheme ::ng-deep .mat-checkbox .mat-checkbox-frame {
|
|
||||||
border-color: white !important;
|
|
||||||
//background-color: white !important;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PopupAddOrUpdateAdComponent } from './popup-add-or-update-ad.component';
|
|
||||||
|
|
||||||
describe('PopupAddOrUpdateAdComponent', () => {
|
|
||||||
let component: PopupAddOrUpdateAdComponent;
|
|
||||||
let fixture: ComponentFixture<PopupAddOrUpdateAdComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PopupAddOrUpdateAdComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PopupAddOrUpdateAdComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,221 +0,0 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
|
||||||
import {Advert} from "../../../utils/interfaces/advert";
|
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ADVERT_VIDE: Advert = {
|
|
||||||
_id: "",
|
|
||||||
userId: "",
|
|
||||||
title: "",
|
|
||||||
url: "",
|
|
||||||
images: [],
|
|
||||||
interests: [],
|
|
||||||
comment: "",
|
|
||||||
views: [],
|
|
||||||
isVisible: true,
|
|
||||||
isActive: true,
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date(),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-popup-add-or-update-ad',
|
|
||||||
templateUrl: './popup-add-or-update-ad.component.html',
|
|
||||||
styleUrls: ['./popup-add-or-update-ad.component.scss']
|
|
||||||
})
|
|
||||||
export class PopupAddOrUpdateAdComponent implements OnInit
|
|
||||||
{
|
|
||||||
advert: any;
|
|
||||||
title: string = "" ;
|
|
||||||
allVideoCategorie = [];
|
|
||||||
allTitle = [];
|
|
||||||
|
|
||||||
tabOfNewImagesBase64 = [];
|
|
||||||
tabOfNewImagesName = [];
|
|
||||||
|
|
||||||
hasError: boolean = false;
|
|
||||||
errorMessage: string = "" ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor( public dialogRef: MatDialogRef<PopupAddOrUpdateAdComponent>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data,
|
|
||||||
private messageService: MessageService,
|
|
||||||
public themeService: ThemeService ) { }
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
this.allVideoCategorie = this.data.allVideoCategorie;
|
|
||||||
this.allTitle = this.data.allTitle.slice();
|
|
||||||
if(this.data.action === "add")
|
|
||||||
{
|
|
||||||
this.advert = Object.assign({}, ADVERT_VIDE);
|
|
||||||
this.advert.images = [];
|
|
||||||
this.advert.interests = [];
|
|
||||||
this.title = "Ajouter annonce" ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.advert = Object.assign({}, this.data.advert);
|
|
||||||
this.advert.interests = this.data.advert.interests.slice();
|
|
||||||
this.title = "Modifier annonce" ;
|
|
||||||
const indexOldTitle = this.allTitle.findIndex(title => title == this.advert.title);
|
|
||||||
this.allTitle.splice(indexOldTitle, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onValidate(): void
|
|
||||||
{
|
|
||||||
this.checkField();
|
|
||||||
if(!this.hasError)
|
|
||||||
{
|
|
||||||
// preparation des donnees
|
|
||||||
this.prepareAdvertInterests();
|
|
||||||
this.prepareAdvertImages();
|
|
||||||
|
|
||||||
// si creation
|
|
||||||
if (this.data.action === "add")
|
|
||||||
{
|
|
||||||
this.messageService
|
|
||||||
.post("ad/create", this.advert)
|
|
||||||
.subscribe(ret => this.onCreateCallback(ret), err => this.onCreateCallback(err));
|
|
||||||
}
|
|
||||||
// si update
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const id = this.advert.id;
|
|
||||||
Reflect.deleteProperty(this.advert, "id");
|
|
||||||
Reflect.deleteProperty(this.advert, "_id");
|
|
||||||
this.messageService
|
|
||||||
.put("ad/update/" + id, this.advert)
|
|
||||||
.subscribe(ret => this.onUpdateCallback(ret, id), err => this.onUpdateCallback(err, id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
checkField()
|
|
||||||
{
|
|
||||||
if(this.advert.title.length === 0) {
|
|
||||||
this.errorMessage = "Veuillez remplir le champ 'titre'." ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else if(this.allTitle.includes(this.advert.title)) {
|
|
||||||
this.errorMessage = "Ce titre est déjà pris." ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else if((this.advert.images.length === 0) && (this.tabOfNewImagesName.length === 0)) {
|
|
||||||
this.errorMessage = "Veuillez uploader au moins une image." ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorMessage = "";
|
|
||||||
this.hasError = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onCreateCallback(retour: any): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.dialogRef.close(retour.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onUpdateCallback(retour: any, id: string): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.advert.id = id;
|
|
||||||
this.dialogRef.close(this.advert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onEventInputTags(myTags: string[]): void
|
|
||||||
{
|
|
||||||
this.advert.interests = myTags;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onRemoveImgAlreadyPresent(image)
|
|
||||||
{
|
|
||||||
const index = this.advert.images.indexOf(image);
|
|
||||||
this.advert.images.splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onReceiveNewImages(files: any): void
|
|
||||||
{
|
|
||||||
this.tabOfNewImagesBase64 = [];
|
|
||||||
this.tabOfNewImagesName = [];
|
|
||||||
if(files)
|
|
||||||
{
|
|
||||||
for(let file of files)
|
|
||||||
{
|
|
||||||
if(file)
|
|
||||||
{
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = this.handleReaderLoaded.bind(this);
|
|
||||||
this.tabOfNewImagesName.push(file.name)
|
|
||||||
reader.readAsBinaryString(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleReaderLoaded(e)
|
|
||||||
{
|
|
||||||
this.tabOfNewImagesBase64.push('data:image/png;base64,' + btoa(e.target.result))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Met bien en forme les "images" avant d'être envoyer
|
|
||||||
prepareAdvertImages(): void
|
|
||||||
{
|
|
||||||
for(let i=0; i<this.tabOfNewImagesName.length ; i++)
|
|
||||||
{
|
|
||||||
let newImagePrepared = {
|
|
||||||
base64: this.tabOfNewImagesBase64[i],
|
|
||||||
url: "",
|
|
||||||
description: this.tabOfNewImagesName[i],
|
|
||||||
type: 0,
|
|
||||||
};
|
|
||||||
this.advert.images.push(newImagePrepared);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Met bien en forme les "interests" avant d'être envoyer
|
|
||||||
prepareAdvertInterests(): void
|
|
||||||
{
|
|
||||||
let interests = [];
|
|
||||||
|
|
||||||
for (let interest of this.advert.interests) {
|
|
||||||
for (let videoCategorie of this.allVideoCategorie) {
|
|
||||||
if (videoCategorie.interest === interest) {
|
|
||||||
interests.push(videoCategorie);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.advert.interests = interests;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<mat-dialog-content class="mat-typography">
|
|
||||||
Êtes-vous sûr de vouloir supprimer l'annonce <i>{{advert.title}}</i> ?
|
|
||||||
</mat-dialog-content>
|
|
||||||
|
|
||||||
<mat-dialog-actions align="end">
|
|
||||||
<button mat-button (click)="dialogRef.close();">Annuler</button>
|
|
||||||
<button mat-button (click)="onValidate()" cdkFocusInitial>Valider</button>
|
|
||||||
</mat-dialog-actions>
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PopupDeleteAdAdvertiserComponent } from './popup-delete-ad-advertiser.component';
|
|
||||||
|
|
||||||
describe('PopupDeleteAdComponent', () => {
|
|
||||||
let component: PopupDeleteAdAdvertiserComponent;
|
|
||||||
let fixture: ComponentFixture<PopupDeleteAdAdvertiserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PopupDeleteAdAdvertiserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PopupDeleteAdAdvertiserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-popup-delete-ad-advertiser',
|
|
||||||
templateUrl: './popup-delete-ad-advertiser.component.html',
|
|
||||||
styleUrls: ['./popup-delete-ad-advertiser.component.scss']
|
|
||||||
})
|
|
||||||
export class PopupDeleteAdAdvertiserComponent implements OnInit
|
|
||||||
{
|
|
||||||
advert: any;
|
|
||||||
|
|
||||||
|
|
||||||
constructor( public dialogRef: MatDialogRef<PopupDeleteAdAdvertiserComponent>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data,
|
|
||||||
private messageService: MessageService) { }
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
this.advert = this.data.advert;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onValidate(): void
|
|
||||||
{
|
|
||||||
this.messageService
|
|
||||||
.delete("ad/delete/"+this.advert.id)
|
|
||||||
.subscribe(ret => this.onValidateCallback(ret), err => this.onValidateCallback(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onValidateCallback(retour: any): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.dialogRef.close(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
<div [class]="themeService.getClassTheme()">
|
|
||||||
|
|
||||||
<h1 mat-dialog-title>{{advert.title}}</h1>
|
|
||||||
|
|
||||||
<!-- ----------------------------------------------------------------------------------------------------------------- -->
|
|
||||||
|
|
||||||
<mat-divider></mat-divider>
|
|
||||||
<mat-dialog-content>
|
|
||||||
|
|
||||||
<!-- Images -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<div class="col-6 myLabel"> Images: </div>
|
|
||||||
<div class="col-6 myValue" style="border-left: solid 1px #e6e6e6">
|
|
||||||
<div *ngFor="let image of advert.images"> {{image.url}} </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Tags -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<div class="col-6 myLabel"> Centre d'intérêt :</div>
|
|
||||||
<div class="col-6 myValue" style="border-left: solid 1px #e6e6e6">
|
|
||||||
<div *ngFor="let tag of advert.interests"> • {{tag}} </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Comment -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<div class="col-6 myLabel"> Commentaire: </div>
|
|
||||||
<div class="col-6 myValue"> {{advert.comment}} </div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Views -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<label class="col-6 myLabel"> Vues: </label>
|
|
||||||
<div class="col-6 myValue"> {{advert.views}} </div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Created at -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<label class="col-6 myLabel"> Date de création: </label>
|
|
||||||
<div class="col-6 myValue">
|
|
||||||
{{ advert.createdAt | date:'dd/LL/YYYY à HH:mm:ss' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Last updtade -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<label class="col-6 myLabel"> Date de dernière modification: </label>
|
|
||||||
<div class="col-6 myValue">
|
|
||||||
{{ advert.updatedAt | date:'dd/LL/YYYY à HH:mm:ss' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- IsVisible -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<label class="col-6 myLabel"> Visibilité: </label>
|
|
||||||
<div class="col-6 myValue">
|
|
||||||
<mat-icon *ngIf="advert.isVisible">checked</mat-icon>
|
|
||||||
<mat-icon *ngIf="!advert.isVisible">close</mat-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</mat-dialog-content>
|
|
||||||
|
|
||||||
<!-- ----------------------------------------------------------------------------------------------------------------- -->
|
|
||||||
|
|
||||||
<mat-dialog-actions align="end">
|
|
||||||
<button mat-button (click)="dialogRef.close()">Fermer</button>
|
|
||||||
</mat-dialog-actions>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
.lightTheme, .darkTheme {
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: xx-large;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.myRow {
|
|
||||||
margin: 15px 0px 15px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.myLabel {
|
|
||||||
text-align: right;
|
|
||||||
padding: 0px 5px 0px 0px;
|
|
||||||
margin: 0px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.myValue {
|
|
||||||
text-align: left;
|
|
||||||
padding: 0px 0px 0px 5px;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PopupVisualizeAdAdvertiserComponent } from './popup-visualize-ad-advertiser.component';
|
|
||||||
|
|
||||||
describe('PopupVisualizeAdComponent', () => {
|
|
||||||
let component: PopupVisualizeAdAdvertiserComponent;
|
|
||||||
let fixture: ComponentFixture<PopupVisualizeAdAdvertiserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PopupVisualizeAdAdvertiserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PopupVisualizeAdAdvertiserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
|
||||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
|
||||||
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
import {Advert} from "../../../utils/interfaces/advert";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-popup-visualize-ad-advertiser',
|
|
||||||
templateUrl: './popup-visualize-ad-advertiser.component.html',
|
|
||||||
styleUrls: ['./popup-visualize-ad-advertiser.component.scss']
|
|
||||||
})
|
|
||||||
export class PopupVisualizeAdAdvertiserComponent implements OnInit
|
|
||||||
{
|
|
||||||
advert: Advert;
|
|
||||||
|
|
||||||
constructor( public dialogRef: MatDialogRef<PopupVisualizeAdAdvertiserComponent>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data,
|
|
||||||
public themeService: ThemeService,
|
|
||||||
public dialog: MatDialog ) { }
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
this.advert = this.data.advert;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<div mat-dialog-title class="dialog-title">
|
|
||||||
<h2></h2>
|
|
||||||
<button mat-icon-button aria-label="close dialog" mat-dialog-close>
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<mat-grid-list cols="12" rowHeight="500">
|
|
||||||
<mat-grid-tile colspan="1" rowspan="1" (click)="onPrecedent()">
|
|
||||||
<button> < </button>
|
|
||||||
</mat-grid-tile>
|
|
||||||
<mat-grid-tile colspan="10" rowspan="1">
|
|
||||||
<img [src]="tabImages[index].base64" [alt]="tabImages[index].description">
|
|
||||||
</mat-grid-tile>
|
|
||||||
<mat-grid-tile colspan="1" rowspan="1" (click)="onSuivant()">
|
|
||||||
<button> > </button>
|
|
||||||
</mat-grid-tile>
|
|
||||||
</mat-grid-list>
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
carousel {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0 auto;
|
|
||||||
text-align: center;
|
|
||||||
justify-content: center
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.dialog-title {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PopupVisualizeImagesAdvertiserComponent } from './popup-visualize-images-advertiser.component';
|
|
||||||
|
|
||||||
describe('PopupVisualizeImagesComponent', () => {
|
|
||||||
let component: PopupVisualizeImagesAdvertiserComponent;
|
|
||||||
let fixture: ComponentFixture<PopupVisualizeImagesAdvertiserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PopupVisualizeImagesAdvertiserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PopupVisualizeImagesAdvertiserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-popup-visualize-images-advertiser',
|
|
||||||
templateUrl: './popup-visualize-images-advertiser.component.html',
|
|
||||||
styleUrls: ['./popup-visualize-images-advertiser.component.scss']
|
|
||||||
})
|
|
||||||
export class PopupVisualizeImagesAdvertiserComponent implements OnInit
|
|
||||||
{
|
|
||||||
tabImages = [];
|
|
||||||
index: number = 0;
|
|
||||||
nbImage: number = 0;
|
|
||||||
|
|
||||||
|
|
||||||
constructor( public dialogRef: MatDialogRef<PopupVisualizeImagesAdvertiserComponent>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data ) { }
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
this.tabImages = this.data.images;
|
|
||||||
this.nbImage = this.tabImages.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
onPrecedent(): void
|
|
||||||
{
|
|
||||||
if(this.index !== 0) this.index -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuivant(): void
|
|
||||||
{
|
|
||||||
if(this.index !== (this.nbImage-1)) this.index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
<div [class]="themeService.getClassTheme()">
|
|
||||||
<div class="myContainer">
|
|
||||||
|
|
||||||
<!-- NavBar -->
|
|
||||||
<app-navbar-advertiser></app-navbar-advertiser>
|
|
||||||
|
|
||||||
<!-- Boite -->
|
|
||||||
<div class="boite">
|
|
||||||
|
|
||||||
<!-- Photo de profil -->
|
|
||||||
<div style="text-align: center">
|
|
||||||
<img [src]="advertiser.profileImageUrl"
|
|
||||||
onerror="this.onerror=null; this.src='assets/profil.png'">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- entreprise -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<div class="col-6 myLabel">Entreprise:</div>
|
|
||||||
<div class="col-6 myValue"> {{advertiser.company}} </div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- login -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<div class="col-6 myLabel">Pseudo:</div>
|
|
||||||
<div class="col-6 myValue"> {{advertiser.login}} </div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- email -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<div class="col-6 myLabel">Mail:</div>
|
|
||||||
<div class="col-6 myValue"> {{advertiser.email}} </div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- createdAt -->
|
|
||||||
<div class="row myRow">
|
|
||||||
<div class="col-6 myLabel">Date de création:</div>
|
|
||||||
<div class="col-6 myValue">{{advertiser.createdAt | date:'dd/LL/YYYY'}}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Modifier profil -->
|
|
||||||
<div class="btnContainer">
|
|
||||||
<button mat-button class="myBtn" (click)="onModifier()">Modifier profil</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
.myContainer {
|
|
||||||
max-width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.boite {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
width: 25%;
|
|
||||||
margin-top: 10vh;
|
|
||||||
border: solid 3px;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 20px 40px 20px 40px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 10px 5px 5px black;
|
|
||||||
}
|
|
||||||
.lightTheme .boite {
|
|
||||||
border-color: black;
|
|
||||||
}
|
|
||||||
.darkTheme .boite {
|
|
||||||
border-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin: 0px 0px 10px 0px;
|
|
||||||
width: 5vw;
|
|
||||||
height: 5vw;
|
|
||||||
border: solid 2px black;
|
|
||||||
border-radius: 50%;
|
|
||||||
font-size: xxx-large;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.myRow {
|
|
||||||
margin: 15px 0px 15px 0px;
|
|
||||||
}
|
|
||||||
.myLabel {
|
|
||||||
text-align: right;
|
|
||||||
padding: 0px 5px 0px 0px;
|
|
||||||
margin: 0px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.myValue {
|
|
||||||
text-align: left;
|
|
||||||
padding: 0px 0px 0px 5px;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.btnContainer {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
.myBtn {
|
|
||||||
border: solid 1px black;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PageProfilAdvertiserComponent } from './page-profil-advertiser.component';
|
|
||||||
|
|
||||||
describe('PageProfilAdvertiserComponent', () => {
|
|
||||||
let component: PageProfilAdvertiserComponent;
|
|
||||||
let fixture: ComponentFixture<PageProfilAdvertiserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PageProfilAdvertiserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PageProfilAdvertiserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import {User} from "../../../utils/interfaces/user";
|
|
||||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
|
||||||
import {PopupUpdateAdvertiserComponent} from "../popup-update-advertiser/popup-update-advertiser.component";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
import {ProfilService} from "../../../utils/services/profil/profil.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-page-profil-advertiser',
|
|
||||||
templateUrl: './page-profil-advertiser.component.html',
|
|
||||||
styleUrls: ['./page-profil-advertiser.component.scss']
|
|
||||||
})
|
|
||||||
export class PageProfilAdvertiserComponent implements OnInit
|
|
||||||
{
|
|
||||||
advertiser: User = {
|
|
||||||
_id: "",
|
|
||||||
login: "",
|
|
||||||
hashPass: "",
|
|
||||||
email: "",
|
|
||||||
role: {
|
|
||||||
name: "advertiser",
|
|
||||||
permission: 5,
|
|
||||||
isAccepted: true,
|
|
||||||
},
|
|
||||||
profileImageUrl: "",
|
|
||||||
dateOfBirth: null,
|
|
||||||
gender: "man",
|
|
||||||
interests: [],
|
|
||||||
company: "",
|
|
||||||
isActive: true,
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date(),
|
|
||||||
lastConnexion: null
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
constructor( public themeService: ThemeService,
|
|
||||||
public dialog: MatDialog,
|
|
||||||
private snackBar: MatSnackBar,
|
|
||||||
private messageService: MessageService,
|
|
||||||
private profilService: ProfilService ) { }
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
this.messageService
|
|
||||||
.get( "user/findOne/"+this.profilService.getId())
|
|
||||||
.subscribe( retour => this.ngOnInitCallback(retour), err => this.ngOnInitCallback(err) )
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInitCallback(retour: any)
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.advertiser = retour.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onModifier()
|
|
||||||
{
|
|
||||||
const config = {
|
|
||||||
width: '25%',
|
|
||||||
data: { advertiser: this.advertiser }
|
|
||||||
};
|
|
||||||
this.dialog
|
|
||||||
.open(PopupUpdateAdvertiserComponent, config)
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe(retour => {
|
|
||||||
|
|
||||||
if((retour === null) || (retour === undefined))
|
|
||||||
{
|
|
||||||
const config = { duration: 1000, panelClass: "custom-class" };
|
|
||||||
this.snackBar.open( "Opération annulé", "", config);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.advertiser = retour;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
<div class="myContainer">
|
|
||||||
<div class="boite">
|
|
||||||
|
|
||||||
<!-- photo de profil -->
|
|
||||||
<div style="text-align: center">
|
|
||||||
<img [src]="advertiserCopy.profileImageUrl" onerror="this.onerror=null; this.src='assets/profil.png'"><br>
|
|
||||||
<input title="lien vers image" type="text" [(ngModel)]="advertiserCopy.profileImageUrl" style="width: 90%">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- divider -->
|
|
||||||
<br><mat-divider></mat-divider><br>
|
|
||||||
|
|
||||||
<!-- entreprise -->
|
|
||||||
<mat-form-field appearance="fill">
|
|
||||||
<mat-label>Entreprise</mat-label>
|
|
||||||
<input matInput type="text" [(ngModel)]="advertiserCopy.company">
|
|
||||||
</mat-form-field><br>
|
|
||||||
|
|
||||||
<!-- login -->
|
|
||||||
<mat-form-field appearance="fill">
|
|
||||||
<mat-label>Pseudo</mat-label>
|
|
||||||
<input matInput type="text" [(ngModel)]="advertiserCopy.login">
|
|
||||||
</mat-form-field><br>
|
|
||||||
|
|
||||||
<!-- divider -->
|
|
||||||
<mat-divider></mat-divider><br>
|
|
||||||
|
|
||||||
<!-- Modifier mot de passe -->
|
|
||||||
<div>
|
|
||||||
Modifier mot de passe:
|
|
||||||
<mat-checkbox [(ngModel)]="changePassword"></mat-checkbox>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- nouveau mot de passe -->
|
|
||||||
<div *ngIf="changePassword" style="margin-top: 10px">
|
|
||||||
<!-- Nouveau mot de passe -->
|
|
||||||
<mat-form-field appearance="fill">
|
|
||||||
<mat-label>Nouveau mot de passe</mat-label>
|
|
||||||
<input matInput type="password" [(ngModel)]="newPassword">
|
|
||||||
</mat-form-field>
|
|
||||||
<br>
|
|
||||||
<!-- Confirmation nouveau mot de passe -->
|
|
||||||
<mat-form-field appearance="fill">
|
|
||||||
<mat-label>Confirmation nouveau mot de passe</mat-label>
|
|
||||||
<input matInput type="password" [(ngModel)]="confirmNewPassword">
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!changePassword"><br></div>
|
|
||||||
|
|
||||||
<!-- divider -->
|
|
||||||
<mat-divider></mat-divider><br>
|
|
||||||
|
|
||||||
<!-- message d'erreur -->
|
|
||||||
<div *ngIf="hasError" style="text-align: center; margin-bottom: 20px;">
|
|
||||||
<span class="mat-error">{{errorMessage}}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- boutons -->
|
|
||||||
<div style="width: 100%; text-align: right">
|
|
||||||
<button mat-button (click)="this.dialogRef.close(null)"> Annuler </button>
|
|
||||||
<button mat-button (click)="onValider()"> Enregistrer </button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
.boite {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin: 0px 0px 10px 0px;
|
|
||||||
width: 5vw;
|
|
||||||
height: 5vw;
|
|
||||||
border: solid 2px black;
|
|
||||||
border-radius: 50%;
|
|
||||||
font-size: xxx-large;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// aura
|
|
||||||
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
|
|
||||||
background-color: grey !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contenu coche
|
|
||||||
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
|
|
||||||
background-color: black !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// indeterminate
|
|
||||||
::ng-deep .mat-checkbox .mat-checkbox-frame {
|
|
||||||
background-color: white !important;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PopupUpdateAdvertiserComponent } from './popup-update-advertiser.component';
|
|
||||||
|
|
||||||
describe('PopupUpdateAdvertiserComponent', () => {
|
|
||||||
let component: PopupUpdateAdvertiserComponent;
|
|
||||||
let fixture: ComponentFixture<PopupUpdateAdvertiserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PopupUpdateAdvertiserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PopupUpdateAdvertiserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
import {Component, Inject, OnInit} from '@angular/core';
|
|
||||||
import {User} from "../../../utils/interfaces/user";
|
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
import {ProfilService} from "../../../utils/services/profil/profil.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-popup-update-advertiser',
|
|
||||||
templateUrl: './popup-update-advertiser.component.html',
|
|
||||||
styleUrls: ['./popup-update-advertiser.component.scss']
|
|
||||||
})
|
|
||||||
export class PopupUpdateAdvertiserComponent implements OnInit
|
|
||||||
{
|
|
||||||
advertiserCopy: User;
|
|
||||||
newPassword: string = "";
|
|
||||||
confirmNewPassword: string = "" ;
|
|
||||||
changePassword: boolean = false ;
|
|
||||||
hasError: boolean = false;
|
|
||||||
errorMessage: string = "" ;
|
|
||||||
|
|
||||||
|
|
||||||
constructor( public dialogRef: MatDialogRef<PopupUpdateAdvertiserComponent>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data,
|
|
||||||
private messageService: MessageService,
|
|
||||||
private profilService: ProfilService ) { }
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
const advertiser0 = this.data.advertiser;
|
|
||||||
this.advertiserCopy = {
|
|
||||||
_id: advertiser0._id,
|
|
||||||
login: advertiser0.login,
|
|
||||||
hashPass: advertiser0.hashPass,
|
|
||||||
email: advertiser0.email,
|
|
||||||
role: {
|
|
||||||
name: advertiser0.role.name,
|
|
||||||
permission: advertiser0.role.permission,
|
|
||||||
isAccepted: advertiser0.role.isAccepted,
|
|
||||||
},
|
|
||||||
profileImageUrl: advertiser0.profileImageUrl,
|
|
||||||
dateOfBirth: advertiser0.dateOfBirth,
|
|
||||||
gender: advertiser0.gender,
|
|
||||||
interests: [],
|
|
||||||
company: advertiser0.company,
|
|
||||||
isActive: advertiser0.isActive,
|
|
||||||
createdAt: advertiser0.createdAt,
|
|
||||||
updatedAt: advertiser0.updatedAt,
|
|
||||||
lastConnexion: new Date()
|
|
||||||
};
|
|
||||||
for(let interest of advertiser0.interests) this.advertiserCopy.interests.push(interest);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onValider()
|
|
||||||
{
|
|
||||||
this.checkField();
|
|
||||||
if(!this.hasError)
|
|
||||||
{
|
|
||||||
if(this.changePassword) this.advertiserCopy.hashPass = this.newPassword;
|
|
||||||
const data = {
|
|
||||||
login: this.advertiserCopy.login,
|
|
||||||
hashPass: this.advertiserCopy.hashPass,
|
|
||||||
email: this.advertiserCopy.email,
|
|
||||||
profileImageUrl: this.advertiserCopy.profileImageUrl,
|
|
||||||
company: this.advertiserCopy.company
|
|
||||||
};
|
|
||||||
this.messageService
|
|
||||||
.put("user/update/"+this.profilService.getId(), data)
|
|
||||||
.subscribe( ret => this.onValiderCallback(ret), err => this.onValiderCallback(err) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onValiderCallback(retour: any)
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
this.dialogRef.close(null);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.profilService.setProfileImageUrl(this.advertiserCopy.profileImageUrl);
|
|
||||||
this.dialogRef.close(this.advertiserCopy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
checkField()
|
|
||||||
{
|
|
||||||
if(this.advertiserCopy.login.length === 0) {
|
|
||||||
this.errorMessage = "Veuillez remplir le champ 'pseudo'" ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else if(this.advertiserCopy.email.length === 0) {
|
|
||||||
this.errorMessage = "Veuillez remplir le champ 'email'" ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else if(!this.isValidEmail(this.advertiserCopy.email)) {
|
|
||||||
this.errorMessage = "Email invalide" ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else if((this.changePassword) && (this.newPassword.length === 0)) {
|
|
||||||
this.errorMessage = "Veuillez remplir le champ 'mot de passe'" ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else if((this.changePassword) && (this.newPassword !== this.confirmNewPassword)) {
|
|
||||||
this.errorMessage = "Le mot de passe est différent de sa confirmation" ;
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorMessage = "" ;
|
|
||||||
this.hasError = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
isValidEmail(email)
|
|
||||||
{
|
|
||||||
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
||||||
return re.test(email);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
<div [class]="themeService.getClassTheme()">
|
|
||||||
<div class="myContainer">
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Navbar -->
|
|
||||||
<app-navbar-advertiser></app-navbar-advertiser>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Filter -->
|
|
||||||
<div class="filtersContainer mat-elevation-z8">
|
|
||||||
|
|
||||||
<div style="font-weight: bold;">Filtre</div>
|
|
||||||
|
|
||||||
<mat-divider></mat-divider><br>
|
|
||||||
|
|
||||||
<div *ngIf="true; then colPeriode"></div>
|
|
||||||
|
|
||||||
<br><mat-divider style="width: 60%"></mat-divider><br>
|
|
||||||
|
|
||||||
<div style="text-align: right; font-size: small;">
|
|
||||||
<button mat-button (click)="onApplyFilter()" style="font-size: small">Appliquer</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- chart -->
|
|
||||||
<div *ngIf="isDisplayable" class="chartContainer">
|
|
||||||
<canvas baseChart
|
|
||||||
[datasets]="lineChartData"
|
|
||||||
[labels]="lineChartLabels"
|
|
||||||
[options]="chartOptions"
|
|
||||||
[colors]="[]"
|
|
||||||
[legend]="true"
|
|
||||||
[chartType]="'line'">
|
|
||||||
</canvas>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ------------------------------------------------------------------------------------------------------------------- -->
|
|
||||||
|
|
||||||
|
|
||||||
<ng-template #colPeriode>
|
|
||||||
|
|
||||||
<!-- startDate -->
|
|
||||||
<mat-form-field appearance="fill" style="width: 140px;">
|
|
||||||
<mat-label>début</mat-label>
|
|
||||||
<input matInput type="date" [ngModel] ="startDate | date:'yyyy-MM-dd'" (ngModelChange)="onNewStartDate($event);">
|
|
||||||
</mat-form-field>
|
|
||||||
-
|
|
||||||
|
|
||||||
<!-- endDate -->
|
|
||||||
<mat-form-field appearance="fill" style="width: 140px;">
|
|
||||||
<mat-label>fin</mat-label>
|
|
||||||
<input matInput type="date" [ngModel] ="endDate | date:'yyyy-MM-dd'" (ngModelChange)="onNewEndDate($event);">
|
|
||||||
</mat-form-field>
|
|
||||||
-
|
|
||||||
|
|
||||||
<!-- step -->
|
|
||||||
<mat-form-field appearance="fill" style="width: 140px;">
|
|
||||||
<mat-label>pas d'affichage</mat-label>
|
|
||||||
<input matInput type="number" [(ngModel)] =step>
|
|
||||||
</mat-form-field>
|
|
||||||
-
|
|
||||||
|
|
||||||
<!-- step unity -->
|
|
||||||
<mat-form-field appearance="fill">
|
|
||||||
<mat-label>unité du pas d'affichage</mat-label>
|
|
||||||
<mat-select [(ngModel)]="stepUnity">
|
|
||||||
<mat-option value="jour">jour</mat-option>
|
|
||||||
<mat-option value="semaine">semaine</mat-option>
|
|
||||||
<mat-option value="mois">mois</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field><br>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ads -->
|
|
||||||
<mat-select [formControl]="formControl" multiple style="padding-top: 10px; width: 60%;">
|
|
||||||
<mat-select-trigger>
|
|
||||||
<span *ngIf="formControl.value?.length > 0">
|
|
||||||
<span *ngFor="let coupleNameViews of formControl.value"> {{coupleNameViews.name}}, </span>
|
|
||||||
</span>
|
|
||||||
</mat-select-trigger>
|
|
||||||
<mat-option *ngFor="let coupleNameViews of allCoupleNameViews" [value]="coupleNameViews">{{coupleNameViews.name}}</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
<button mat-button class="btnToutSelectionner" (click)="onSelectAll()">Tout sélectionner</button>
|
|
||||||
<button mat-button class="btnToutDeselectionner" (click)="onDeSelectAll()">Tout désélectionner</button>
|
|
||||||
|
|
||||||
</ng-template>
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
.myContainer {
|
|
||||||
font-size: small;
|
|
||||||
max-width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
font-size: small;
|
|
||||||
width: 140px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filtersContainer {
|
|
||||||
background-color: white;
|
|
||||||
width: 60%;
|
|
||||||
margin: 50px 50px 50px 50px;
|
|
||||||
padding: 20px 20px 20px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chartContainer {
|
|
||||||
background-color: white;
|
|
||||||
border: solid 1px black;
|
|
||||||
padding: 10px 10px 10px 10px;
|
|
||||||
margin: 50px 50px 50px 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------
|
|
||||||
// periode
|
|
||||||
|
|
||||||
.periode {
|
|
||||||
padding: 10px 10px 0px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.periode .titleContainer {
|
|
||||||
text-align: right;
|
|
||||||
border-right: solid 1px #dcdcdc;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btnToutSelectionner {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
.btnToutDeselectionner {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
::ng-deep .mat-pseudo-checkbox-checked {
|
|
||||||
background-color: black !important;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PagesPopularityComponent } from './pages-popularity.component';
|
|
||||||
|
|
||||||
describe('SubjectsPopularityComponent', () => {
|
|
||||||
let component: PagesPopularityComponent;
|
|
||||||
let fixture: ComponentFixture<PagesPopularityComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PagesPopularityComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PagesPopularityComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,308 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import {FormControl} from "@angular/forms";
|
|
||||||
import {ChartDataSets} from "chart.js";
|
|
||||||
import {Label} from "ng2-charts";
|
|
||||||
import { Router} from "@angular/router";
|
|
||||||
import {FictitiousAdvertsService} from "../../utils/services/fictitiousDatas/fictitiousAdverts/fictitious-adverts.service";
|
|
||||||
import {FictitiousVideosService} from "../../utils/services/fictitiousDatas/fictitiousVideos/fictitious-videos.service";
|
|
||||||
import {ThemeService} from "../../utils/services/theme/theme.service";
|
|
||||||
import {MessageService} from "../../utils/services/message/message.service";
|
|
||||||
import {HttpParams} from "@angular/common/http";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
interface CoupleNameViews {
|
|
||||||
name: string,
|
|
||||||
views: Date[],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-subjects-popularity',
|
|
||||||
templateUrl: './pages-popularity.component.html',
|
|
||||||
styleUrls: ['./pages-popularity.component.scss']
|
|
||||||
})
|
|
||||||
export class PagesPopularityComponent implements OnInit
|
|
||||||
{
|
|
||||||
formControl: FormControl = new FormControl();
|
|
||||||
allCoupleNameViews: CoupleNameViews[] = [];
|
|
||||||
|
|
||||||
allInterests: string[] = [];
|
|
||||||
|
|
||||||
startDate: Date = null;
|
|
||||||
endDate: Date = null;
|
|
||||||
step: number = 1;
|
|
||||||
stepUnity: string = "jour" ;
|
|
||||||
|
|
||||||
oneDay: number = 24*60*60*1000;
|
|
||||||
oneWeek: number = 7*24*60*60*1000;
|
|
||||||
|
|
||||||
lineChartData: ChartDataSets[] = [];
|
|
||||||
lineChartLabels: Label[] = [];
|
|
||||||
chartOptions: any = {
|
|
||||||
responsive: true,
|
|
||||||
scales: {
|
|
||||||
yAxes: [{ display: true, scaleLabel: { display: true, labelString: "vues" } }],
|
|
||||||
xAxes: [{ scaleLabel: { display: true, labelString: "temps" } }],
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
isDisplayable: boolean = false;
|
|
||||||
|
|
||||||
|
|
||||||
constructor( private router: Router,
|
|
||||||
public themeService: ThemeService,
|
|
||||||
private fictitiousAdvertsService: FictitiousAdvertsService,
|
|
||||||
private fictitiousVideosService: FictitiousVideosService,
|
|
||||||
private messageService: MessageService ) {}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void
|
|
||||||
{
|
|
||||||
// Sera excuté si on est sur la page 'adsPopularity'
|
|
||||||
// Remplie l'attribut 'allCoupleNameViews'
|
|
||||||
if(this.router.url.includes("ads"))
|
|
||||||
{
|
|
||||||
let params = new HttpParams();
|
|
||||||
params = params.append("isActive", true);
|
|
||||||
this.messageService
|
|
||||||
.get("ad/findAll", params )
|
|
||||||
.subscribe(ret => this.afterReceivingAds(ret), err => this.afterReceivingAds(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sera excuté si on est sur la page 'subjectsPopularity'
|
|
||||||
// Remplie l'attribut 'allCoupleNameViews'
|
|
||||||
else if(this.router.url.includes("subjects"))
|
|
||||||
{
|
|
||||||
this.messageService
|
|
||||||
.get("misc/getInterests")
|
|
||||||
.subscribe( retour => {
|
|
||||||
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.allInterests = retour.data.map(x => x.interest);
|
|
||||||
this.allInterests.sort();
|
|
||||||
this.messageService
|
|
||||||
.get("video/findAll")
|
|
||||||
.subscribe(ret => this.afterReceivingVideos(ret), err => this.afterReceivingVideos(err));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Callback: Sera excuté si on est sur la page 'adsPopularity'
|
|
||||||
afterReceivingAds(retour: any): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const allAdverts = retour.data;
|
|
||||||
for(let advert of allAdverts)
|
|
||||||
{
|
|
||||||
let couple = {name: advert.title, views: advert.views }
|
|
||||||
this.allCoupleNameViews.push(couple);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.formControl = new FormControl(this.allCoupleNameViews);
|
|
||||||
this.onApplyFilter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Callback: Sera excuté si on est sur la page 'subjectsPopularity'
|
|
||||||
afterReceivingVideos(retour: any): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") {
|
|
||||||
console.log(retour);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const allVideos = retour.data;
|
|
||||||
let myMap: Map<string,Date[]> = new Map();
|
|
||||||
|
|
||||||
// parcours des interest de chaque video
|
|
||||||
for(let video of allVideos)
|
|
||||||
{
|
|
||||||
const key = video.interest;
|
|
||||||
if(!myMap.has(key)) myMap.set(key, video.watchedDates);
|
|
||||||
else {
|
|
||||||
let tabDate = myMap.get(key);
|
|
||||||
for(let date0 of video.watchedDates) tabDate = this.insertInOrder(tabDate, date0);
|
|
||||||
myMap.set(key, tabDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parcours les interest qui n'ont pas p été vu dans les videos
|
|
||||||
for(let interest of this.allInterests)
|
|
||||||
{
|
|
||||||
if(!myMap.has(interest)) myMap.set(interest, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
// parcours de la map pour remplir 'allCoupleNameViews'
|
|
||||||
for(const [key, value] of myMap.entries())
|
|
||||||
{
|
|
||||||
let couple = {name: key, views: value }
|
|
||||||
this.allCoupleNameViews.push(couple);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.formControl = new FormControl(this.allCoupleNameViews);
|
|
||||||
this.onApplyFilter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// Applique le filtre
|
|
||||||
onApplyFilter(): void
|
|
||||||
{
|
|
||||||
// --- initialisation ---
|
|
||||||
this.lineChartData = [];
|
|
||||||
this.lineChartLabels = [];
|
|
||||||
|
|
||||||
if(this.step <= 0) this.step = 0;
|
|
||||||
if((this.endDate === null) || (this.endDate === undefined)) this.endDate = new Date();
|
|
||||||
if((this.startDate === null) || (this.startDate === undefined)) this.startDate = new Date(this.endDate.getTime() - this.oneWeek); // date d'il y a une semaine
|
|
||||||
|
|
||||||
const startTime = this.startDate.getTime();
|
|
||||||
const endTime = this.endDate.getTime();
|
|
||||||
|
|
||||||
|
|
||||||
// --- remplissage de 'lineChartLabels' ---
|
|
||||||
let dataWithZeros = [];
|
|
||||||
let time = startTime;
|
|
||||||
const intervals = [];
|
|
||||||
while(time <= endTime)
|
|
||||||
{
|
|
||||||
dataWithZeros.push(0);
|
|
||||||
this.lineChartLabels.push(this.getLabel(new Date(time)));
|
|
||||||
intervals.push(time);
|
|
||||||
time = this.addStep(time);
|
|
||||||
}
|
|
||||||
intervals.push(time);
|
|
||||||
|
|
||||||
|
|
||||||
// --- remplissage de 'lineChartLabels' ---
|
|
||||||
for(let coupleNameViews of this.formControl.value)
|
|
||||||
{
|
|
||||||
let data = dataWithZeros.slice();
|
|
||||||
let label = coupleNameViews.name;
|
|
||||||
let index = 0;
|
|
||||||
|
|
||||||
for(let date0 of coupleNameViews.views)
|
|
||||||
{
|
|
||||||
const time0 = (new Date(date0)).getTime();
|
|
||||||
|
|
||||||
if(time0 > endTime) break;
|
|
||||||
|
|
||||||
if((startTime <= time0) && (time0 <= endTime))
|
|
||||||
{
|
|
||||||
while((index < intervals.length) && (time0 >= intervals[index])) index += 1;
|
|
||||||
index = index - 1;
|
|
||||||
data[index] += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lineChartData.push({"data": data.slice(), "label": label});
|
|
||||||
}
|
|
||||||
this.isDisplayable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onNewStartDate(event): void {
|
|
||||||
this.startDate = new Date(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onNewEndDate(event): void {
|
|
||||||
this.endDate = new Date(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Renvoie le bon label pour le graph
|
|
||||||
getLabel(date0: Date): string
|
|
||||||
{
|
|
||||||
if((this.stepUnity === 'jour') && (this.step === 1))
|
|
||||||
{
|
|
||||||
return date0.toLocaleDateString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const time2 = this.addStep((new Date(date0)).getTime()) - this.oneDay;
|
|
||||||
let date2 = new Date(time2);
|
|
||||||
return date0.toLocaleDateString() + " à " + date2.toLocaleDateString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Ajoute le bon pas à la date 'new Date(time)'
|
|
||||||
addStep(time: number): number
|
|
||||||
{
|
|
||||||
let newDate;
|
|
||||||
|
|
||||||
if(this.stepUnity === 'jour') {
|
|
||||||
newDate = new Date(time + this.step*this.oneDay);
|
|
||||||
}
|
|
||||||
else if(this.stepUnity === 'semaine') {
|
|
||||||
newDate = new Date(time + this.step*this.oneWeek);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const oldDate = new Date(time);
|
|
||||||
|
|
||||||
let newMonth = oldDate.getMonth() + this.step;
|
|
||||||
const newYear = oldDate.getFullYear() + (newMonth / 12);
|
|
||||||
newMonth = newMonth % 12;
|
|
||||||
const day = this.startDate.getDate();
|
|
||||||
|
|
||||||
if((newMonth === 1) && ([29, 30, 31].includes(day))) { // si fevrier et si jour n'existe pas
|
|
||||||
newDate = new Date(newYear, newMonth, 28);
|
|
||||||
}
|
|
||||||
else if((day === 31) && ([3, 5, 9, 10].includes(newMonth))) { // si 31 et mois à 30 jours
|
|
||||||
newDate = new Date(newYear, newMonth, 30);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
newDate = new Date(newYear, newMonth, day);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const _1h = 60*60*1000;
|
|
||||||
if(newDate.getHours() === 23) return newDate.getTime() + _1h;
|
|
||||||
else if(newDate.getHours() === 1) return newDate.getTime() - _1h;
|
|
||||||
else return newDate.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Insere la date0 dans le tableau tabDate par ordre croissant
|
|
||||||
insertInOrder(tabDate: Date[], date0: Date): Date[]
|
|
||||||
{
|
|
||||||
let i = 0;
|
|
||||||
let n = tabDate.length;
|
|
||||||
let time0 = (new Date(date0)).getTime();
|
|
||||||
|
|
||||||
while((i <n) && (time0 > (new Date(tabDate[i])).getTime())) i++;
|
|
||||||
if(i === n) tabDate.push(date0);
|
|
||||||
else tabDate.splice(i, 0, date0);
|
|
||||||
|
|
||||||
return tabDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onSelectAll(): void
|
|
||||||
{
|
|
||||||
this.formControl = new FormControl(this.allCoupleNameViews);
|
|
||||||
}
|
|
||||||
|
|
||||||
onDeSelectAll(): void
|
|
||||||
{
|
|
||||||
this.formControl = new FormControl([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import { DragAndDropDirective } from './drag-and-drop.directive';
|
|
||||||
|
|
||||||
describe('DragAndDropDirective', () => {
|
|
||||||
it('should create an instance', () => {
|
|
||||||
const directive = new DragAndDropDirective();
|
|
||||||
expect(directive).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
import {Directive, EventEmitter, HostBinding, HostListener, Output} from '@angular/core';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[appDragAndDrop]'
|
|
||||||
})
|
|
||||||
export class DragAndDropDirective
|
|
||||||
{
|
|
||||||
@HostBinding('class.fileover') fileOver: boolean;
|
|
||||||
@Output() fileDropped = new EventEmitter<any>();
|
|
||||||
|
|
||||||
// Dragover listener
|
|
||||||
@HostListener('dragover', ['$event']) onDragOver(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
evt.stopPropagation();
|
|
||||||
this.fileOver = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dragleave listener
|
|
||||||
@HostListener('dragleave', ['$event']) public onDragLeave(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
evt.stopPropagation();
|
|
||||||
this.fileOver = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop listener
|
|
||||||
@HostListener('drop', ['$event']) public ondrop(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
evt.stopPropagation();
|
|
||||||
this.fileOver = false;
|
|
||||||
let files = evt.dataTransfer.files;
|
|
||||||
if (files.length > 0) {
|
|
||||||
this.fileDropped.emit(files);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
<nav class="navbar navbar-expand-lg">
|
|
||||||
|
|
||||||
<!-- PolyNotFound -->
|
|
||||||
<a class="navbar-brand" routerLink="/url/adList"> StreamNotFound </a>
|
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- [adList] [adsPopularity] [subjectsPopularity] -->
|
|
||||||
<div class="collapse navbar-collapse">
|
|
||||||
<ul class="navbar-nav">
|
|
||||||
<li class="nav-item active monLi">
|
|
||||||
<a *ngIf="(url !== routes[0]) && (url !== routes[1])" [routerLink]="routes[1]" class="nav-link">Gestion des annonces</a>
|
|
||||||
<a *ngIf="(url === routes[0]) || (url === routes[1])" [routerLink]="routes[1]" class="nav-link myActiveLink">Gestion des annonces</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active monLi">
|
|
||||||
<a *ngIf="url !== routes[2]" [routerLink]="routes[2]" class="nav-link">Popularité des annonces</a>
|
|
||||||
<a *ngIf="url === routes[2]" [routerLink]="routes[2]" class="nav-link myActiveLink">Popularité des annonces</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active monLi">
|
|
||||||
<a *ngIf="url !== routes[3]" [routerLink]="routes[3]" class="nav-link">Popularité des domaines</a>
|
|
||||||
<a *ngIf="url === routes[3]" [routerLink]="routes[3]" class="nav-link myActiveLink">Popularité des domaines</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Mon profil -->
|
|
||||||
<img [src]=profilService.getProfileImageUrl()
|
|
||||||
onerror="this.onerror=null; this.src='assets/profil.png'"
|
|
||||||
[routerLink]="routes[4]"
|
|
||||||
alt="">
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Deconnexion -->
|
|
||||||
<button mat-button class="btnDeconnexion" (click)="onDeconnexion()" routerLink="/">
|
|
||||||
Déconnexion
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</nav>
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
.navbar {
|
|
||||||
background-color: black;
|
|
||||||
height: 60px;
|
|
||||||
font-size: medium;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.navbar-expand-lg {
|
|
||||||
border-bottom: solid;
|
|
||||||
border-color: white;
|
|
||||||
border-bottom-width: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// PolyNotFound
|
|
||||||
.navbar-brand {
|
|
||||||
font-family: cursive;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: x-large;
|
|
||||||
margin-left: 15px;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.monLi {
|
|
||||||
margin: 0px 10px 0px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.nav-link:hover {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
.myActiveLink {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.btnDeconnexion {
|
|
||||||
font-size: medium;
|
|
||||||
margin: 0px 10px 0px 10px
|
|
||||||
}
|
|
||||||
.btnDeconnexion:hover {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
img {
|
|
||||||
border: solid 2px white;
|
|
||||||
border-radius: 50px;
|
|
||||||
margin: 0px 10px 0px 15px;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
img:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
::ng-deep .mat-slide-toggle-thumb {
|
|
||||||
background-color: #c8c8c8;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .mat-slide-toggle-bar {
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb {
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar {
|
|
||||||
background-color: #646464;
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { NavbarAdvertiserComponent } from './navbar-advertiser.component';
|
|
||||||
|
|
||||||
describe('NavbarAdvertiserComponent', () => {
|
|
||||||
let component: NavbarAdvertiserComponent;
|
|
||||||
let fixture: ComponentFixture<NavbarAdvertiserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ NavbarAdvertiserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(NavbarAdvertiserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
import {Router} from "@angular/router";
|
|
||||||
import {ProfilService} from "../../../utils/services/profil/profil.service";
|
|
||||||
import {MessageService} from "../../../utils/services/message/message.service";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-navbar-advertiser',
|
|
||||||
templateUrl: './navbar-advertiser.component.html',
|
|
||||||
styleUrls: ['./navbar-advertiser.component.scss']
|
|
||||||
})
|
|
||||||
export class NavbarAdvertiserComponent
|
|
||||||
{
|
|
||||||
routes: string[] = [
|
|
||||||
"/advertiser", // 0
|
|
||||||
"/advertiser/adList", // 1
|
|
||||||
"/advertiser/adsPopularity", // 2
|
|
||||||
"/advertiser/subjectsPopularity", // 3
|
|
||||||
"/advertiser/myProfil" // 4
|
|
||||||
];
|
|
||||||
|
|
||||||
url = this.router.url;
|
|
||||||
|
|
||||||
constructor( private router: Router,
|
|
||||||
public profilService: ProfilService,
|
|
||||||
private messageService: MessageService ) { }
|
|
||||||
|
|
||||||
onDeconnexion(): void
|
|
||||||
{
|
|
||||||
this.messageService
|
|
||||||
.delete('user/logout')
|
|
||||||
.subscribe(retour => this.onDeconnexionCallback(retour), err => this.onDeconnexionCallback(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
onDeconnexionCallback(retour: any): void
|
|
||||||
{
|
|
||||||
if(retour.status !== "success") console.log(retour);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +1,11 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import {PageLoginComponent} from './beforeConnexion/login/page-login/page-login.component';
|
import {PageLoginComponent} from "./beforeConnexion/login/page-login/page-login.component";
|
||||||
import {PageRegisterComponent} from "./beforeConnexion/register/page-register/page-register.component";
|
import {PageRegisterComponent} from "./beforeConnexion/register/page-register/page-register.component";
|
||||||
import {PageSearchComponent} from "./user/search/page-search/page-search.component";
|
|
||||||
import {PageMyPlaylistsComponent} from "./user/myPlaylists/page-my-playlists/page-my-playlists.component";
|
|
||||||
import {PageHistoryUserComponent} from "./user/history/page-history-user/page-history-user.component";
|
|
||||||
import {PageAdListAdvertiserComponent} from "./advertiser/adList/page-ad-list-advertiser/page-ad-list-advertiser.component";
|
|
||||||
import {PageProfilUserComponent} from "./user/myProfil/page-profil-user/page-profil-user.component";
|
|
||||||
import {PageProfilAdvertiserComponent} from "./advertiser/myProfil/page-profil-advertiser/page-profil-advertiser.component";
|
|
||||||
import {PageProfilAdminComponent} from "./admin/myProfil/page-profil-admin/page-profil-admin.component";
|
|
||||||
import {PageAdListAdminComponent} from "./admin/adList/page-ad-list-admin/page-ad-list-admin.component";
|
import {PageAdListAdminComponent} from "./admin/adList/page-ad-list-admin/page-ad-list-admin.component";
|
||||||
|
import {PageProfilAdminComponent} from "./admin/myProfil/page-profil-admin/page-profil-admin.component";
|
||||||
import {PageUserListComponent} from "./admin/userList/page-user-list/page-user-list.component";
|
import {PageUserListComponent} from "./admin/userList/page-user-list/page-user-list.component";
|
||||||
import {PageWatchingVideoComponent} from "./user/watching/page-watching-video/page-watching-video.component";
|
import {MyGuardGuard} from "./utils/my-guard/my-guard.guard";
|
||||||
import {PagesPopularityComponent} from "./advertiser/pages-popularity/pages-popularity.component";
|
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
|
|
||||||
|
|
@ -22,30 +14,13 @@ const routes: Routes = [
|
||||||
{ path: 'login', component: PageLoginComponent },
|
{ path: 'login', component: PageLoginComponent },
|
||||||
{ path: 'register', component: PageRegisterComponent },
|
{ path: 'register', component: PageRegisterComponent },
|
||||||
|
|
||||||
// User
|
|
||||||
{ path: 'user', component: PageSearchComponent },
|
|
||||||
{ path: 'user/search', component: PageSearchComponent },
|
|
||||||
{ path: 'user/myPlaylists', component: PageMyPlaylistsComponent },
|
|
||||||
{ path: 'user/history', component: PageHistoryUserComponent },
|
|
||||||
{ path: 'user/myProfil', component: PageProfilUserComponent },
|
|
||||||
{ path: 'user/watching', component: PageWatchingVideoComponent },
|
|
||||||
|
|
||||||
// Advertiser
|
|
||||||
{ path: 'advertiser', component: PageAdListAdvertiserComponent },
|
|
||||||
{ path: 'advertiser/adList', component: PageAdListAdvertiserComponent },
|
|
||||||
{ path: 'advertiser/myProfil', component: PageProfilAdvertiserComponent },
|
|
||||||
{ path: 'advertiser/adsPopularity', component: PagesPopularityComponent },
|
|
||||||
{ path: 'advertiser/subjectsPopularity', component: PagesPopularityComponent },
|
|
||||||
|
|
||||||
// Admin
|
// Admin
|
||||||
{ path: 'admin', component: PageUserListComponent },
|
{ path: 'admin', component: PageUserListComponent, canActivate: [MyGuardGuard] },
|
||||||
{ path: 'admin/userList', component: PageUserListComponent },
|
{ path: 'admin/userList', component: PageUserListComponent, canActivate: [MyGuardGuard] },
|
||||||
{ path: 'admin/adList', component: PageAdListAdminComponent },
|
{ path: 'admin/adList', component: PageAdListAdminComponent, canActivate: [MyGuardGuard] },
|
||||||
{ path: 'admin/myProfil', component: PageProfilAdminComponent },
|
{ path: 'admin/myProfil', component: PageProfilAdminComponent, canActivate: [MyGuardGuard] },
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,16 @@ describe('AppComponent', () => {
|
||||||
expect(app).toBeTruthy();
|
expect(app).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should have as title 'frontend'`, () => {
|
it(`should have as title 'admin'`, () => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
const app = fixture.componentInstance;
|
const app = fixture.componentInstance;
|
||||||
expect(app.title).toEqual('frontend');
|
expect(app.title).toEqual('admin');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render title', () => {
|
it('should render title', () => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const compiled = fixture.nativeElement;
|
const compiled = fixture.nativeElement as HTMLElement;
|
||||||
expect(compiled.querySelector('.content span').textContent).toContain('frontend app is running!');
|
expect(compiled.querySelector('.content span')?.textContent).toContain('admin app is running!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,5 @@ import { Component } from '@angular/core';
|
||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'frontend';
|
title = 'admin';
|
||||||
|
|
||||||
themeIsLight = true;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,154 +4,92 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { PageLoginComponent } from './beforeConnexion/login/page-login/page-login.component';
|
import { PageLoginComponent } from './beforeConnexion/login/page-login/page-login.component';
|
||||||
import { PageRegisterComponent } from './beforeConnexion/register/page-register/page-register.component';
|
import { PopupForgottenPasswordComponent } from './beforeConnexion/login/popup-forgotten-password/popup-forgotten-password.component';
|
||||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
|
||||||
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
|
|
||||||
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
|
||||||
import { PageSearchComponent } from './user/search/page-search/page-search.component';
|
|
||||||
import {HttpClientModule} from "@angular/common/http";
|
import {HttpClientModule} from "@angular/common/http";
|
||||||
import { PopupConfirmationComponent } from './beforeConnexion/register/popup-confirmation/popup-confirmation.component';
|
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
||||||
import {MatDialogModule} from '@angular/material/dialog';
|
import {MatTableModule} from "@angular/material/table";
|
||||||
import {MatButtonModule} from "@angular/material/button";
|
|
||||||
import { AdvertComponent } from './user/utils/components/advert/advert.component';
|
|
||||||
import { VideoGridComponent } from './user/search/video-grid/video-grid.component';
|
|
||||||
import {MatIconModule} from "@angular/material/icon";
|
|
||||||
import { PopupAddVideoToPlaylistsComponent } from './user/utils/components/popup-add-video-to-playlists/popup-add-video-to-playlists.component';
|
|
||||||
import {MatInputModule} from "@angular/material/input";
|
|
||||||
import {MatDividerModule} from "@angular/material/divider";
|
|
||||||
import {MatCheckboxModule} from "@angular/material/checkbox";
|
|
||||||
import {MatFormFieldModule} from "@angular/material/form-field";
|
|
||||||
import {MatSnackBarModule} from "@angular/material/snack-bar";
|
|
||||||
import {MatGridListModule} from "@angular/material/grid-list";
|
|
||||||
import { PageMyPlaylistsComponent } from './user/myPlaylists/page-my-playlists/page-my-playlists.component';
|
|
||||||
import { PlaylistListComponent } from './user/myPlaylists/playlist-list/playlist-list.component';
|
|
||||||
import {VideoListComponent} from "./user/myPlaylists/video-list/video-list.component";
|
|
||||||
import { PopupCreateOrUpdatePlaylistComponent } from './user/myPlaylists/popup-create-or-update-playlist/popup-create-or-update-playlist.component';
|
|
||||||
import { PageHistoryUserComponent } from './user/history/page-history-user/page-history-user.component';
|
|
||||||
import {MatTableModule} from '@angular/material/table';
|
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
|
||||||
import {MatSortModule} from "@angular/material/sort";
|
import {MatSortModule} from "@angular/material/sort";
|
||||||
import { PageAdListAdvertiserComponent } from './advertiser/adList/page-ad-list-advertiser/page-ad-list-advertiser.component';
|
|
||||||
import { PopupDeleteAdAdvertiserComponent } from './advertiser/adList/popup-delete-ad-advertiser/popup-delete-ad-advertiser.component';
|
|
||||||
import { PopupAddOrUpdateAdComponent } from './advertiser/adList/popup-add-or-update-ad/popup-add-or-update-ad.component';
|
|
||||||
import { PopupVisualizeAdAdvertiserComponent } from './advertiser/adList/popup-visualize-ad-advertiser/popup-visualize-ad-advertiser.component';
|
|
||||||
import { InputInterestsAdComponent } from './advertiser/adList/input-interests-ad/input-interests-ad.component';
|
|
||||||
import {MatChipsModule} from "@angular/material/chips";
|
|
||||||
import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
|
||||||
import {MatSelectModule} from "@angular/material/select";
|
|
||||||
import { PopupVisualizeImagesAdvertiserComponent } from './advertiser/adList/popup-visualize-images-advertiser/popup-visualize-images-advertiser.component';
|
|
||||||
import {IvyCarouselModule} from "angular-responsive-carousel";
|
|
||||||
import { DragAndDropComponent } from './advertiser/adList/drag-and-drop/drag-and-drop.component';
|
|
||||||
import { DragAndDropDirective } from './advertiser/utils/dragAndDrop/drag-and-drop.directive';
|
|
||||||
import { PageProfilUserComponent } from './user/myProfil/page-profil-user/page-profil-user.component';
|
|
||||||
import { NavbarUserComponent } from './user/utils/components/navbar-user/navbar-user.component';
|
|
||||||
import { NavbarAdvertiserComponent } from './advertiser/utils/navbar-advertiser/navbar-advertiser.component';
|
|
||||||
import { NavbarAdminComponent } from './admin/utils/navbar-admin/navbar-admin.component';
|
|
||||||
import { PageProfilAdvertiserComponent } from './advertiser/myProfil/page-profil-advertiser/page-profil-advertiser.component';
|
|
||||||
import { PopupUpdateAdvertiserComponent } from './advertiser/myProfil/popup-update-advertiser/popup-update-advertiser.component';
|
|
||||||
import { PopupUpdateUserComponent } from './user/myProfil/popup-update-user/popup-update-user.component';
|
|
||||||
import { NavbarBeforeConnexionComponent } from './beforeConnexion/utils/navbar-before-connexion/navbar-before-connexion.component';
|
|
||||||
import {MatRadioModule} from "@angular/material/radio";
|
import {MatRadioModule} from "@angular/material/radio";
|
||||||
import { InputInterestsProfilComponent } from './user/myProfil/input-interests-profil/input-interests-profil.component';
|
import {MatDialogModule} from "@angular/material/dialog";
|
||||||
|
import {MatSnackBarModule} from "@angular/material/snack-bar";
|
||||||
|
import {MatButtonModule} from "@angular/material/button";
|
||||||
|
import {MatCheckboxModule} from "@angular/material/checkbox";
|
||||||
|
import { PageRegisterComponent } from './beforeConnexion/register/page-register/page-register.component';
|
||||||
|
import { PopupConfirmationComponent } from './beforeConnexion/register/popup-confirmation/popup-confirmation.component';
|
||||||
|
import { InputInterestsRegisterComponent } from './beforeConnexion/register/input-interests-register/input-interests-register.component';
|
||||||
|
import {MatFormFieldModule} from "@angular/material/form-field";
|
||||||
|
import {MatChipsModule} from "@angular/material/chips";
|
||||||
|
import {MatIconModule} from "@angular/material/icon";
|
||||||
|
import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
||||||
|
import {MatStepperModule} from "@angular/material/stepper";
|
||||||
|
import { NavbarBeforeConnexionComponent } from './beforeConnexion/utils/navbar-before-connexion/navbar-before-connexion.component';
|
||||||
import { PageProfilAdminComponent } from './admin/myProfil/page-profil-admin/page-profil-admin.component';
|
import { PageProfilAdminComponent } from './admin/myProfil/page-profil-admin/page-profil-admin.component';
|
||||||
import { PopupUpdateAdminComponent } from './admin/myProfil/popup-update-admin/popup-update-admin.component';
|
import { PopupUpdateAdminComponent } from './admin/myProfil/popup-update-admin/popup-update-admin.component';
|
||||||
import {MatStepperModule} from "@angular/material/stepper";
|
|
||||||
import { InputInterestsRegisterComponent } from './beforeConnexion/register/input-interests-register/input-interests-register.component';
|
|
||||||
import {MatPaginatorModule} from "@angular/material/paginator";
|
|
||||||
import { PageAdListAdminComponent } from './admin/adList/page-ad-list-admin/page-ad-list-admin.component';
|
import { PageAdListAdminComponent } from './admin/adList/page-ad-list-admin/page-ad-list-admin.component';
|
||||||
import { PopupDeleteAdAdminComponent } from './admin/adList/popup-delete-ad-admin/popup-delete-ad-admin.component';
|
import { PopupDeleteAdAdminComponent } from './admin/adList/popup-delete-ad-admin/popup-delete-ad-admin.component';
|
||||||
import { PopupVisualizeImagesAdminComponent } from './admin/adList/popup-visualize-images-admin/popup-visualize-images-admin.component';
|
import { PopupVisualizeImagesAdminComponent } from './admin/adList/popup-visualize-images-admin/popup-visualize-images-admin.component';
|
||||||
|
import {MatDividerModule} from "@angular/material/divider";
|
||||||
|
import {MatSelectModule} from "@angular/material/select";
|
||||||
|
import {MatPaginatorModule} from "@angular/material/paginator";
|
||||||
|
import {MatGridListModule} from "@angular/material/grid-list";
|
||||||
import { PageUserListComponent } from './admin/userList/page-user-list/page-user-list.component';
|
import { PageUserListComponent } from './admin/userList/page-user-list/page-user-list.component';
|
||||||
import { PopupDeleteUserComponent } from './admin/userList/popup-delete-user/popup-delete-user.component';
|
|
||||||
import { PopupCreateUserComponent } from './admin/userList/popup-create-user/popup-create-user.component';
|
|
||||||
import { InputInterestsAdminComponent } from './admin/userList/input-interests-admin/input-interests-admin.component';
|
import { InputInterestsAdminComponent } from './admin/userList/input-interests-admin/input-interests-admin.component';
|
||||||
import { PageWatchingVideoComponent } from './user/watching/page-watching-video/page-watching-video.component';
|
import { PopupCreateUserComponent } from './admin/userList/popup-create-user/popup-create-user.component';
|
||||||
|
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
|
||||||
|
import { NavbarAdminComponent } from './admin/utils/navbar-admin/navbar-admin.component';
|
||||||
|
import {MatInputModule} from "@angular/material/input";
|
||||||
import {MatDatepickerModule} from "@angular/material/datepicker";
|
import {MatDatepickerModule} from "@angular/material/datepicker";
|
||||||
import { PagesPopularityComponent } from './advertiser/pages-popularity/pages-popularity.component';
|
import {MAT_DATE_LOCALE, MatNativeDateModule} from "@angular/material/core";
|
||||||
import { ChartsModule } from 'ng2-charts';
|
|
||||||
import { PopupDeletePlaylistComponent } from './user/myPlaylists/popup-delete-playlist/popup-delete-playlist.component';
|
|
||||||
import { PopupForgottenPasswordComponent } from './beforeConnexion/login/popup-forgotten-password/popup-forgotten-password.component';
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
PageLoginComponent,
|
PageLoginComponent,
|
||||||
|
PopupForgottenPasswordComponent,
|
||||||
PageRegisterComponent,
|
PageRegisterComponent,
|
||||||
PageSearchComponent,
|
|
||||||
PopupConfirmationComponent,
|
PopupConfirmationComponent,
|
||||||
AdvertComponent,
|
InputInterestsRegisterComponent,
|
||||||
VideoGridComponent,
|
|
||||||
PopupAddVideoToPlaylistsComponent,
|
|
||||||
PageMyPlaylistsComponent,
|
|
||||||
VideoListComponent,
|
|
||||||
PlaylistListComponent,
|
|
||||||
VideoListComponent,
|
|
||||||
PopupCreateOrUpdatePlaylistComponent,
|
|
||||||
PageHistoryUserComponent,
|
|
||||||
PageAdListAdvertiserComponent,
|
|
||||||
PopupDeleteAdAdvertiserComponent,
|
|
||||||
PopupAddOrUpdateAdComponent,
|
|
||||||
PopupVisualizeAdAdvertiserComponent,
|
|
||||||
InputInterestsAdComponent,
|
|
||||||
PopupVisualizeImagesAdvertiserComponent,
|
|
||||||
DragAndDropComponent,
|
|
||||||
DragAndDropDirective,
|
|
||||||
PageProfilUserComponent,
|
|
||||||
NavbarUserComponent,
|
|
||||||
NavbarAdvertiserComponent,
|
|
||||||
NavbarAdminComponent,
|
|
||||||
PageProfilAdvertiserComponent,
|
|
||||||
PopupUpdateAdvertiserComponent,
|
|
||||||
PopupUpdateUserComponent,
|
|
||||||
NavbarBeforeConnexionComponent,
|
NavbarBeforeConnexionComponent,
|
||||||
InputInterestsProfilComponent,
|
|
||||||
PageProfilAdminComponent,
|
PageProfilAdminComponent,
|
||||||
PopupUpdateAdminComponent,
|
PopupUpdateAdminComponent,
|
||||||
InputInterestsRegisterComponent,
|
|
||||||
PageAdListAdminComponent,
|
PageAdListAdminComponent,
|
||||||
PopupDeleteAdAdminComponent,
|
PopupDeleteAdAdminComponent,
|
||||||
PopupVisualizeImagesAdminComponent,
|
PopupVisualizeImagesAdminComponent,
|
||||||
PageUserListComponent,
|
PageUserListComponent,
|
||||||
PopupDeleteUserComponent,
|
|
||||||
PopupCreateUserComponent,
|
|
||||||
InputInterestsAdminComponent,
|
InputInterestsAdminComponent,
|
||||||
PageWatchingVideoComponent,
|
PopupCreateUserComponent,
|
||||||
PagesPopularityComponent,
|
NavbarAdminComponent
|
||||||
PopupDeletePlaylistComponent,
|
|
||||||
PopupForgottenPasswordComponent,
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
MatSlideToggleModule,
|
MatTableModule,
|
||||||
|
MatSortModule,
|
||||||
|
MatRadioModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
|
||||||
MatInputModule,
|
|
||||||
MatDividerModule,
|
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatFormFieldModule,
|
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatGridListModule,
|
MatFormFieldModule,
|
||||||
MatTableModule,
|
MatInputModule,
|
||||||
NgbModule,
|
|
||||||
MatSortModule,
|
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
ReactiveFormsModule,
|
MatIconModule,
|
||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatSelectModule,
|
ReactiveFormsModule,
|
||||||
IvyCarouselModule,
|
|
||||||
MatRadioModule,
|
|
||||||
MatStepperModule,
|
MatStepperModule,
|
||||||
|
MatDividerModule,
|
||||||
|
MatSelectModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
|
MatGridListModule,
|
||||||
|
MatSlideToggleModule,
|
||||||
MatDatepickerModule,
|
MatDatepickerModule,
|
||||||
ChartsModule
|
MatNativeDateModule,
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [{ provide: MAT_DATE_LOCALE, useValue: 'en-GB' }],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue