Compare commits

...
This repository has been archived on 2026-05-01. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.

218 commits

Author SHA1 Message Date
Yûki VACHOT
1419e97b2f Update: Ajout de NodeJS 2021-12-26 17:11:40 +01:00
Yûki VACHOT
92edacb59d Update: Lancement en Local et Production en ligne sur Heroku 2021-12-26 17:03:49 +01:00
Yûki VACHOT
d1b3829450 Update: README 2021-12-25 00:59:53 +01:00
Yûki VACHOT
f91febf919 Update: Add parameters to not update the timestamps of the document 2021-12-22 10:59:10 +01:00
00d991f8b1 Remove unnecessary files 2021-12-17 11:35:57 +01:00
25260cdf87 Update: Playlist.findOne add views & publishedAt 2021-12-17 11:35:26 +01:00
MiharyR
6839740f50 clic sur video d'une playlist --> ajout dans l'historique 2021-12-16 19:32:27 +01:00
MiharyR
dab2748079 boutons 'tout (dé)sélectionner' pour les pages popularity 2021-12-16 19:10:09 +01:00
MiharyR
ad0397e8ad implementation du bouton 'retour' dans la page 'user/watching' 2021-12-16 17:42:33 +01:00
MiharyR
f2ced83246 correction de tous les bugs niveaux 1 (faibles) 2021-12-16 13:45:05 +01:00
b5bb8e7cc4 Update: User.ad add Dates in views when getting ads 2021-12-15 14:16:07 +01:00
e6c28fb41f Update: User.ad add Dates in views when getting ads 2021-12-15 14:02:15 +01:00
d220a68f3d Update: Ad.findAll add userId 2021-12-15 08:50:19 +01:00
b66ea1f929 Update: Ad.create 2021-12-15 08:21:56 +01:00
b9512ef3b0 Update: User.ad 2021-12-15 02:25:19 +01:00
a369177e19 Update: User.ad 2021-12-15 02:08:18 +01:00
a6b1828c4b Update: User.ad console.log interests 2021-12-15 01:55:57 +01:00
bec2c5848b Update: User.ad console.log of match and pick 2021-12-15 01:52:32 +01:00
fc4abb2546 Update: User.ad add isVisible=true & isActive=true 2021-12-15 01:35:30 +01:00
d94a22e87f Merge remote-tracking branch 'origin/main' into main 2021-12-15 01:26:14 +01:00
cbb72a8382 Update: Playlist.create same name and playlist deletd 2021-12-15 01:13:57 +01:00
MiharyR
b0b17c062d gestion de l'affichage des annonces dans la partie user 2021-12-15 00:49:33 +01:00
MiharyR
7ea0a5eb97 rectification de 'publishedAt' sur la page 'user/search' 2021-12-14 22:05:58 +01:00
MiharyR
f1614c44aa les 'interests'/'themes' ne s'affichent plus dans l'input s'ils ont déjà été sélectionnés 2021-12-14 20:55:45 +01:00
MiharyR
c1ecb3cb5e gestion des erreurs dans quand on ajoute une video dans une playlist 2021-12-14 18:44:05 +01:00
MiharyR
95e88f93ab ajout d'une video dans une playlist: fonctionnel 2021-12-14 17:43:54 +01:00
4af6891bd5 Update: Playlist.update remove console.log() 2021-12-14 17:04:59 +01:00
2433262c0e Merge remote-tracking branch 'origin/main' into main 2021-12-14 17:02:09 +01:00
3ffb579ed6 Update: Playlist.update videoIds + videoId fields 2021-12-14 17:02:02 +01:00
MiharyR
98ae71b5c1 avancement dans la connexion avec le back de la page user/myPlaylist 2021-12-14 16:24:37 +01:00
2bc7c968ef Update: Add console.log of MongoDB Version 2021-12-14 13:55:07 +01:00
de787919b1 Update: French name + Alphabetic sorted 2021-12-14 13:49:13 +01:00
2fef2c135e Merge remote-tracking branch 'origin/main' into main 2021-12-14 13:36:51 +01:00
d9205e4ddf Update: Playlist.findOne add interest field 2021-12-14 13:27:37 +01:00
MiharyR
bde03fb908 Avancement de la connexion avec le back pour la partie user 2021-12-14 01:29:40 +01:00
MiharyR
7444715b2f avancement dans la connexion du back avec la partie user 2021-12-14 01:28:50 +01:00
c465b87b3f Update: User.history missing sort by watchedDate 2021-12-13 23:17:48 +01:00
7dc6b64a3c Merge remote-tracking branch 'origin/main' into main 2021-12-13 23:07:26 +01:00
73831f0dd0 Update: Ad.update remove duplicate interests + Ad.findAll can filter with multiple interest with ',' 2021-12-13 23:07:16 +01:00
MiharyR
7030a0ea21 connexion avec back de la page 'user/history' 2021-12-13 21:19:23 +01:00
8f39312a6e Update: User.history watchedDates.length > 0 2021-12-13 21:03:45 +01:00
df3deb057c Debug: User.history watchedDates 2021-12-13 20:43:35 +01:00
027a34ac70 Merge remote-tracking branch 'origin/main' into main 2021-12-13 20:03:33 +01:00
b10ba5890f Update: User.history $last -> $arrayElemAt 2021-12-13 20:03:22 +01:00
3c0b26e166 Update: Video.update +watchedDates 2021-12-13 19:54:05 +01:00
MiharyR
326ea73b86 on ne peut pas ajouter plusieurs fois le memme 'centre d'interet'/'sujet' 2021-12-13 18:54:45 +01:00
MiharyR
0ea00bf062 gestion des images 2021-12-13 15:01:35 +01:00
will82-code
837f1056e9
Merge pull request #5 from NyxiumYuuki/correction_ortho
Correction ortho
2021-12-13 11:28:47 +01:00
wilfriedvallee
9b1d29649a Update: correction mot "filtre..." car oubli 2021-12-13 11:15:37 +01:00
wilfriedvallee
26a1c1b040 Update: correction mot "déconnexion" 2021-12-13 11:08:17 +01:00
wilfriedvallee
a72a89eedf Update: correction mot "filtre..." 2021-12-13 11:01:18 +01:00
wilfriedvallee
a2c9dc2502 Update: correction mot "Rechercher..." 2021-12-13 10:58:46 +01:00
will82-code
cec8804cc7
Merge pull request #4 from NyxiumYuuki/correction_ortho
Correction ortho
2021-12-13 10:50:54 +01:00
wilfriedvallee
15e5133ad7 register : correction mot "centre d'intérêt" 2021-12-13 10:49:23 +01:00
wilfriedvallee
cc505ca3ac register : correction mot "centre d'intérêt" 2021-12-13 10:48:31 +01:00
2b02e13321 Merge remote-tracking branch 'origin/main' into main 2021-12-12 20:47:15 +01:00
51e9870340 Update: Ad.delete 2021-12-12 20:43:42 +01:00
MiharyR
f868e1c91d connexion avec back des pages 'advertiser/adsPopularity' et 'advertiser/subjectsPopularity' 2021-12-12 20:28:44 +01:00
MiharyR
0dd39af7ad connexion avec back des pages 'advertiser/manageAds' et 'admin/adList' 2021-12-12 19:04:40 +01:00
MiharyR
c91fc523aa connexion avec back de la page 'admin/userList' 2021-12-12 15:27:40 +01:00
MiharyR
fd722f613d connexion avec back de 'admin/adList' 2021-12-12 13:34:45 +01:00
b617af0051 Merge remote-tracking branch 'origin/main' into main 2021-12-12 08:41:02 +01:00
0b8a2bd87d Update: Playlist.search add maxResults for Youtube to 45 2021-12-12 08:40:48 +01:00
MiharyR
5e62d2e4ef connexion avec le back pour 'page search' et 'page watching' 2021-12-12 07:44:17 +01:00
d53bc27b7c Update: Playlist.create 2021-12-12 07:39:36 +01:00
b3e5fe3888 Update: Playlist.create 2021-12-12 07:03:01 +01:00
fd5d9505b0 Update: Playlist.update 2021-12-12 05:32:29 +01:00
88670b9c18 Update: require async functions 2021-12-12 03:36:32 +01:00
7af7cd85c9 Create: async Functions 2021-12-12 03:36:10 +01:00
a874e4f53c Update: User.history all data retrieved 2021-12-12 03:36:00 +01:00
559b8624b3 Update: Error.reason 2021-12-12 01:55:35 +01:00
cf6264cc87 Update: Auth refused is the role is not accepted 2021-12-12 01:49:58 +01:00
MiharyR
d6752acaad connexion avec back pour page 'search' 2021-12-12 01:38:18 +01:00
a2d5a7afc6 Update: Add Check of Env Variables of API 2021-12-12 01:15:26 +01:00
de32a8479c Update: Add Check of Env Variables of API 2021-12-12 01:14:50 +01:00
2078f872a0 Update: Video.search remove console.log 2021-12-12 00:56:59 +01:00
016a609d67 Update: User.create typeof added 2021-12-12 00:46:28 +01:00
474e40b0dd Update: Video.search add trends' 2021-12-12 00:32:52 +01:00
5f20411dd8 Merge remote-tracking branch 'origin/main' into main 2021-12-12 00:04:44 +01:00
7e7432d75e Update: Video.search sources is now a concatenate string with character ',' 2021-12-12 00:04:33 +01:00
MiharyR
526e5fbbbf connexion avec le back de toutes les pages 'myProfil' 2021-12-11 21:59:15 +01:00
MiharyR
7f6d089f1d commencement de la connexion avec le back de 'user/myProfil' et de 'user/myPlaylists' 2021-12-11 21:22:27 +01:00
MiharyR
cf3c596c7b partie 'beforeConnexion' entierement connectée avec le back 2021-12-11 14:17:10 +01:00
411cea6ff0 Update: checkLogin 2021-12-11 12:40:33 +01:00
49bef8ec5f Update: checkLogin 2021-12-11 12:39:49 +01:00
d2194ee9ea Update: checkLogin 2021-12-11 12:37:56 +01:00
ec6cc0631a Update: User.deleteAll will now update isActive 2021-12-11 12:31:01 +01:00
a146c21502 Update: User.ad 2021-12-11 12:17:53 +01:00
c02114adc8 Update: Video.update 2021-12-11 11:13:56 +01:00
429c75473a Update: Video.findOne 2021-12-11 11:06:58 +01:00
792ae45bca Update: interest is a String !! 2021-12-11 11:04:05 +01:00
4a64e01693 Update: findAll can only be retrieve by a Advertiser or above 2021-12-11 11:00:39 +01:00
e52d756d3b Update: Video.findAll 2021-12-11 11:00:11 +01:00
0cf76acdfe Update: video/:id to video/get/:id 2021-12-11 11:00:01 +01:00
5fffe19d98 Update: Video.delete 2021-12-11 10:44:32 +01:00
83f49038ea Update: Video.deleteAll 2021-12-11 10:43:21 +01:00
b07bb11879 Update: Video.search + Video.get interests 2021-12-11 10:28:08 +01:00
e0bbe27d2b Update: Add Tech Dailymotion Categorie to Science and Technology 2021-12-11 10:25:35 +01:00
8c33157fb8 Update: Remove useless object 2021-12-11 10:24:59 +01:00
da1adf9679 Update: isActive field added 2021-12-10 18:44:06 +01:00
000a4e0054 Update: Prettify token expiration dates 2021-12-10 18:21:30 +01:00
de57170c35 Update: Useless line removed 2021-12-10 18:21:04 +01:00
f07db5bbc4 Update: Video.create 2021-12-10 18:20:31 +01:00
03bb63c861 Update: Add default values 2021-12-10 18:20:11 +01:00
924b06816c Update: no field check 2021-12-10 17:02:24 +01:00
249c846093 Update: typeof missing 2021-12-10 17:02:11 +01:00
6524db19e7 Update: add Video.get interest field 2021-12-10 16:40:28 +01:00
c152f62aa7 Update: Video.get 2021-12-10 16:06:25 +01:00
e5870a639a Update: Add baseChannelUrl 2021-12-10 16:05:57 +01:00
0faec6c9df Update: Add request 2021-12-10 16:05:38 +01:00
9aa988d18c Update: Add API KEY + shortname 2021-12-10 14:25:56 +01:00
1dd527296c Update: User.ad v0.1 2021-12-10 13:59:01 +01:00
d564f7d8b3 Update: Ad.update 2021-12-10 13:44:13 +01:00
61813b0644 Update: Ad.findAll 2021-12-10 13:38:52 +01:00
d2044c2b28 Update: Ad.delete 2021-12-10 13:29:26 +01:00
e2927e497a Update: Ad.deleteAll 2021-12-10 13:26:36 +01:00
7ba18e8488 Update: Ad.findOne 2021-12-10 13:25:05 +01:00
ee253ba76b Update: add default values 2021-12-10 13:22:44 +01:00
91915dc1a9 Update: Ad.create 2021-12-10 13:22:34 +01:00
a34f3030dd Update: Playlist.delete + returns added + check if ObjectId is valid 2021-12-10 12:54:23 +01:00
b73da1a288 Update: add returns 2021-12-10 12:53:38 +01:00
76390fcec5 Update: Playlist.deleteAll 2021-12-10 12:46:23 +01:00
c638550e4d Update: Playlist.update 2021-12-10 12:42:31 +01:00
c36c48dc91 Update: Add if ObjectId isValid 2021-12-10 12:42:11 +01:00
14afbe363d Update: Playlist.findAll 2021-12-10 12:03:58 +01:00
8ceb6bf43d Update: User.ad in development 2021-12-10 12:03:26 +01:00
81c6895e72 Update: add default values 2021-12-10 12:02:19 +01:00
16b04f1b91 Update: Playlist.create 2021-12-10 11:53:25 +01:00
eb1e73193b Update: add default values 2021-12-10 11:45:34 +01:00
29673c992a Update: User.history 2021-12-10 11:09:19 +01:00
dd78505db8 Update: User.delete 2021-12-10 10:32:56 +01:00
d69f4badff Update: User.update 2021-12-10 10:25:16 +01:00
48919a95d9 Update: Error response 2021-12-10 09:47:44 +01:00
1ac491e46e Update: add User.findAll 2021-12-06 06:07:50 +01:00
4c1d954fba Merge remote-tracking branch 'origin/main' into main 2021-12-06 05:40:45 +01:00
3ff25921c1 Update: add User.auth, User.logout, User.create, User.deleteAll, User.roles 2021-12-06 05:39:42 +01:00
2a93962432 Update: login to email 2021-12-06 05:38:43 +01:00
9ab394244b Update: add isAccepted field 2021-12-06 05:38:31 +01:00
2772acfc2e Move: Model files 2021-12-06 05:38:07 +01:00
MiharyR
be3956818b connexion au back avec la partie 'beforeConnexion' 2021-12-05 16:44:47 +01:00
be318e8c06 Update: subscribe & onSeConnecterCallback() 2021-12-04 11:39:09 +01:00
MiharyR
6444df567b modification messageService 2021-12-04 11:09:37 +01:00
819d266601 Update: Url Origin Cors changed 2021-12-04 10:54:59 +01:00
4ebbd04c99 Update: User.controller.auth 2021-12-04 10:38:20 +01:00
d740beda4e Update: change profilePictureUrl to profileImageUrl 2021-12-04 10:34:33 +01:00
83bd6e36f0 Update: default profilePictureUrl 2021-12-04 10:31:45 +01:00
6e55133335 Update: mail to email 2021-12-04 10:27:10 +01:00
e6e3b6b15d Merge remote-tracking branch 'origin/main' into main 2021-12-04 10:14:15 +01:00
47df4a1d23 Update: User.controller & User.model 2021-12-04 10:13:56 +01:00
MiharyR
7a0d1136a9 ['dateOfBirth' non obligatoire] + [popup forgotten password] 2021-12-03 17:34:02 +01:00
a70574a8e2 Merge remote-tracking branch 'origin/main' into main 2021-12-01 05:53:08 +01:00
002f79851a Update: Models 2021-12-01 05:52:34 +01:00
70ca726122 Fix: require of host.config 2021-12-01 05:29:11 +01:00
46d1daa085 Update routes & controllers 2021-12-01 05:28:47 +01:00
698fe87024 Add Misc routes 2021-12-01 05:27:33 +01:00
MiharyR
939e5f4df1 corrections des erreurs remarquées par Wilfried 2021-11-27 22:13:46 +01:00
MiharyR
d1ac1b77f0 amelioration du style globale 2021-11-26 17:05:12 +01:00
MiharyR
cd1f323686 ameloriation du style de la partie user 2021-11-24 21:34:27 +01:00
MiharyR
1e5b9bd49c continuation de la partie advertiser 2021-11-24 12:07:31 +01:00
MiharyR
01c0e137e0 Amelioration de la partie advertiser 2021-11-23 12:53:12 +01:00
MiharyR
1643f3f336 amelioration de la partie advertiser 2021-11-23 12:52:22 +01:00
0a351baac8 Add Video Categories 2021-11-22 22:53:51 +01:00
MiharyR
2d66d182d8 amelioration de la partie admin 2021-11-21 22:16:48 +01:00
MiharyR
7c24996e73 amelioration du style de la partie user 2021-11-21 12:56:11 +01:00
MiharyR
3dce1f6865 commencement de la page watching 2021-11-21 01:36:54 +01:00
MiharyR
ccb33d8aeb commencement de la page watching 2021-11-21 01:30:53 +01:00
MiharyR
fd7322a7bc renommage de l'image play 2021-11-19 15:53:53 +01:00
MiharyR
573ef426a3 image video à la place de iframe 2021-11-19 15:44:03 +01:00
MiharyR
b045f507d2 image video à la place de iframe 2021-11-19 15:42:51 +01:00
MiharyR
500b32626e modification popup-update-user 2021-11-17 20:30:33 +01:00
MiharyR
080a50e2fe correction page register et titre de l'onglet 2021-11-16 09:56:56 +01:00
MiharyR
a8cbd4efb7 correction pages: register, myProfil-user, search, myPlaylists 2021-11-14 03:39:24 +01:00
MiharyR
91171a3765 continuation de la partie admin 2021-11-13 20:44:12 +01:00
MiharyR
de939b47f1 commencement de la partie admin 2021-11-13 13:35:08 +01:00
MiharyR
11472d0045 correction de CSS 2021-11-13 00:52:49 +01:00
MiharyR
ad08803578 Realisation de la page register 2021-11-12 19:43:22 +01:00
MiharyR
d55287531b realisation de la page register 2021-11-12 19:42:39 +01:00
f6950f28d1 Update Local Env 2021-11-12 17:21:47 +01:00
569fc127d0 Env Conf 2021-11-12 17:07:14 +01:00
255c8b1ca3 Update 2021-11-12 16:55:32 +01:00
21d32a2dc2 Update 2021-11-12 16:28:49 +01:00
ca0ae3e991 Update 2021-11-12 16:24:04 +01:00
3ec65bb72d Update 2021-11-12 16:15:07 +01:00
d2e750c446 Update 2021-11-12 16:04:19 +01:00
5e6dbdab39 Update 2021-11-12 15:57:26 +01:00
cda8af0b6c Update 2021-11-12 15:56:04 +01:00
2c4cc218d3 Update 2021-11-12 15:45:49 +01:00
00ab283d56 Update 2021-11-12 15:40:11 +01:00
ed4e7470fc Update 2021-11-12 15:25:59 +01:00
7f45c525b0 Update 2021-11-12 15:23:47 +01:00
0bab55f04c Update 2021-11-12 15:12:55 +01:00
c620e19449 Update 2021-11-12 15:00:49 +01:00
80b0ea401b Update 2021-11-12 14:56:12 +01:00
b6130a7268 Update 2021-11-12 14:25:10 +01:00
b92456d8d3 Update 2021-11-12 14:13:04 +01:00
0cf86bd63f Update 2021-11-12 14:08:08 +01:00
f707393796 Update 2021-11-12 14:00:12 +01:00
7966face35 Update 2021-11-12 13:50:43 +01:00
2c7a4c5686 Update 2021-11-12 13:46:23 +01:00
1c64051aae Update 2021-11-12 13:41:03 +01:00
92a583b413
Update package.json 2021-11-12 13:36:56 +01:00
c39b71808c
Update package.json 2021-11-12 13:34:04 +01:00
MiharyR
89e174a28d création des 3 pages de profil 2021-11-12 09:47:14 +01:00
MiharyR
ef5dd96747 restructuration des fichiers (pour pouvoir passer plus facilement plusieurs fronts) 2021-11-11 17:02:27 +01:00
MiharyR
48fb0845f1 Merge branch 'advertiser2' into main 2021-11-09 14:14:38 +01:00
MiharyR
2f9c9c2b77 ajout du drag and drop pour ajouter une image 2021-11-09 14:10:36 +01:00
3ce5567f8a Add profilePictureUrl, dateOfBirth, gender and interests of a user 2021-11-03 20:16:12 +01:00
54324794e9 Docker ready 2021-11-02 14:59:31 +01:00
740fa9ab7b Docker ready 2021-11-02 04:52:34 +01:00
4629b42b36 History added + User tested 2021-11-02 04:37:22 +01:00
f774cf64bd Merge remote-tracking branch 'origin/main' into main 2021-11-01 20:08:52 +01:00
e17adfcfa5 Update 2021-11-01 19:53:21 +01:00
MiharyR
7715a5a8eb resolution du conflit sur la page de connexion 2021-11-01 12:23:38 +01:00
MiharyR
4336169d2e amélioration du style 2021-11-01 11:59:20 +01:00
wilfried
f178f91b91 Type password lors de la connexion 2021-11-01 08:54:17 +01:00
MiharyR
7ebacdc287 realistion de la page Mon Profil 2021-10-31 02:17:23 +01:00
MiharyR
4138c22051 Merge branch 'main' of github.com:NyxiumYuuki/PolyNotFound into main 2021-10-30 16:22:50 +02:00
MiharyR
e358b6fa0e realisation de la page user/historique 2021-10-30 16:18:57 +02:00
135 changed files with 27 additions and 41899 deletions

View file

@ -1,17 +0,0 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

View file

@ -1,16 +0,0 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

52
.gitignore vendored
View file

@ -1,52 +0,0 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
speed-measure-plugin*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
*.env
# System Files
.DS_Store
Thumbs.db
/backend/database/
/backend/node_modules/
package-lock.json

View file

@ -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 . .

View file

@ -1,27 +1,40 @@
# Frontend
# PolyNotFound
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.7.
Le projet est séparé en 3 parties :
## Development server
- 2 Frontend :
- 1 partie Administrateur
- 1 partie pour les utilisateurs et les publicitaires
- 1 Backend
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.
Nous avons décidé que chaque partie du projet a sa propre branche git et non leur propre répertoire git.
## Code scaffolding
En effet, les branches concernées par le projet est :
- Frontend partie Administrateur : `front-admin`
- Frontend partie pour les utilisateurs et les publicitaires : `front-user-advertiser`
- Backend : `backend`
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`.
Nous pouvons récupérer une branche git avec `git checkout <nom_branche>`.
## Build
# Lancer le projet en Local
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.
Dans un premier temps, il est obligatoire d'avoir NodeJS (version >12 au minimum), [téléchargeable sur cette page](https://nodejs.org/en/download/).
## Running unit tests
Pour lancer le projet en local dans son ensemble, il faut impérativement avoir les branches concernées dans leur propre dossier.
Il faudra donc __clone__ le projet 3 fois.
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
Dans un dossier nommé par exemple `Polynotfound`:
- frontend-admin : `git clone --branch frontend-admin https://github.com/NyxiumYuuki/PolyNotFound.git polynotfound-frontend-admin`
- front-user-advertiser : `git clone --branch front-user-advertiser https://github.com/NyxiumYuuki/PolyNotFound.git polynotfound-front-user-advertiser`
- backend : `git clone --branch backend https://github.com/NyxiumYuuki/PolyNotFound.git polynotfound-backend`
## Running end-to-end tests
Un README est disponible pour chaque branche pour lancer le projet en local soit en mode **production** soit en mode **développement**.
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
# Lancer le projet en ligne avec Heroku
## Further help
Nous avons déployé le projet en ligne avec Heroku.
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
Le projet est disponible sur ces URL :
- Partie Utilisateurs et Publicitaires : https://polynotfound.herokuapp.com/
- Partie Administrateur : https://admin-polynotfound.herokuapp.com/
- API : https://api-polynotfound.herokuapp.com/

View file

@ -1,131 +0,0 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"frontend": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/frontend",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.scss",
"node_modules/bootstrap/scss/bootstrap.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "frontend:build"
},
"configurations": {
"production": {
"browserTarget": "frontend:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "frontend:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.scss"
],
"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"
}

View file

@ -1,7 +0,0 @@
FROM node:current-slim
WORKDIR /app-backend
COPY ["package.json", "package-lock.json*", "./"]
RUN npm install
COPY . .
CMD ./app/jwtRS256.sh
CMD node server.js

View file

@ -1,8 +0,0 @@
module.exports = {
youtube: {
baseAPIUrl: 'https://www.youtube.com/'
},
dailymotion: {
baseAPIUrl: 'https://api.dailymotion.com/'
}
};

View file

@ -1,3 +0,0 @@
module.exports = {
url: "mongodb://127.0.0.1:27017/polynotfound"
};

View file

@ -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, data: { token: token, reason: reason }});
}
module.exports = { sendMessage, sendError };

View file

@ -1,5 +0,0 @@
module.exports = {
User: 0,
Advertiser: 5,
Admin: 10
};

View file

@ -1,99 +0,0 @@
const sessionJWTConfig = require ('jsonwebtoken');
require('dotenv').config({ path: './app/.env' });
const {sendError} = require ("./response.config");
if(process.env.JWTRS256_PRIVATE_KEY === undefined || process.env.JWTRS256_PUBLIC_KEY === undefined){
console.log('Error Env Variables');
process.exit();
}
console.log('Env variables 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, login, role) {
return sessionJWTConfig.sign(
{
id: id,
login: login,
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.login !== '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.login, payload.role);
}
res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false});
}
function decodeSessionCookie(sessionid) {
if (typeof sessionid === 'undefined') {
return {id: -1, login: -1, role: -1};
}
try {
const token = sessionJWTConfig.verify(
sessionid,
JWTRS256_PUBLIC_KEY,
{algorithms: ['RS256']});
return {token: token};
}
catch (err) {
return {id: -1, login: -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(token.login === 'undefined' || token.login === -1){
return sendError(res, 500, -1, "User not authenticated.");
} else{
if(role === null){
return token;
} else{
if(token.role !== 'undefined' && role.includes(token.role)){
return token;
} else{
return sendError(res, 500, -1, "User doesn't have permission.", token);
}
}
}
} else {
return sendError(res, 500, -1, "Cookies don't exist.");
}
}
module.exports.checkLogin = checkLogin;

View file

@ -1,53 +0,0 @@
const db = require("../models/mongodb.model");
const {sendError, sendMessage} = require ("../config/response.config");
const {checkLogin} = require("../config/sessionJWT.config");
const roles = require("../config/role.config");
const Ads = db.ads;
// Create a new Ad
exports.create = (req, res) => {
const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]);
if(token){
return sendError(res, 501, -1, "Ads.create not Implemented", token);
}
};
// Retrieve all Ads
exports.findAll = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Ads.findAll not Implemented", token);
}
};
// Retrieve a single Ad with id
exports.findOne = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Ads.findOne not Implemented", token);
}
};
// Update a Ad with id
exports.update = (req, res) => {
const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]);
if(token){
return sendError(res, 501, -1, "Ads.update not Implemented", token);
}
};
// Delete a Ad with id
exports.delete = (req, res) => {
const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]);
if(token){
return sendError(res, 501, -1, "Ads.delete not Implemented", token);
}
};
// Delete all Ads
exports.deleteAll = (req, res) => {
const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]);
if(token){
return sendError(res, 501, -1, "Ads.deleteAll not Implemented", token);
}
};

View file

@ -1,52 +0,0 @@
const db = require("../models/mongodb.model");
const {sendError, sendMessage} = require ("../config/response.config");
const {checkLogin} = require("../config/sessionJWT.config");
const Playlist = db.playlists;
// Create a new Playlist
exports.create = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Playlist.create not Implemented", token);
}
};
// Retrieve all Playlists
exports.findAll = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Playlist.findAll not Implemented", token);
}
};
// Retrieve a single Playlist with id
exports.findOne = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Playlist.findOne not Implemented", token);
}
};
// Update a Playlist with id
exports.update = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Playlist.update not Implemented", token);
}
};
// Delete a Playlist with id
exports.delete = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Playlist.delete not Implemented", token);
}
};
// Delete all Playlists
exports.deleteAll = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Playlist.deleteAll not Implemented", token);
}
};

View file

@ -1,175 +0,0 @@
const db = require("../models/mongodb.model");
const {sendError, sendMessage} = require ("../config/response.config");
const {checkLogin, setSessionCookie} = require("../config/sessionJWT.config");
const roles = require("../config/role.config");
const User = db.users;
// Authenticate a User
exports.auth = (req, res) => {
// Validate request
if (!req.body.login || !req.body.hashPass) {
sendError(res, 400,-1,"Content can not be empty ! (login and hashPass needed)");
} else{
// Check User in the database
User
.findOne({login: req.body.login, hashPass: req.body.hashPass}, {role: true})
.then(data => {
if (data !== null){
setSessionCookie(req, res, {id: data._id, login: req.body.login, role: data.role});
return sendMessage(res, 1, true);
} else {
setSessionCookie(req, res, {id: -1, login: -1, role: -1 });
return sendError(res, 500, -1, "Invalid login or password.");
}
})
.catch(err => {
sendError(res, 500,-1,err.message || "Some error occurred while authenticating the User.");
});
}
};
// Logout a User
exports.disconnect = (req, res) => {
const token = checkLogin(req, res);
if(token){
console.log(token);
setSessionCookie(req, res, {id: -1, login: -1, role: -1});
return sendMessage(res, 1, {message: "User disconnected"}, token);
}
};
// Create and Save a new User
exports.create = (req, res) => {
// Validate request
if (!req.body.login || !req.body.hashPass || !req.body.mail) {
sendError(res, 400,-1,"Content can not be empty ! (login, hashPass and mail needed");
}
else{
User.exists({login: req.body.login}, function (err, docs){
if(err){
sendError(res, 500,-1,err.message || "Some error occurred while checking if the User already exists.");
} else{
if(docs === null) {
const user = new User({
login: req.body.login,
hashPass: req.body.hashPass,
mail: req.body.mail,
role: req.body.role
});
// Save User in the database
user
.save(user)
.then(data => {
data.hashPass = undefined; // Hiding hashPass on return
sendMessage(res, 1, data)
})
.catch(err => {
sendError(res, 500,-1,err.message || "Some error occurred while creating the User.");
});
} else{
sendError(res, 500, -1, err || "User already exists.");
}
}
});
}
};
// Retrieve all Users from the database if admin.
exports.findAll = (req, res) => {
const token = checkLogin(req, res, [roles.Admin]);
if(token){
console.log(token);
const login = req.query.login;
let condition = login ? { login: { $regex: new RegExp(login), $options: "i" } } : {};
User.find(condition, {hashPass: false})
.then(data => {
sendMessage(res, 1, data, token)
})
.catch(err => {
sendError(res,500,-1,err.message || "Some error occurred while retrieving users.", token);
});
}
};
// Find a single User with login if admin or login from cookie session
exports.findOne = (req, res) => {
const token = checkLogin(req, res);
if(token){
let login;
if(token.role === [roles.Admin]){
login = req.params.login;
} else{
login = token.login;
}
console.log(token.role, login);
User.find({login: login}, {hashPass: false})
.then(data => {
if (data){
sendMessage(res, 1, data);
} else {
sendError(res,404,-1,"Not found User with login " + login );
}
})
.catch(err => {
sendError(res,500,-1,err.message || "Error retrieving User with login=" + login );
});
}
};
// Update a User by the id in the request
exports.update = (req, res) => {
if (!req.body) {
sendError(res,400,-1,"Data to update can not be empty!");
} else{
const id = req.params.id;
User.findByIdAndUpdate(id, req.body, { useFindAndModify: false })
.then(data => {
if (data) {
sendMessage(res, 1, { message: "User was updated successfully." });
} else {
sendError(res,404,-1,`Cannot update User with id=${id}. Maybe User was not found!`);
}
})
.catch(err => {
sendError(res,500,-1,err.message || "Error updating User with id=" + id);
});
}
};
// Delete a User with the specified id in the request
exports.delete = (req, res) => {
const id = req.params.id;
User.findByIdAndRemove(id)
.then(data => {
if (data) {
sendMessage(res, 1, { message: "User was deleted successfully!" });
} else {
sendError(res,404,-1,`Cannot delete User with id=${id}. Maybe User was not found!`);
}
})
.catch(err => {
sendError(res,500,-1,err.message || "Could not delete User with id=" + id);
});
};
// Delete all Users from the database.
exports.deleteAll = (req, res) => {
const token = checkLogin(req, res, [roles.Admin]);
if(token) {
console.log(token);
User.deleteMany({})
.then(data => {
sendMessage(res, 1, {
message: `${data.deletedCount} Users were deleted successfully!`
});
})
.catch(err => {
sendError(res, 500, -1, err.message || "Some error occurred while removing all Users.");
});
}
};

View file

@ -1,60 +0,0 @@
const db = require("../models/mongodb.model");
const {sendError, sendMessage} = require ("../config/response.config");
const {checkLogin} = require("../config/sessionJWT.config");
const Video = db.video;
// Search Video
exports.search = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Video.search not Implemented", token);
}
};
// Create a new Video
exports.create = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Video.create not Implemented", token);
}
};
// Retrieve all Videos
exports.findAll = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Video.findAll not Implemented", token);
}
};
// Retrieve a single Video with id
exports.findOne = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Video.findOne not Implemented", token);
}
};
// Update a Video with id
exports.update = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Video.update not Implemented", token);
}
};
// Delete a Video with id
exports.delete = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Video.delete not Implemented", token);
}
};
// Delete all Videos
exports.deleteAll = (req, res) => {
const token = checkLogin(req, res);
if(token){
return sendError(res, 501, -1, "Video.deleteAll not Implemented", token);
}
};

View file

@ -1,14 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyTaN1skc89wdcz8SLY9c
lkcARENbO40DncmcUZwQEq+EYR9BzUhjIzKJ6JetU+qGt4SJQkPAczQbw8+LaF6P
NT0QTF6E6BUgTZg1p98E/208AiFDnoqEjmlLdQN7ekttJXGDrVOTds9WMbn8lVpa
4EpVc+8CPDmrSTIC2YVSZmmektmFTSUA6411+5FGlq5oUdyKkToWYdn/ViJbYst8
N48E2Vuh1ghY5t7oPWGzPibMc/6A+uDAF7+VVD8x5UydMZ9id+RxC7lhtDDvZeRM
BllHcnWfw0UMhVk8PC6/BenJ4I8HiOgyl4cypTvlevfbZjSoNJ4g/u/lDKpdqbBg
T76OksaYqvwvTrcvPdgF1f8l/7M9ESYZTMpxvqK6YvYC/MG2355fmZ1SeuqKfDt8
rQXfXzesGSNmFNkm8mORHYiXBqyuNAwnSqRtP8qfoB4yXZ2W1HjUf24TvkvMrqwT
7PFg55c/f4LVdPjx52z30QzBJmcyVZgzXNOCG1KafwBibhriQmhdfiWogs824mwI
9w0vG2pPqSHRAa6N1y9JHSP1rIfu1jzRNFWTUuqyKgLYBE47HqxxJ21BwBryTVUz
8Ei+o05lJFkQX2/ISFYP2RunfUBccqmv0nEcGr+RSLTeqz5+WUTWs8tQxUItf2p6
9Y30htlmCJlSnHn2JlaJWQUCAwEAAQ==
-----END PUBLIC KEY-----

View file

@ -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

View file

@ -1,18 +0,0 @@
module.exports = mongoose => {
let schema = mongoose.Schema({
images: [],
text: String,
subjectTarget: [],
seen: Number
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
return mongoose.model("ad", schema);
};

View file

@ -1,18 +0,0 @@
module.exports = mongoose => {
let schema = mongoose.Schema({
base64: String,
fromUrl: String,
description: String,
type: Number
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
return mongoose.model("image", schema);
};

View file

@ -1,15 +0,0 @@
const dbConfig = require("../config/mongodb.config");
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
db.url = dbConfig.url;
db.users = require("./user.model")(mongoose);
db.playlists = require("./playlist.model")(mongoose);
db.videos = require("./video.model")(mongoose);
db.ads = require("./ad.model")(mongoose);
db.images = require("./image.model")(mongoose);
module.exports = db;

View file

@ -1,16 +0,0 @@
module.exports = mongoose => {
let schema = mongoose.Schema({
name: String,
videos: []
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
return mongoose.model("playlist", schema);
};

View file

@ -1,16 +0,0 @@
module.exports = mongoose => {
let schema = mongoose.Schema({
name: String,
keywords: []
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
return mongoose.model("subjectTarget", schema);
};

View file

@ -1,24 +0,0 @@
const roles = require("../config/role.config");
module.exports = mongoose => {
let schema = mongoose.Schema({
login: String,
hashPass: String, // WARNING: We don't want to send back the hashPass
mail: String,
role: {
type: Number,
default: roles.User
},
playlists: []
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
return mongoose.model("user", schema);
};

View file

@ -1,18 +0,0 @@
module.exports = mongoose => {
let schema = mongoose.Schema({
url: String,
title: String,
description: String,
views: Number
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
return mongoose.model("video", schema);
};

View file

@ -1,24 +0,0 @@
const ads = require("../controllers/ad.controller");
module.exports = app => {
let router = require("express").Router();
// Create a new Ad
router.post("/user/ad", ads.create);
// Retrieve all Ads
router.get("/user/ad", ads.findAll);
// Retrieve a single Ad with id
router.get("/user/ad/:id", ads.findOne);
// Update an Ad with id
router.put("/user/ad/:id", ads.update);
// Delete an Ad with id
router.delete("/user/ad/:id", ads.delete);
// Delete all Ads
router.delete("/user/ad", ads.deleteAll);
app.use('/api', router);
};

View file

@ -1,24 +0,0 @@
const playlists = require("../controllers/playlist.controller");
module.exports = app => {
let router = require("express").Router();
// Create a new Playlist
router.post("/user/playlist", playlists.create);
// Retrieve all Playlists
router.get("/user/playlists", playlists.findAll);
// Retrieve a single Playlist with id
router.get("/user/playlist/:id", playlists.findOne);
// Update a Playlist with id
router.put("/user/playlist/:id", playlists.update);
// Delete a Playlist with id
router.delete("/user/playlist/:id", playlists.delete);
// Delete all Playlists
router.delete("/user/playlists", playlists.deleteAll);
app.use('/api', router);
};

View file

@ -1,30 +0,0 @@
const users = require("../controllers/user.controller");
module.exports = app => {
let router = require("express").Router();
// Create a new User
router.post("/user", users.create);
// Retrieve all Users
router.get("/users", users.findAll);
// Retrieve a single User with id
router.get("/user/:id", users.findOne);
// Update a User with id
router.put("/user/:id", users.update);
// Delete a User with id
router.delete("/user/:id", users.delete);
// Delete all Users
router.delete("/users", users.deleteAll);
// Authenticate a User
router.post("/user/auth", users.auth);
// Logout a User
router.delete("/user/logout", users.disconnect);
app.use('/api', router);
};

View file

@ -1,27 +0,0 @@
const videos = require("../controllers/video.controller");
module.exports = app => {
let router = require("express").Router();
// Search Video
router.post("/videos", videos.search);
// Create a new Video
router.post("/video", videos.create);
// Retrieve all Videos
router.get("/videos", videos.findAll);
// Retrieve a single Video with id
router.get("/video/:id", videos.findOne);
// Update a Video with id
router.put("/video/:id", videos.update);
// Delete a Video with id
router.delete("/video/:id", videos.delete);
// Delete all Videos
router.delete("/videos", videos.deleteAll);
app.use('/api', router);
};

View file

@ -1,724 +0,0 @@
{
"name": "backend",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "16.11.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
"integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w=="
},
"@types/webidl-conversions": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
},
"@types/whatwg-url": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
"integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
"requires": {
"@types/node": "*",
"@types/webidl-conversions": "*"
}
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
"requires": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
}
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
"requires": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"bson": {
"version": "4.5.3",
"resolved": "https://registry.npmjs.org/bson/-/bson-4.5.3.tgz",
"integrity": "sha512-qVX7LX79Mtj7B3NPLzCfBiCP6RAsjiV8N63DjlaVVpZW+PFoDTxQ4SeDbSpcqgE6mXksM5CAwZnXxxxn/XwC0g==",
"requires": {
"buffer": "^5.6.0"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
},
"content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
"requires": {
"safe-buffer": "5.1.2"
}
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
},
"cookie-parser": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
"integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
"requires": {
"cookie": "0.4.0",
"cookie-signature": "1.0.6"
}
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
},
"denque": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ=="
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
},
"ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
"requires": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
"body-parser": "1.19.0",
"content-disposition": "0.5.3",
"content-type": "~1.0.4",
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "~1.1.2",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.5",
"qs": "6.7.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.1.2",
"send": "0.17.1",
"serve-static": "1.14.1",
"setprototypeof": "1.1.1",
"statuses": "~1.5.0",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"http-errors": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"kareem": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz",
"integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ=="
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.50.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz",
"integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A=="
},
"mime-types": {
"version": "2.1.33",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz",
"integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==",
"requires": {
"mime-db": "1.50.0"
}
},
"mongodb": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.1.3.tgz",
"integrity": "sha512-lHvTqODBiSpuqjpCj48DOyYWS6Iq6ElJNUiH9HWdQtONyOfjgsKzJULipWduMGsSzaNO4nFi/kmlMFCLvjox/Q==",
"requires": {
"bson": "^4.5.2",
"denque": "^2.0.1",
"mongodb-connection-string-url": "^2.0.0",
"saslprep": "^1.0.3"
}
},
"mongodb-connection-string-url": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.1.0.tgz",
"integrity": "sha512-Qf9Zw7KGiRljWvMrrUFDdVqo46KIEiDuCzvEN97rh/PcKzk2bd6n9KuzEwBwW9xo5glwx69y1mI6s+jFUD/aIQ==",
"requires": {
"@types/whatwg-url": "^8.2.1",
"whatwg-url": "^9.1.0"
}
},
"mongoose": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.0.12.tgz",
"integrity": "sha512-BvsZk7zEEhb1AgQFLtxN9C+7qgy5edRuA3ZDDwHU+kHG/HM44vI6FdKV5m6HVdAUeCHHQTiVv+YQh8BRsToSHw==",
"requires": {
"bson": "^4.2.2",
"kareem": "2.3.2",
"mongodb": "4.1.3",
"mpath": "0.8.4",
"mquery": "4.0.0",
"ms": "2.1.2",
"regexp-clone": "1.0.0",
"sift": "13.5.2",
"sliced": "1.0.1"
}
},
"mpath": {
"version": "0.8.4",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz",
"integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g=="
},
"mquery": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.0.tgz",
"integrity": "sha512-nGjm89lHja+T/b8cybAby6H0YgA4qYC/lx6UlwvHGqvTq8bDaNeCwl1sY8uRELrNbVWJzIihxVd+vphGGn1vBw==",
"requires": {
"debug": "4.x",
"regexp-clone": "^1.0.0",
"sliced": "1.0.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"requires": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
},
"regexp-clone": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
"integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"send": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.7.2",
"mime": "1.6.0",
"ms": "2.1.1",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
},
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
}
}
},
"serve-static": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.17.1"
}
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"sift": {
"version": "13.5.2",
"resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz",
"integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA=="
},
"sliced": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
"integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
},
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"tr46": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
"integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
"requires": {
"punycode": "^2.1.1"
}
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"webidl-conversions": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
"integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
},
"whatwg-url": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-9.1.0.tgz",
"integrity": "sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA==",
"requires": {
"tr46": "^2.1.0",
"webidl-conversions": "^6.1.0"
}
}
}
}

View file

@ -1,21 +0,0 @@
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Yûki Vachot",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.0.12"
},
"devDependencies": {}
}

View file

@ -1,36 +0,0 @@
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const cookieParser = require('cookie-parser');
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://localhost:4200', credentials: true}));
const db = require("./app/models/mongodb.model");
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
}, function (err){
if(err){
console.log("Cannot connect to the database!", err);
process.exit();
} else{
console.log("Connected to the database!", db.url);
}
});
require("./app/routes/user.routes")(app);
require("./app/routes/playlist.routes")(app);
require("./app/routes/video.routes")(app);
require("./app/routes/ad.routes")(app);
app.listen(port, '0.0.0.0',() => {
console.log (`listening on port ${port}`);
});

View file

@ -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/keys:/data/backend/keys
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

View file

@ -1,37 +0,0 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome'
},
directConnect: true,
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: StacktraceOption.PRETTY
}
}));
}
};

View file

@ -1,23 +0,0 @@
import { browser, logging } from 'protractor';
import { AppPage } from './app.po';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', async () => {
await page.navigateTo();
expect(await page.getTitleText()).toEqual('frontend app is running!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

View file

@ -1,11 +0,0 @@
import { browser, by, element } from 'protractor';
export class AppPage {
async navigateTo(): Promise<unknown> {
return browser.get(browser.baseUrl);
}
async getTitleText(): Promise<string> {
return element(by.css('app-root .content span')).getText();
}
}

View file

@ -1,13 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es2018",
"types": [
"jasmine",
"node"
]
}
}

View file

@ -1,4 +0,0 @@
build:
docker:
frontend: Dockerfile
backend: backend/Dockerfile

View file

@ -1,44 +0,0 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/frontend'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

36834
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,50 +0,0 @@
{
"name": "frontend",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^12.2.11",
"@angular/cdk": "^12.2.11",
"@angular/common": "^12.2.11",
"@angular/compiler": "^12.2.11",
"@angular/core": "^12.2.11",
"@angular/forms": "^12.2.11",
"@angular/material": "^12.2.11",
"@angular/platform-browser": "^12.2.11",
"@angular/platform-browser-dynamic": "^12.2.11",
"@angular/router": "^12.2.11",
"bootstrap": "^5.1.3",
"jquery": "^3.6.0",
"popper": "^1.0.1",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.11.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.11",
"@angular/cli": "~12.2.11",
"@angular/compiler-cli": "~12.2.11",
"@types/jasmine": "~3.6.0",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.3.5",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.3.5"
}
}

View file

@ -1,22 +0,0 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {PageConnexionComponent} from './pourLes3Roles/page-connexion/page-connexion.component';
import {PageRegisterComponent} from './pourLes3Roles/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";
const routes: Routes = [
{ path: '', component: PageConnexionComponent },
{ path: 'connexion', component: PageConnexionComponent },
{ path: 'register', component: PageRegisterComponent },
{ path: 'search', component: PageSearchComponent },
{ path: 'myPlaylists', component: PageMyPlaylistsComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

View file

@ -1 +0,0 @@
<router-outlet></router-outlet>

View file

@ -1,7 +0,0 @@
::ng-deep snack-bar-container.custom-class {
//background: yellow;
}
::ng-deep .custom-class .mat-simple-snackbar {
//color: green;
justify-content: center;
}

View file

@ -1,35 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'frontend'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('frontend');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('frontend app is running!');
});
});

View file

@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'frontend';
themeIsLight = true;
}

View file

@ -1,74 +0,0 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PageConnexionComponent } from './pourLes3Roles/page-connexion/page-connexion.component';
import { PageRegisterComponent } from './pourLes3Roles/register/page-register/page-register.component';
import { NavBarComponent } from './utils/components/nav-bar/nav-bar.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {FormsModule} from "@angular/forms";
import { PageSearchComponent } from './user/search/page-search/page-search.component';
import {HttpClientModule} from "@angular/common/http";
import { PopupConfirmationComponent } from './pourLes3Roles/register/popup-confirmation/popup-confirmation.component';
import {MatDialogModule} from '@angular/material/dialog';
import {MatButtonModule} from "@angular/material/button";
import { AdvertComponent } from './utils/components/advert/advert.component';
import { VideoCellComponent } from './user/search/video-cell/video-cell.component';
import { VideoGridComponent } from './user/search/video-grid/video-grid.component';
import {MatIconModule} from "@angular/material/icon";
import { PopupAddVideoToPlaylistsComponent } from './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 { IframeTrackerDirective } from './utils/directives/iframe-tracker/iframe-tracker.directive';
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 { PopupCreatePlaylistComponent } from './utils/components/popup-create-playlist/popup-create-playlist.component';
@NgModule({
declarations: [
AppComponent,
PageConnexionComponent,
PageRegisterComponent,
NavBarComponent,
PageSearchComponent,
PopupConfirmationComponent,
AdvertComponent,
VideoCellComponent,
VideoGridComponent,
PopupAddVideoToPlaylistsComponent,
IframeTrackerDirective,
PageMyPlaylistsComponent,
VideoListComponent,
PlaylistListComponent,
VideoListComponent,
PopupCreatePlaylistComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatSlideToggleModule,
FormsModule,
HttpClientModule,
MatDialogModule,
MatButtonModule,
MatIconModule,
MatInputModule,
MatDividerModule,
MatCheckboxModule,
MatFormFieldModule,
MatSnackBarModule,
MatGridListModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

View file

@ -1,41 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<app-nav-bar pour="3roles"></app-nav-bar>
<div class="boite">
<h1> Connexion </h1>
<!-- Email -->
<div class="row">
<div class="col-4 label"> Email: &nbsp; </div>
<div class="col-8 champ">
<input type="text" [(ngModel)]="email">
</div>
</div>
<!-- Mot de passe -->
<div class="row">
<div class="col-4 label"> Mot de passe: &nbsp; </div>
<div class="col-8 champ">
<input type="text" [(ngModel)]="password">
</div>
</div>
<!-- Boutons -->
<div class="row">
<div class="col-6">
<button (click)="onSeConnecter()"> Se connecter </button>
</div>
<div class="col-6" style="text-align: right">
<button routerLink="/register"> S'inscrire </button>
</div>
</div>
<!-- Mot de passe oublié -->
<div style="text-align: right">
<a class="lien" href="https://pixar.fandom.com/wiki/Sadness"> Mot de passe oublié ? </a>
</div>
</div>
</div>
</div>

View file

@ -1,64 +0,0 @@
.myContainer {
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
font-size: x-large;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.boite {
margin-left: auto;
margin-right: auto;
width: 30%;
margin-top: 50vh;
transform: translateY(-100%);
border: solid 3px;
border-radius: 10px;
padding: 20px 40px 20px 20px;
background-color: #dcdcdc;
}
.lightTheme .boite {
border-color: black;
}
.darkTheme .boite {
border-color: white;
}
.row {
margin: 25px 0px 25px 0px
}
.label {
text-align: right;
margin-right: 0px;
padding: 0px;
}
.champ {
margin: 0px;
padding: 0px;
}
input {
width: 100%;
}
button {
width: 100%;
margin-right: 0px;
}
.col-6 {
//text-align: center;
}
.lien {
text-decoration: underline;
color: black;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageConnexionComponent } from './page-connexion.component';
describe('PageConnexionComponent', () => {
let component: PageConnexionComponent;
let fixture: ComponentFixture<PageConnexionComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageConnexionComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageConnexionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,45 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {MessageService} from "../../utils/services/message/message.service";
import {Router} from "@angular/router";
import {ThemeService} from "../../utils/services/theme/theme.service";
@Component({
selector: 'app-page-connexion',
templateUrl: './page-connexion.component.html',
styleUrls: ['./page-connexion.component.scss']
})
export class PageConnexionComponent implements OnInit
{
email: string = ""
password: string = ""
constructor( private messageService: MessageService,
private router: Router,
public themeService: ThemeService ) { }
ngOnInit(): void {}
onSeConnecter(): void
{
let data = {
"email": this.email,
"password": this.password
};
this.messageService
.sendMessage('connexion', data)
.subscribe( retour => this.maCallback(retour))
}
maCallback(retour): void
{
if(retour.status === "error") console.log(retour.data)
else {
console.log(retour.data)
//this.router.navigateByUrl( '/search' );
}
}
}

View file

@ -1,53 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<app-nav-bar pour="3roles"></app-nav-bar>
<div class="boite">
<h1> Inscription </h1>
<!-- Pseudo -->
<div class="row">
<div class="col-6 label"> Pseudo: &nbsp; </div>
<div class="col-6 champ">
<input type="text" [(ngModel)]="pseudo">
</div>
</div>
<!-- Email -->
<div class="row">
<div class="col-6 label"> Email: &nbsp; </div>
<div class="col-6 champ">
<input type="email" [(ngModel)]="email">
</div>
</div>
<!-- Mot de passe -->
<div class="row">
<div class="col-6 label"> Mot de passe: &nbsp; </div>
<div class="col-6 champ">
<input type="password" [(ngModel)]="password">
</div>
</div>
<!-- Confirmation mot de passe -->
<div class="row">
<div class="col-6 label"> Confirmer le mot de passe: &nbsp; </div>
<div class="col-6 champ">
<input type="password" [(ngModel)]="confirmPassword">
</div>
</div>
<!-- Bouton valider -->
<div style="width: 100%; margin-top: 30px">
<button (click)="onValider()"> Valider </button>
</div>
<!-- Message d'erreur -->
<div *ngIf="hasError" style="text-align: center">
<span class="mat-error"> {{errorMessage}} </span>
</div>
</div>
</div>
</div>

View file

@ -1,58 +0,0 @@
.myContainer {
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
font-size: x-large;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.boite {
margin-left: auto;
margin-right: auto;
width: 35%;
margin-top: 50vh;
transform: translateY(-100%);
border: solid 3px;
border-radius: 10px;
padding: 20px 40px 20px 40px;
background-color: #dcdcdc;
}
.lightTheme .boite {
border-color: black;
}
.darkTheme .boite {
border-color: white;
}
input {
width: 100%;
}
.row {
margin: 15px 0px 15px 0px
}
.label {
text-align: right;
margin-right: 0px;
padding: 0px;
}
.champ {
margin: 0px;
padding: 0px
}
button {
width: 100%;
margin-right: 0px;
background-color: #969696;
border: solid 2px black;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageRegisterComponent } from './page-register.component';
describe('PageRegisterComponent', () => {
let component: PageRegisterComponent;
let fixture: ComponentFixture<PageRegisterComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageRegisterComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageRegisterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,97 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {MessageService} from "../../../utils/services/message/message.service";
import {Router} from "@angular/router";
import {MatDialog} from "@angular/material/dialog";
import {PopupConfirmationComponent} from "../popup-confirmation/popup-confirmation.component";
import {ThemeService} from "../../../utils/services/theme/theme.service";
@Component({
selector: 'app-page-register',
templateUrl: './page-register.component.html',
styleUrls: ['./page-register.component.scss']
})
export class PageRegisterComponent implements OnInit
{
pseudo: string = "";
email: string = "" ;
password: string = "";
confirmPassword: string = "";
hasError: boolean = false;
errorMessage: string = "";
constructor( private messageService: MessageService,
private router: Router,
public dialog: MatDialog,
public themeService: ThemeService ) { }
ngOnInit(): void {}
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);
}
verifierChamps(): void
{
if(this.pseudo.length === 0) {
this.errorMessage = "Veuillez remplir le champ 'pseudo'"
this.hasError = true;
}
else if(this.email.length === 0)
{
this.errorMessage = "Veuillez remplir le champ 'email'"
this.hasError = true;
}
else if(!this.isValidEmail(this.email))
{
this.errorMessage = "Email invalide"
this.hasError = true;
}
else if(this.password.length === 0)
{
this.errorMessage = "Veuillez remplir le champ 'mot de passe'"
this.hasError = true;
}
else if(this.password !== this.confirmPassword)
{
this.errorMessage = "Le mot de passe est différent de sa confirmation"
this.hasError = true;
}
else {
this.hasError = false;
}
}
onValider(): void
{
this.verifierChamps()
console.log(this.hasError)
if(!this.hasError)
{
let data = { "pseudo": this.pseudo, "email": this.email, "password": this.password }
this.messageService
.sendMessage('register', data)
.subscribe(retour => this.maCallback(retour))
}
}
maCallback(retour): void
{
if(retour.status === "error") console.log(retour.data)
else
{
const config = { width: '25%', data: {} }
this.dialog
.open(PopupConfirmationComponent, config )
.afterClosed()
.subscribe(result => this.router.navigateByUrl( '/connexion' ));
}
}
}

View file

@ -1,4 +0,0 @@
<p> Votre inscription a bien été effectué. </p>
<div style="text-align: right">
<button mat-button mat-dialog-close> Continuer </button>
</div>

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupConfirmationComponent } from './popup-confirmation.component';
describe('PopupConfirmationComponent', () => {
let component: PopupConfirmationComponent;
let fixture: ComponentFixture<PopupConfirmationComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupConfirmationComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupConfirmationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,18 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
@Component({
selector: 'app-popup-confirmation',
templateUrl: './popup-confirmation.component.html',
styleUrls: ['./popup-confirmation.component.scss']
})
export class PopupConfirmationComponent
{
constructor( public dialogRef: MatDialogRef<PopupConfirmationComponent>,
@Inject(MAT_DIALOG_DATA) public data) {}
onClick(): void
{
this.dialogRef.close();
}
}

View file

@ -1,38 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<div style="margin-bottom: 50px">
<app-nav-bar pour="user"></app-nav-bar>
</div>
<!-- --------------------------------------------------------------------- -->
<!-- [liste des videos] + [liste des playlist] + [pub] -->
<mat-grid-list cols="10" rowHeight="85vh">
<!-- liste des videos -->
<mat-grid-tile colspan="4" rowspan="1" class="celluleListeVideo">
<div class="videoListContainer">
<app-video-list [playlist]="playlist"></app-video-list>
</div>
</mat-grid-tile>
<!-- liste des playlist -->
<mat-grid-tile colspan="4" rowspan="1" class="celluleListePlaylist">
<div class="playlistListContainer">
<app-playlist-list [allPlaylists]="allPlaylists" (eventEmitter)="transmitToVideoList($event)"></app-playlist-list>
</div>
</mat-grid-tile>
<!-- pub -->
<mat-grid-tile colspan="2" rowspan="1" class="cellulePub">
<div class="conteneurPub">
<app-advert [ad]="ad"></app-advert>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
</div>

View file

@ -1,51 +0,0 @@
.lightTheme {
border-color: black;
}
.darkTheme {
border-color: white;
}
.myContainer {
text-align: center;
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
}
// Liste des vidéos -------------------------------------------------
.celluleListeVideo {
margin: 0px;
}
// Liste des playlists ---------------------------------------------
.celluleListePlaylist {
margin: 0px;
}
.playlistListContainer {
}
// Pub -------------------------------------------------------------
.cellulePub {
padding: 0px 10px 0px 10px;
width: 100%;
text-align: center;
justify-content: center;
}
.conteneurPub {
height: 85vh;
text-align: center;
justify-content: center;
vertical-align: middle;
display: block;
width: 75%;
margin-left: auto;
margin-right: auto;
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageMyPlaylistsComponent } from './page-my-playlists.component';
describe('PageMesPlaylistsComponent', () => {
let component: PageMyPlaylistsComponent;
let fixture: ComponentFixture<PageMyPlaylistsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageMyPlaylistsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageMyPlaylistsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,52 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {Advert} from "../../../utils/interfaces/advert";
import {FictitiousDatasService} from "../../../utils/services/fictitiousDatas/fictitious-datas.service";
import {MessageService} from "../../../utils/services/message/message.service";
import {Playlist} from "../../../utils/interfaces/playlist";
@Component({
selector: 'app-page-my-playlists',
templateUrl: './page-my-playlists.component.html',
styleUrls: ['./page-my-playlists.component.scss']
})
export class PageMyPlaylistsComponent implements OnInit
{
allPlaylists: Playlist[]; // toutes les playlists
ad: Advert; // pub
playlist: Playlist; // la playlist sélectionnée
constructor( public themeService: ThemeService,
private messageService: MessageService,
private fictitioousData: FictitiousDatasService ) { }
ngOnInit(): void
{
// --- FAUX CODE ---
this.allPlaylists = this.fictitioousData.getTabPlaylist(10, 10);
this.ad = this.fictitioousData.getAdvert();
// --- VRAI CODE ---
/*
this.messageService
.sendMessage("user/get/playlists", null)
.subscribe( retour => {
if(retour.status === "error") console.log(retour.data);
else {
this.tabPlaylists = retour.data.playlists;
this.ad = retour.data.ad;
}
})
*/
}
transmitToVideoList(playlist: Playlist): void
{
this.playlist = playlist;
}
}

View file

@ -1,36 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Search bar -->
<div class="row" style="margin: 0px">
<div class="searchBarContainer">
<input type="search" placeholder="recherche..." class="inputSearchBar" [(ngModel)]="search" (ngModelChange)="whileSearch()"> &nbsp;
<!--
<button class="btnRechercher" (click)="onSearch()"> Rechercher </button>
-->
</div>
</div>
<!-- Liste des playlist -->
<div class="row" style="margin: 0px">
<div class="playlistListContainer">
<div *ngFor="let playlist of tabPlaylist" class="playlistContainer">
<button class="btnPlaylist" (click)="eventEmitter.emit(playlist)">
<span class="playlistName"> {{playlist.name}} </span><br>
<span class="playListCount"> {{playlist.videos.length}} vidéos </span>
</button>
</div>
</div>
</div>
<!-- Bouton creer playlist-->
<div class="row" style="margin: 0px">
<div class="btnCreerPlaylistContainer">
<button class="btnCreerPlaylist" (click)="onCreatePlaylist()"> Creer playlist </button>
</div>
</div>
</div>
</div>

View file

@ -1,75 +0,0 @@
.myContainer {
background-color: white ;
text-align: center;
width: 35vw;
height: 79vh;
margin: 3vh 0vh 3vh 0vh;
padding: 0px;
border: solid 2px black;
}
// SearchBar -----------------------------------------------------------
.searchBarContainer {
background-color: #dcdcdc;
border-bottom: solid 2px black;
height: 5vh;
padding: 15px;
}
.inputSearchBar {
width: 50%;
}
.btnRechercher {
border: solid black 1px;
border-radius: 5px;
}
// Liste des playlists -------------------------------------------------
.playlistListContainer {
max-width: 100%;
height: 70vh;
overflow-y: scroll;
padding: 0px;
}
.playlistContainer {
max-width: 100%;
padding: 0px;
}
.btnPlaylist {
background-color: white;
padding: 20px;
border-bottom: solid 2px black;
width: 100%;
}
.btnPlaylist:hover {
background-color: #f0f0f0;
}
.playListCount {
color: gray;
font-style: italic;
}
// Bouton creer playlist -------------------------------------------------
.btnCreerPlaylistContainer {
height: 4vh;
margin: 0px;
padding: 0px;
}
.btnCreerPlaylist {
background-color: #dcdcdc;
border-top: solid 2px black;
border-bottom: solid 2px black;
height: 100%;
width: 100%;
padding: 10px;
}
.btnCreerPlaylist:hover {
background-color: #969696;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PlaylistListComponent } from './playlist-list.component';
describe('PlaylistListComponent', () => {
let component: PlaylistListComponent;
let fixture: ComponentFixture<PlaylistListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PlaylistListComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PlaylistListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,67 +0,0 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {Playlist} from "../../../utils/interfaces/playlist";
import {MessageService} from "../../../utils/services/message/message.service";
import {MatDialog} from "@angular/material/dialog";
import {PopupAddVideoToPlaylistsComponent} from "../../../utils/components/popup-add-video-to-playlists/popup-add-video-to-playlists.component";
import {MatSnackBar} from "@angular/material/snack-bar";
import {PopupCreatePlaylistComponent} from "../../../utils/components/popup-create-playlist/popup-create-playlist.component";
@Component({
selector: 'app-playlist-list',
templateUrl: './playlist-list.component.html',
styleUrls: ['./playlist-list.component.scss']
})
export class PlaylistListComponent implements OnInit
{
@Input() allPlaylists: Playlist[] = []; // toutes les playlists
@Output() eventEmitter = new EventEmitter<Playlist>(); // pour envoyer au parent la playlist selectionner
search: string = "" ; // contenu de la barre de recherche
tabPlaylist: Playlist[] = []; // playlist affichées
constructor( public themeService: ThemeService,
public dialog: MatDialog,
public snackBar: MatSnackBar ) { }
ngOnInit(): void
{
this.tabPlaylist = [].concat(this.allPlaylists);
}
whileSearch()
{
console.log("whileSearch");
this.tabPlaylist = [];
for(let playlist of this.allPlaylists)
{
if(playlist.name.includes(this.search)) this.tabPlaylist.push(playlist);
}
}
onCreatePlaylist(): void
{
const config = { width: '15%', data: this.tabPlaylist };
this.dialog
.open(PopupCreatePlaylistComponent, config )
.afterClosed()
.subscribe(playlist => {
const config = { duration: 1000, panelClass: "custom-class" };
if((playlist === null) || (playlist === undefined)) {
this.snackBar.open("Opération annulée ❌", "", config);
}
else {
this.allPlaylists.push(playlist);
this.tabPlaylist.push(playlist);
this.snackBar.open("La playlist a bien été créée ✔", "", config);
}
});
}
}

View file

@ -1,74 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Bordure haute -->
<div class="row" style="margin: 0px; padding: 0px">
<div class="topBorder">
<!-- Playlist existe ? -->
<div *ngIf="(playlist !== null) && (playlist !== undefined); then ok1 else nope1"></div>
<!-- oui -->
<ng-template #ok1>
<span class="spanPlayListTitle"> {{playlist.name}} </span>
</ng-template>
<!-- non -->
<ng-template #nope1>
<span class="spanPlayListTitle"> Aucune playlist selectionnée </span>
</ng-template>
</div>
</div>
<!-- --------------------------------------------------------------------------------------------------------------------- -->
<!-- Liste des videos -->
<div class="row" style="margin: 0px; padding: 0px">
<div class="listVideoContainer">
<!-- Playlist existe ? -->
<div *ngIf="(playlist !== null) && (playlist !== undefined); then ok2 else nope2"></div>
<!-- oui -->
<ng-template #ok2>
<div *ngFor="let video of playlist.videos ; let i = index" class="videoContainer">
<!-- bouton add -->
<button mat-icon-button (click)="onAdd(video)">
<mat-icon > add_circle </mat-icon>
</button>
<!-- video -->
<iframe appIframeTracker
[src]=videoUrlService.safeUrl(this.video.url)
allowfullscreen
(iframeClick)="onIframeClick(this.video.url)"></iframe>
<!-- bouton delete -->
<button mat-icon-button (click)="onDelete(video, i)">
<mat-icon>delete</mat-icon>
</button><br/>
<!-- titre video -->
<span>{{video.title}}</span>
</div>
</ng-template>
<!-- non -->
<ng-template #nope2>
<div></div>
</ng-template>
</div>
</div>
<!-- --------------------------------------------------------------------------------------------------------------------- -->
<!-- Bordure basse -->
<div class="row" style="margin: 0px; padding: 0px">
<div class="bottomBorder"></div>
</div>
</div>
</div>

View file

@ -1,52 +0,0 @@
.myContainer {
background-color: white ;
text-align: center;
width: 35vw;
height: 79vh;
margin: 3vh 0vh 3vh 0vh;
padding: 0px;
border: solid 1px black;
}
// TopBorder --------------------------------------------------------
.topBorder {
height: 4vh;
background-color: #dcdcdc;
text-align: left;
padding: 7px;
display: inline-block;
border-bottom: solid 1px black;
}
.spanPlayListTitle {
height: 100%;
padding: 0px;
font-size: x-large;
font-weight: bold;
}
// Liste des videos ------------------------------------------------
.listVideoContainer {
height: 73vh;
background-color: white;
padding: 0px;
overflow-y: scroll;
}
.videoContainer {
border-bottom: solid 2px black;
padding: 25px;
}
// BottomBorder --------------------------------------------------------
.bottomBorder {
height: 2vh;
background-color: #dcdcdc;
border-top: solid 1px black;
border-bottom: solid 1px black;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { VideoListComponent } from './video-list.component';
describe('VideoListComponent', () => {
let component: VideoListComponent;
let fixture: ComponentFixture<VideoListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ VideoListComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(VideoListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,69 +0,0 @@
import {Component, Input, OnInit} from '@angular/core';
import {ThemeService} from "../../../utils/services/theme/theme.service";
import {FictitiousDatasService} from "../../../utils/services/fictitiousDatas/fictitious-datas.service";
import {Video} from "../../../utils/interfaces/video";
import {VideoUrlService} from "../../../utils/services/videoUrl/video-url.service";
import {AddVideoToPlaylistsService} from "../../../utils/services/addVideoToPlaylists/add-video-to-playlists.service";
import {MessageService} from "../../../utils/services/message/message.service";
import {Playlist} from "../../../utils/interfaces/playlist";
import {MatSnackBar} from "@angular/material/snack-bar";
@Component({
selector: 'app-video-list',
templateUrl: './video-list.component.html',
styleUrls: ['./video-list.component.scss']
})
export class VideoListComponent
{
@Input() playlist: Playlist;
constructor( private messageService: MessageService,
public themeService: ThemeService,
private fictitiousDatasService: FictitiousDatasService,
public videoUrlService: VideoUrlService,
private addVideoToPlaylistService: AddVideoToPlaylistsService,
private snackBar: MatSnackBar ) { }
onAdd(video: Video): void
{
this.addVideoToPlaylistService.run(video);
}
onDelete(video0: Video, indexVideo: number): void
{
// --- FAUX CODE ---
let message = "La video a bien été supprimé de la playlist" ;
this.playlist.videos.splice(indexVideo, 1);
const config = { duration: 1000, panelClass: "custom-class" };
this.snackBar.open( message, "", config);
// --- VRAI CODE ---
/*
this.messageService
.sendMessage("user/delete/video", {video: video0, playlist: this.playlist})
.subscribe( retour => {
let message = "" ;
if(retour.status === "error") message = "Echec de l'opération" ;
else {
message = "La video a bien été supprimé de la playlist" ;
this.playlist.videos.splice(index, 1);
}
const config = { duration: 1000, panelClass: "custom-class" };
this.snackBar.open( message, "", config);
})
*/
}
onIframeClick(videoUrl: string): void
{
console.log(videoUrl)
}
}

View file

@ -1,75 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<div style="margin-bottom: 50px">
<app-nav-bar pour="user"></app-nav-bar>
</div>
<!-- --------------------------------------------------------------------- -->
<!-- [Search bar] + [Site de streaming] -->
<div class="row">
<div class="col-2"></div>
<div class="col-8" style="margin-bottom: 20px">
<!-- Search bar -->
<div class="row" style="margin-bottom: 10px">
<div>
<input type="search" placeholder="recherche..." class="inputSearchBar" [(ngModel)]="search"> &nbsp;
<button class="btnRechercher" (click)="onSearch()"> Rechercher </button>
</div>
</div>
<!-- Site de streaming -->
<div class="row" style="margin-bottom: 10px">
<div>
<span *ngFor="let plateforme of tabPlateform">
&nbsp;
<input type="checkbox" [id]="plateforme.name" [name]="plateforme.name" style="margin-left: 5px" [(ngModel)]="plateforme.isSelected">
<img [src]="'/assets/logo_plateforms/'+plateforme.name+'.png'" alt="image" width="25px" height="25px" style="margin-left: 5px">
<label [for]="plateforme.name" style="margin-left: 5px"> {{plateforme.name}}</label>
&nbsp;
</span>
</div>
</div>
</div>
<div class="col-2"></div>
</div>
<!-- --------------------------------------------------------------------- -->
<!-- [pub gauche] + [Grilles des videos] + [pub droite] -->
<mat-grid-list cols="11" rowHeight="75vh">
<!-- pub gauche -->
<mat-grid-tile colspan="2" rowspan="1" class="cellulePub">
<div class="conteneurPub">
<app-advert [ad]="ad1"></app-advert>
</div>
</mat-grid-tile>
<!-- Grilles des videos -->
<mat-grid-tile colspan="7" rowspan="1" class="celluleGrilleVideo">
<div class="conteneurVideosGrid">
<app-video-grid [tabVideo]="tabVideo"></app-video-grid>
</div>
</mat-grid-tile>
<!-- pub droite -->
<mat-grid-tile colspan="2" rowspan="1" class="cellulePub">
<div class="conteneurPub">
<app-advert [ad]="ad1"></app-advert>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
</div>

View file

@ -1,68 +0,0 @@
.lightTheme {
color: black;
border-color: black;
}
.darkTheme {
color: white;
border-color: white;
}
.myContainer {
text-align: center;
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
}
.inputSearchBar {
width: 50%;
font-size: x-large;
}
.btnRechercher {
border: solid black 1px;
border-radius: 5px;
font-size: x-large;
}
.celluleGrilleVideo {
border: solid 4px;
border-radius: 5px;
width: 100%;
}
.lightTheme .celluleGrilleVideo{
border-color: black;
background-color: #f0f0f0;
}
.darkTheme .celluleGrilleVideo{
border-color: white;
background-color: #646464;
}
.conteneurVideosGrid {
height: 75vh;
width: 100%;
}
.cellulePub {
padding: 0px 10px 0px 10px;
width: 100%;
text-align: center;
justify-content: center;
}
.conteneurPub {
height: 75vh;
text-align: center;
justify-content: center;
vertical-align: middle;
display: block;
width: 75%;
margin-left: auto;
margin-right: auto;
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageSearchComponent } from './page-search.component';
describe('PageSearchComponent', () => {
let component: PageSearchComponent;
let fixture: ComponentFixture<PageSearchComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageSearchComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageSearchComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,96 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {MessageService} from "../../../utils/services/message/message.service";
import {FictitiousDatasService} from "../../../utils/services/fictitiousDatas/fictitious-datas.service";
import {AddVideoToPlaylistsService} from "../../../utils/services/addVideoToPlaylists/add-video-to-playlists.service";
import {Video} from "../../../utils/interfaces/video";
import {Advert} from "../../../utils/interfaces/advert";
import {ThemeService} from "../../../utils/services/theme/theme.service";
let TAB_PLATEFORM = [
{ name: "Youtube", isSelected: false },
{ name: "Dailymotion", isSelected: false }
];
@Component({
selector: 'app-page-search',
templateUrl: './page-search.component.html',
styleUrls: ['./page-search.component.scss']
})
export class PageSearchComponent implements OnInit
{
tabPlateform = TAB_PLATEFORM;
tabVideo: Video[] = [];
search: string = "";
ad1: Advert;
ad2: Advert;
constructor( private messageService: MessageService,
private fictitiousDatasService: FictitiousDatasService,
public themeService: ThemeService ) { }
ngOnInit(): void
{
// --- FAUX CODE ---
this.tabVideo = this.fictitiousDatasService.getTabVideo(11);
this.ad1 = this.fictitiousDatasService.getAdvert();
this.ad2 = this.fictitiousDatasService.getAdvert();
// --- VRAI CODE ---
/*
let tabPlateformName = [];
for(let plateform of this.tabPlateform) tabPlateformName.push(plateform.name);
let data = { search: "", plaateforms: tabPlateformName };
this.messageService
.sendMessage("user/searchVideo", data)
.subscribe( retour => {
if(retour.status === "error") console.log(retour.data);
else {
this.tabVideo = retour.data.videos;
this.ad1 = retour.data.ad1;
this.ad2 = retour.data.ad2;
}
});
*/
}
onSearch()
{
// --- FAUX CODE ---
this.tabVideo = this.fictitiousDatasService.getTabVideo(4);
// --- VRAI CODE ---
/*
let tabPlateformName = [];
for(let plateform of this.tabPlateform)
{
if(plateform.isSelected) tabPlateformName.push(plateform.name);
}
let data = { "search": this.search, "plateforms": tabPlateformName };
this.messageService
.sendMessage("user/searchVideo", data)
.subscribe(retour => {
if(retour.status === "error") console.log(retour.data);
else {
this.tabVideo = retour.data.videos;
this.ad1 = retour.data.ad1;
this.ad2 = retour.data.ad2;
}
});
*/
}
tiles = [
{text: 'One', cols: 2, rows: 1, color: 'lightblue'},
{text: 'Two', cols: 7, rows: 1, color: 'lightgreen'},
{text: 'Three', cols: 2, rows: 1, color: 'lightpink'},
];
}

View file

@ -1,11 +0,0 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div [class]="themeService.getClassTheme()">
<div class="conteneur">
<iframe appIframeTracker [src]=safeUrl allowfullscreen (iframeClick)="onIframeClick(this.video.url)"></iframe><br/>
<span>{{video.title}}</span>
<button mat-icon-button (click)="onAdd()">
<mat-icon > add_circle </mat-icon>
</button>
</div>
</div>

View file

@ -1,18 +0,0 @@
.conteneur {
text-align: center;
border: solid 2px;
border-radius: 5px;
padding-top: 15px;
}
.lightTheme .conteneur {
background-color: #ffffff;
border-color: black;
font-color: black;
}
.darkTheme .conteneur {
background-color: #c8c8c8;
border-color: #ffffff;
font-color: white;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { VideoCellComponent } from './video-cell.component';
describe('RectangleVideoComponent', () => {
let component: VideoCellComponent;
let fixture: ComponentFixture<VideoCellComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ VideoCellComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(VideoCellComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,38 +0,0 @@
import {
Component,
Input,
OnInit,
} from '@angular/core';
import {VideoUrlService} from "../../../utils/services/videoUrl/video-url.service";
import {AddVideoToPlaylistsService} from "../../../utils/services/addVideoToPlaylists/add-video-to-playlists.service";
import {Video} from "../../../utils/interfaces/video";
import {ThemeService} from "../../../utils/services/theme/theme.service";
@Component({
selector: 'app-video-cell',
templateUrl: './video-cell.component.html',
styleUrls: ['./video-cell.component.scss']
})
export class VideoCellComponent implements OnInit
{
@Input() video: Video;
safeUrl;
constructor( private videoUrlService: VideoUrlService,
private addVideoToPlaylistsService: AddVideoToPlaylistsService,
public themeService: ThemeService) {}
ngOnInit(): void
{
this.safeUrl = this.videoUrlService.safeUrl(this.video.url);
}
onAdd(): void
{
this.addVideoToPlaylistsService.run(this.video);
}
onIframeClick(videoUrl: string) {
console.log("test click iframe "+ videoUrl);
}
}

View file

@ -1,11 +0,0 @@
<div class="conteneur">
<nav>
<ul>
<li class="row ligne" *ngFor="let triplet of tabTriplet">
<div class="col-4" *ngFor="let video0 of triplet">
<app-video-cell [video]="video0"></app-video-cell>
</div>
</li>
</ul>
</nav>
</div>

View file

@ -1,14 +0,0 @@
.conteneur {
height: 100%;
}
nav ul {
overflow: hidden;
overflow-y: scroll;
height: 75vh;
padding: 30px;
}
.ligne {
margin: 30px 0px 30px 0px;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { VideoGridComponent } from './video-grid.component';
describe('VideoGridComponent', () => {
let component: VideoGridComponent;
let fixture: ComponentFixture<VideoGridComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ VideoGridComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(VideoGridComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,34 +0,0 @@
import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {Video} from "../../../utils/interfaces/video";
@Component({
selector: 'app-video-grid',
templateUrl: './video-grid.component.html',
styleUrls: ['./video-grid.component.scss']
})
export class VideoGridComponent implements OnChanges
{
@Input() tabVideo: Video[] = [];
tabTriplet = [];
ngOnChanges(changes: SimpleChanges): void
{
this.tabTriplet = [];
let n = this.tabVideo.length;
let i = 0;
while(i < n)
{
let triplet = []
let compteur = 0;
while((compteur < 3) && (i < n))
{
triplet.push(this.tabVideo[i]);
i++ ;
compteur++ ;
}
this.tabTriplet.push(triplet)
}
}
}

View file

@ -1,6 +0,0 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<span class="helper"></span>
<img [src]="'assets/pub/'+ad.images[idxImage].url" [alt]="ad.images[idxImage].url">
</div>
</div>

View file

@ -1,28 +0,0 @@
.myContainer {
margin: 0;
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
img {
max-width: 100%;
max-height: 100%;
border: solid 3px;
vertical-align: middle;
}
.lightTheme img {
border-color: black;
}
.darkTheme img {
border-color: white;
}
.helper {
display: inline-block;
height: 100%;
vertical-align: middle;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AdvertComponent } from './advert.component';
describe('PubComponent', () => {
let component: AdvertComponent;
let fixture: ComponentFixture<AdvertComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AdvertComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AdvertComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,27 +0,0 @@
import {Component, Input, OnInit} from '@angular/core';
import {Advert} from "../../interfaces/advert";
import {ThemeService} from "../../services/theme/theme.service";
@Component({
selector: 'app-advert',
templateUrl: './advert.component.html',
styleUrls: ['./advert.component.scss']
})
export class AdvertComponent implements OnInit
{
@Input() ad: Advert;
idxImage: number = 0;
constructor(public themeService: ThemeService) { }
ngOnInit(): void
{
const nbImages = this.ad.images.length;
this.idxImage = Math.floor(Math.random() * nbImages);
}
}

View file

@ -1,41 +0,0 @@
<div [class]="themeService.getClassTheme()">
<!-- pour les 3 roles -->
<div *ngIf="pour === '3roles'">
<ul>
<li>
<a routerLink="/connexion" class="StreamNotFound"> StreamNotFound </a>
</li>
<li style="float:right; margin-right: 20px;">
<mat-slide-toggle (click)="onClick()"></mat-slide-toggle>
</li>
</ul>
</div>
<!-- pour User -->
<div *ngIf="pour === 'user'">
<ul>
<li>
<a routerLink="/search" class="StreamNotFound"> StreamNotFound </a>
</li>
<li class="cliquable">
<a routerLink="/search"> Rechercher </a>
</li>
<li class="cliquable">
<a routerLink="/myPlaylists"> Mes playlists </a>
</li>
<li class="cliquable">
<a routerLink="/search"> Historique </a>
</li>
<li style="float:right; margin-right: 20px;">
<a routerLink="/search">
<mat-icon>settings</mat-icon>
</a>
</li>
<li style="float:right; margin-right: 20px;">
<mat-slide-toggle (click)="onClick()"></mat-slide-toggle>
</li>
</ul>
</div>
</div>

View file

@ -1,69 +0,0 @@
.StreamNotFound {
font-style: oblique;
font-family: cursive;
font-size: xx-large;
}
mat-icon {
margin-top: 2px;
font-size: xx-large;
}
mat-slide-toggle {
margin-top: 20px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: black;
height: 70px;
color: white;
border-bottom: solid 2px white;
}
li {
float: left;
font-size: x-large;
background-color: black;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
background-color: black;
}
.cliquable a:hover:not(.active) {
background-color: #c8c8c8;
}
::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;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavBarComponent } from './nav-bar.component';
describe('NavBarComponent', () => {
let component: NavBarComponent;
let fixture: ComponentFixture<NavBarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NavBarComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(NavBarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,19 +0,0 @@
import {Component, Input, OnInit} from '@angular/core';
import {ThemeService} from "../../services/theme/theme.service";
@Component({
selector: 'app-nav-bar',
templateUrl: './nav-bar.component.html',
styleUrls: ['./nav-bar.component.scss']
})
export class NavBarComponent
{
@Input() pour = "3roles";
constructor(public themeService: ThemeService) { }
onClick(): void {
this.themeService.isLightTheme = !this.themeService.isLightTheme
}
}

View file

@ -1,41 +0,0 @@
<h3> Ajouter dans </h3>
<mat-divider></mat-divider><!------------------------------------------------------------------------------------------------------------->
<div class="conteneurPlaylists">
<div *ngFor="let playlist of tabPlaylistAndBool" style="margin-left: 10px">
<mat-checkbox [(ngModel)]="playlist.isSelected"> {{playlist.name}} </mat-checkbox>
</div>
</div>
<mat-divider></mat-divider><!------------------------------------------------------------------------------------------------------------->
<div class="conteneurBtnCreerPlaylist" *ngIf="!goToCreatePlaylist">
<button mat-button (click)="goToCreatePlaylist=true">
<mat-label>Creer une playlist</mat-label>
<mat-icon>add</mat-icon>
</button>
</div>
<div class="conteneurInputNewPlaylist" *ngIf="goToCreatePlaylist">
<mat-form-field>
<mat-label> Nom playlist </mat-label>
<input matInput type="text" [(ngModel)]="newPlaylistName">
</mat-form-field>
<button mat-icon-button (click)="goToCreatePlaylist=false">
<mat-icon>close</mat-icon>
</button>
</div>
<mat-divider></mat-divider><!------------------------------------------------------------------------------------------------------------->
<mat-dialog-actions style="justify-content: flex-end;">
<button mat-button mat-dialog-close (click)="onAnnuler()">Annuler</button>
<button mat-button [mat-dialog-close]="true" cdkFocusInitial (click)="onValider()">Valider</button>
</mat-dialog-actions>

View file

@ -1,19 +0,0 @@
h3 {
text-align: center;
margin-bottom: 10px
}
.conteneurPlaylists {
margin-top: 10px;
margin-bottom: 10px;
}
.conteneurBtnCreerPlaylist {
margin-top: 10px;
margin-bottom: 10px;
}
.conteneurInputNewPlaylist {
margin-top: 10px;
margin-bottom: 10px;
}

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupAddVideoToPlaylistsComponent } from './popup-add-video-to-playlists.component';
describe('PopupAddVideoToPlaylistsComponent', () => {
let component: PopupAddVideoToPlaylistsComponent;
let fixture: ComponentFixture<PopupAddVideoToPlaylistsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupAddVideoToPlaylistsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupAddVideoToPlaylistsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,67 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {Video} from "../../interfaces/video";
import {MessageService} from "../../services/message/message.service";
@Component({
selector: 'app-popup-add-video-to-playlists',
templateUrl: './popup-add-video-to-playlists.component.html',
styleUrls: ['./popup-add-video-to-playlists.component.scss']
})
export class PopupAddVideoToPlaylistsComponent implements OnInit
{
video: Video;
tabPlaylistAndBool = [];
goToCreatePlaylist = false;
newPlaylistName = "";
constructor( public dialogRef: MatDialogRef<PopupAddVideoToPlaylistsComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService) { }
ngOnInit(): void
{
this.video = this.data.video;
for(let playlist of this.data.playlists)
{
playlist["isSelected"] = false;
this.tabPlaylistAndBool.push(playlist);
}
}
onValider(): void
{
const tabPlaylist = [];
for(let playlist of this.tabPlaylistAndBool)
{
if(playlist.isSelected) {
delete playlist["isSelected"];
tabPlaylist.push(playlist);
}
}
// --- FAUX CODE ---
this.dialogRef.close("success");
// --- VRAI CODE ---
/*
if(!this.goToCreatePlaylist) this.newPlaylistName = "";
const data = { "video": this.video, "playlists": tabPlaylist, "newPlaylistName": this.newPlaylistName };
this.messageService
.sendMessage("user/add/vidéo", data)
.subscribe( retour => { this.dialogRef.close(retour.status) });
*/
}
onAnnuler(): void
{
this.dialogRef.close("annulation")
}
}

View file

@ -1,16 +0,0 @@
<div style="text-align: center; margin: 0px; padding: 0px">
<div style="margin: 0px; padding: 0px">
<mat-form-field appearance="fill" style="margin: 0px; padding: 0px">
<mat-label> Nom de la playlist </mat-label>
<input matInput [(ngModel)]="name" style="width: 100%">
</mat-form-field>
<span *ngIf="hasError" class="mat-error"> {{errorMessage}} </span>
</div>
<div style="text-align: right ; margin: 0px; padding: 0px">
<button mat-button (click)="onAnnuler()">Annuler</button>
<button mat-button (click)="onValider()">Creer</button>
</div>
</div>

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PopupCreatePlaylistComponent } from './popup-create-playlist.component';
describe('PopupCreatePlaylistComponent', () => {
let component: PopupCreatePlaylistComponent;
let fixture: ComponentFixture<PopupCreatePlaylistComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PopupCreatePlaylistComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PopupCreatePlaylistComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -1,92 +0,0 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {MessageService} from "../../services/message/message.service";
import {Playlist} from "../../interfaces/playlist";
@Component({
selector: 'app-popup-create-playlist',
templateUrl: './popup-create-playlist.component.html',
styleUrls: ['./popup-create-playlist.component.scss']
})
export class PopupCreatePlaylistComponent implements OnInit
{
name: string = "" ;
hasError: boolean = false;
tabNomPlaylist: string[] = [];
errorMessage: string = "" ;
constructor( public dialogRef: MatDialogRef<PopupCreatePlaylistComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private messageService: MessageService) { }
ngOnInit(): void
{
this.tabNomPlaylist = this.data.map( playlist0 => playlist0.name );
}
onValider(): void
{
// --- FAUX CODE ---
//
this.checkError();
if(!this.hasError)
{
const playlist: Playlist = {
_id: "monId",
user: null,
name: this.name,
videos: [],
};
this.dialogRef.close(playlist);
}
// --- VRAI CODE ---
/*
this.checkError();
if(!this.hasError)
{
this.messageService
.sendMessage("user/create/playlist", {name: this.data.name})
.subscribe(retour => {
if (retour.status === "error") {
console.log(retour);
this.dialogRef.close(null);
} else {
this.dialogRef.close(retour.data.playlist);
}
});
}
*/
}
checkError(): void
{
if(this.name === "") {
this.errorMessage = "Le nom ne peut pas être vide" ;
this.hasError = true;
}
else if(this.tabNomPlaylist.includes(this.name)){
this.errorMessage = "Ce nom est déjà utilisé" ;
this.hasError = true;
}
else {
this.hasError = false;
this.errorMessage = "" ;
}
console.log("em:" + this.errorMessage);
}
onAnnuler(): void
{
this.dialogRef.close(null);
}
}

View file

@ -1,8 +0,0 @@
import { IframeTrackerDirective } from './iframe-tracker.directive';
describe('IframeTrackerDirective', () => {
it('should create an instance', () => {
const directive = new IframeTrackerDirective();
expect(directive).toBeTruthy();
});
});

Some files were not shown because too many files have changed in this diff Show more