✨ Website : ShortLinks

This commit is contained in:
divlo committed 2020-08-03 20:56:01 +02:00
1 parent eba7858caf
commit cc899a020a
2 files changed
+439 -1

No files matched your search

+1 -1
View File
@@ -19,7 +19,7 @@ INSERT INTO `functions` (`id`, `title`, `slug`, `description`, `image`, `type`,
(9, 'Conversion d\'un nombre arabe en nombre romain', 'convertRomanArabicNumbers', 'Convertis un nombre arabe en nombre romain (et l\'inverse aussi).', '/images/functions/convertRomanArabicNumbers.png', 'form', '<p>Nous allons créer 2 fonctions, une qui convertis un nombre arabe en nombre romain et l\"autre qui fera dans l\"inverse.</p><p>Pour cela nous avons besoin d\"une variables de référence, qu\"on utilisera dans les deux fonctions :</p><div class=\"vscode-editor\" style=\"color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, \'Courier New\', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;\"><div><span style=\"color: #569cd6;\">const</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #51b6c4;\">correspondancesRomainArabe</span><span style=\"color: #d4d4d4;\">&nbsp;=&nbsp;[</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">1000</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"M\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">900</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"CM\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">500</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"D\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">400</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"CD\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">100</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"C\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">90</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"XC\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">50</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"L\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">40</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"XL\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">10</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"X\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">9</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"IX\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">5</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"V\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">4</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"IV\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style=\"color: #b5cea8;\">1</span><span style=\"color: #d4d4d4;\">,&nbsp;</span><span style=\"color: #ce9178;\">\"I\"</span><span style=\"color: #d4d4d4;\">],</span></div><div><span style=\"color: #d4d4d4;\">];</span></div></div><p>- Commençons par la fonction qui convertis un nombre arabe en nombre romain :</p><div class=\"vscode-editor\" style=\"color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, \'Courier New\', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;\"><div><span style=\"color: #6a9955;\">/**&nbsp;</span></div><div><span style=\"color: #6a9955;\">&nbsp;*&nbsp;</span><span style=\"color: #569cd6;\">@description</span><span style=\"color: #6a9955;\">&nbsp;Convertis&nbsp;un&nbsp;nombre&nbsp;arabe&nbsp;en&nbsp;nombre&nbsp;romain.</span></div><div><span style=\"color: #6a9955;\">&nbsp;*&nbsp;</span><span style=\"color: #569cd6;\">@param</span><span style=\"color: #6a9955;\">&nbsp;</span><span style=\"color: #4ec9b0;\">{number}</span><span style=\"color: #6a9955;\">&nbsp;</span><span style=\"color: #9cdcfe;\">nombLine truncated
(10, 'Nombre d\'Armstrong', 'armstrongNumber', 'Permet de savoir si un nombre fait partie des nombres d\'Armstrong.', '/images/functions/armstrongNumber.png', 'form', '<p>Un nombre d\"Armstrong est un nombre entier positif qui est égal à la somme de ses chiffres portés à la puissance du nombre de chiffres le composant. Cette fonction permet de savoir si un nombre fait partie des nombres d\"Armstrong (avec l\"explication).<br>\n<br>\n\n\n\nExemple : 153 est un nombre d\"Armstrong&nbsp;car 1<sup>3</sup>&nbsp;+ 5<sup>3</sup>&nbsp;+ 3<sup>3</sup>&nbsp;= 153.</p><div class=\"vscode-editor\" style=\"color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, \'Courier New\', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;\"><div><span style=\"color: #6a9955;\">/**&nbsp;</span></div><div><span style=\"color: #6a9955;\">&nbsp;*&nbsp;</span><span style=\"color: #569cd6;\">@description</span><span style=\"color: #6a9955;\">&nbsp;Vérifie&nbsp;si&nbsp;un&nbsp;nombre&nbsp;fait&nbsp;partie&nbsp;des&nbsp;nombres&nbsp;d\'Armstrong.</span></div><div><span style=\"color: #6a9955;\">&nbsp;*&nbsp;</span><span style=\"color: #569cd6;\">@param</span><span style=\"color: #6a9955;\">&nbsp;</span><span style=\"color: #4ec9b0;\">{number}</span><span style=\"color: #6a9955;\">&nbsp;</span><span style=\"color: #9cdcfe;\">number</span><span style=\"color: #6a9955;\">&nbsp;-&nbsp;Le&nbsp;nombre&nbsp;à&nbsp;tester</span></div><div><span style=\"color: #6a9955;\">&nbsp;*&nbsp;</span><span style=\"color: #569cd6;\">@return</span><span style=\"color: #6a9955;\">&nbsp;</span><span style=\"color: #4ec9b0;\">{boolean}</span><span style=\"color: #6a9955;\">&nbsp;</span></div><div><span style=\"color: #6a9955;\">&nbsp;*&nbsp;</span><span style=\"color: #569cd6;\">@example</span><span style=\"color: #6a9955;\">&nbsp;isArmstrongNumber(153)&nbsp;→&nbsp;true</span></div><div><span style=\"color: #6a9955;\">&nbsp;*/</span><span style=\"color: #d4d4d4;\">&nbsp;</span></div><div><span style=\"color: #569cd6;\">function</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #dcdcaa;\">isArmstrongNumber</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #9cdcfe;\">number</span><span style=\"color: #d4d4d4;\">)&nbsp;{</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #569cd6;\">let</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #9cdcfe;\">numberString</span><span style=\"color: #d4d4d4;\">&nbsp;=&nbsp;</span><span style=\"color: #9cdcfe;\">number</span><span style=\"color: #d4d4d4;\">.</span><span style=\"color: #dcdcaa;\">toString</span><span style=\"color: #d4d4d4;\">();</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #569cd6;\">let</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #9cdcfe;\">result</span><span style=\"color: #d4d4d4;\">&nbsp;=&nbsp;</span><span style=\"color: #b5cea8;\">0</span><span style=\"color: #d4d4d4;\">;</span></div><br><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #c586c0;\">for</span><span style=\"color: #d4d4d4;\">&nbsp;(</span><span style=\"color: #569cd6;\">let</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #9cdcfe;\">index</span><span style=\"color: #d4d4d4;\">&nbsp;=&nbsp;</span><span style=\"color: #b5cea8;\">0</span><span style=\"color: #d4d4d4;\">;&nbsp;</span><span style=\"color: #9cdcfe;\">index</span><span style=\"color: #d4d4d4;\">&nbsp;&lt;&nbsp;</span><span style=\"color: #9cdcfe;\">numberString</span><span style=\"color: #d4d4d4;\">.</span><span style=\"color: #9cdcfe;\">length</span><span style=\"color: #d4d4d4;\">;&nbsp;</span><span style=\"color: #9cdcfe;\">index</span><span style=\"color: #d4d4d4;\">++)&nbsp;{</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #9cdcfe;\">result</span><span style=\"color: #d4d4d4;\">&nbsp;+=&nbsp;</span><span style=\"color: #dcdcaa;\">parseInt</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #9cdcfe;\">numberString</span><span style=\"color: #d4d4d4;\">[</span><span style=\"color: #9cdcfe;\">index</span><span style=\"color: #d4d4d4;\">])&nbsp;**&nbsp;</span><span style=\"color: #9cdcfe;\">numberString</span><span style=\"color: #d4d4d4;\">.</span><span style=\"color: #9cdcfe;\">length</span><span style=\"color: #d4d4d4;\">;</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div><br><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #c586c0;\">return</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #9cdcfe;\">result</span><span style=\"color: #d4d4d4;\">&nbsp;===&nbsp;</span><span style=\"color: #9cdcfe;\">number</span><span style=\"color: #d4d4d4;\">;&nbsp;</span></div><div><span style=\"color: #d4d4dLine truncated
(11, 'Heap\'s algorithm', 'heapAlgorithm', 'Génère toutes les permutations uniques possibles d\'une chaîne de caractère.', '/images/functions/heapAlgorithm.png', 'form', NULL, '[{\"name\": \"string\", \"type\": \"text\", \"label\": \"Entrez un mot :\", \"placeholder\": \"(e.g : Mot)\"}]', 1, '2019-10-11 00:01:00', '2020-04-22 23:06:15', 2),
(12, 'Raccourcisseurs de liens', 'linkShortener', 'Une URL trop longue ? Raccourcissez-là !', '/images/functions/linkShortener.png', 'form', '<p>Pour faire son propre \"link shortener\" comme Bitly etc. Il faut une simple base de donnée (J\'utilise MySQL), avec 3 champs : id, url et shortcut. Le principe c\'est que vous avez une url prédéfinie (grâce à Express et NodeJS c\'est très simple), qui peut ressembler à ça : nomdedomaine.fr/?q=shortcut et à la place de \"shortcut\" c\'est le shortcut enregistré dans la base de donnée pour accéder à l\'url raccourci, donc l\'algo va se contenter de chercher dans sa base de donnée si le shortcut existe si oui il va prendre le champ url et faire un simple redirect. Pour que l\'algo fonctionne correctement, il faudrait que le shortcut soit unique.</p>', '[{\"name\": \"url\", \"type\": \"text\", \"label\": \"Entrez le lien à raccourcir :\", \"placeholder\": \"(e.g : https://divlo.fr)\"}, {\"name\": \"shortcutName\", \"type\": \"text\", \"label\": \"Entrez le nom du raccourci :\", \"placeholder\": \"(e.g : divlo)\"}]', 1, '2019-12-11 00:00:00', '2020-05-12 07:49:46', 1),
(12, 'Raccourcisseurs de liens', 'linkShortener', 'Une URL trop longue ? Raccourcissez-là !', '/images/functions/linkShortener.png', 'page', '<p>Pour faire son propre \"link shortener\" comme Bitly etc. Il faut une simple base de donnée (J\'utilise MySQL), avec 3 champs : id, url et shortcut. Le principe c\'est que vous avez une url prédéfinie (grâce à Express et NodeJS c\'est très simple), qui peut ressembler à ça : nomdedomaine.fr/?q=shortcut et à la place de \"shortcut\" c\'est le shortcut enregistré dans la base de donnée pour accéder à l\'url raccourci, donc l\'algo va se contenter de chercher dans sa base de donnée si le shortcut existe si oui il va prendre le champ url et faire un simple redirect. Pour que l\'algo fonctionne correctement, il faudrait que le shortcut soit unique.</p>', '[{\"name\": \"url\", \"type\": \"text\", \"label\": \"Entrez le lien à raccourcir :\", \"placeholder\": \"(e.g : https://divlo.fr)\"}, {\"name\": \"shortcutName\", \"type\": \"text\", \"label\": \"Entrez le nom du raccourci :\", \"placeholder\": \"(e.g : divlo)\"}]', 1, '2019-12-11 00:00:00', '2020-05-12 07:49:46', 1),
(13, 'Liste de choses à faire', 'toDoList', 'Prévoyez la liste de choses que vous devez faire.', '/images/functions/toDoList.png', 'page', '<p>La To do list c\'est l\'applications que tout les débutants font en programmation, c\'est le meilleur moyen de mettre en pratique les connaissances pour faire des applications CRUD (Create. Read. Update. Delete). Surtout qu\'avec un peu d\'imagination c\'est une app qui peut-être très grandement amélioré. Pour sauvegarder vos données vous pouvez utilisez le localStorage du navigateur ou encore mieux (ce que j\'utilise ici), un système de connexion/inscription des utilisateurs et sauvegarde des données en base de donnée (MySQL par exemple). Ici, l\'utilisateur peut ajouter une tâche à faire, voir les tâches ajoutées précédemment, déclarer comme fait et supprimer. Libre à vous d\'ajouter des fonctionnalités comme par exemple la possibilté de modifier une tâche ou encore de séparer les tâches faîtes des tâches en cours. Si vous apprennez le développement web, c\'est la 1ère application \"fullstack\" que vous pouvez faire simplement : HTML, CSS, JS et un langage côté serveur (PHP ou NodeJS par exemple).</p>', NULL, 1, '2019-12-26 00:00:00', '2020-05-12 10:49:48', 1),
(14, 'Juste Prix', 'rightPrice', 'Arriverez-vous à deviner le prix d\'un objet ?', '/images/functions/rightPrice.png', 'page', '<p>Faire un juste prix ce n\"est pas très compliqué, ça se résume en 3 conditions if, pour vérifier si le prix est inférieur/supérieur ou égale, donc très simple mais pour rendre le jeu un peu plus fun surtout à développer. J\"ai imaginé de prendre un produit d\"Amazon au hasard, d\"afficher le titre et l\"image et de faire deviner le prix du produit. Problème : Amazon ne possède pas d\"API (avec documentation etc.), donc pas moyen de récupérer les 3 informations que je veux d\"un produit.&nbsp;</p><p>Donc pas le choix, on va faire ce qu\"on appelle du \"Web scraping\", c\"est à dire qu\"on va faire un script qui va aller sur la page Amazon et on va prendre tout le HTML de la page, le stocké dans une variable et faire un DOM virtuel pour pouvoir accéder aux mêmes fonctions/méthodes en JavaScript comme le document.getElementById, document.querySelector etc. et donc pouvoir récupérer les valeurs voulues.</p><p>Pour cela j\"utilise NodeJS avec la librairie <a target=\"blank\" rel=\"noopener noreferrer\" href=\"https://github.com/segmentio/nightmare\">Nightmare</a>&nbsp;qui permet justement de faire du Web Scraping.<br>\n\nDonc l\"idée c\"est que nous allons faire une fonction qui va nous retourner un Tableau de produits d\"Amazon avec chaque produit c\"est un objet contenant comme information : le nom, l\"image et le prix.\n</p><div class=\"vscode-editor\" style=\"color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, \'Courier New\', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;\"><div><span style=\"color: #569cd6;\">async</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #569cd6;\">function</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #dcdcaa;\">getAmazonProductList</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #9cdcfe;\">subject</span><span style=\"color: #d4d4d4;\">)&nbsp;{</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #569cd6;\">const</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #51b6c4;\">url</span><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;</span><span style=\"color: #ce9178;\">`https://www.amazon.fr/s?k=</span><span style=\"color: #569cd6;\">${</span><span style=\"color: #9cdcfe;\">subject</span><span style=\"color: #569cd6;\">}</span><span style=\"color: #ce9178;\">`</span><span style=\"color: #d4d4d4;\">;</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #569cd6;\">const</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #51b6c4;\">Nightmare</span><span style=\"color: #d4d4d4;\">&nbsp;=&nbsp;</span><span style=\"color: #dcdcaa;\">require</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #ce9178;\">\"nightmare\"</span><span style=\"color: #d4d4d4;\">)();</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #c586c0;\">return</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #c586c0;\">await</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #9cdcfe;\">Nightmare</span><span style=\"color: #d4d4d4;\">.</span><span style=\"color: #dcdcaa;\">goto</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #9cdcfe;\">url</span><span style=\"color: #d4d4d4;\">)</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style=\"color: #dcdcaa;\">wait</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #ce9178;\">\".s-result-item\"</span><span style=\"color: #d4d4d4;\">)</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style=\"color: #dcdcaa;\">evaluate</span><span style=\"color: #d4d4d4;\">(()&nbsp;</span><span style=\"color: #569cd6;\">=&gt;</span><span style=\"color: #d4d4d4;\">&nbsp;{</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #569cd6;\">const</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #51b6c4;\">amazonProductList</span><span style=\"color: #d4d4d4;\">&nbsp;=&nbsp;</span><span style=\"color: #9cdcfe;\">document</span><span style=\"color: #d4d4d4;\">.</span><span style=\"color: #dcdcaa;\">querySelectorAll</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #ce9178;\">\".s-result-item\"</span><span style=\"color: #d4d4d4;\">);</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #569cd6;\">const</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #51b6c4;\Line truncated
(15, 'Chronomètre', 'chronometerTimer', 'Gérer votre temps facilement (et adopter la technique Pomodoro).', '/images/functions/chronometerTimer.png', 'page', '<p>Pour faire un chronomètre il faut utiliser la fonction globale setInterval, qui va exécuter une callback toutes les x nombres de millisecondes. Nous dans notre cas, chaque seconde on va incrémenter la variable de 1 pour connaître les secondes.</p><div class=\"vscode-editor\" style=\"color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, \'Courier New\', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;\"><div><span style=\"color: #569cd6;\">let</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #9cdcfe;\">timeLength</span><span style=\"color: #d4d4d4;\">&nbsp;=&nbsp;</span><span style=\"color: #b5cea8;\">0</span><span style=\"color: #d4d4d4;\">;</span></div><div><span style=\"color: #dcdcaa;\">setInterval</span><span style=\"color: #d4d4d4;\">(()&nbsp;</span><span style=\"color: #569cd6;\">=&gt;</span><span style=\"color: #d4d4d4;\">&nbsp;{</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #9cdcfe;\">timeLength</span><span style=\"color: #d4d4d4;\">++;</span></div><div><span style=\"color: #d4d4d4;\">},&nbsp;</span><span style=\"color: #b5cea8;\">1000</span><span style=\"color: #d4d4d4;\">);</span></div></div><p>Puis pour afficher le nombre de minutes on va créer une fonction convertSeconds :</p><div class=\"vscode-editor\" style=\"color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, \'Courier New\', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;\"><div><span style=\"color: #569cd6;\">function</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #dcdcaa;\">convertSeconds</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #9cdcfe;\">seconds</span><span style=\"color: #d4d4d4;\">)&nbsp;{</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #c586c0;\">return</span><span style=\"color: #d4d4d4;\">&nbsp;{</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #9cdcfe;\">minutes:</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #4ec9b0;\">Math</span><span style=\"color: #d4d4d4;\">.</span><span style=\"color: #dcdcaa;\">floor</span><span style=\"color: #d4d4d4;\">(</span><span style=\"color: #9cdcfe;\">seconds</span><span style=\"color: #d4d4d4;\">&nbsp;/&nbsp;</span><span style=\"color: #b5cea8;\">60</span><span style=\"color: #d4d4d4;\">),</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style=\"color: #9cdcfe;\">seconds:</span><span style=\"color: #d4d4d4;\">&nbsp;</span><span style=\"color: #9cdcfe;\">seconds</span><span style=\"color: #d4d4d4;\">&nbsp;%&nbsp;</span><span style=\"color: #b5cea8;\">60</span><span style=\"color: #d4d4d4;\">&nbsp;</span></div><div><span style=\"color: #d4d4d4;\">&nbsp;&nbsp;&nbsp;&nbsp;};</span></div><div><span style=\"color: #d4d4d4;\">}</span></div></div><p>Exemple : On exécute la fonction convertSeconds(90) qui va nous retourner l\'objet où minutes vaudra 1 et seconds vaudra 30,&nbsp;</p><p>Et globalement le reste c\'est de la manipulation du DOM en JavaScript.</p>', NULL, 1, '2020-04-29 09:28:08', '2020-05-12 13:11:48', 1);
+438
View File
@@ -0,0 +1,438 @@
import { useState, useEffect, useContext, useRef, useCallback } from 'react'
import Link from 'next/link'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPen, faTrash, faTimes } from '@fortawesome/free-solid-svg-icons'
import { UserContext } from '../../contexts/UserContext'
import redirect from '../../utils/redirect'
import htmlParser from 'html-react-parser'
import Loader from '../../components/Loader'
import FunctionPage from '../../components/FunctionPage/FunctionPage'
import FunctionTabs from '../../components/FunctionPage/FunctionTabs'
import FunctionArticle from '../../components/FunctionPage/FunctionArticle'
import FunctionComments from '../../components/FunctionPage/FunctionComments/FunctionComments'
import Modal from '../../components/Modal'
import api from '../../utils/api'
import 'notyf/notyf.min.css'
import '../../public/css/pages/FunctionComponent.css'
import '../../public/css/pages/admin.css'
const CreateLink = () => {
const { isAuth, user } = useContext(UserContext)
const [inputState, setInputState] = useState({})
const [message, setMessage] = useState('')
const [isLoading, setIsLoading] = useState(false)
const handleSubmit = async event => {
setIsLoading(true)
event.preventDefault()
try {
const response = await api.post('/links', inputState, {
headers: { Authorization: user.token }
})
setMessage(response.data.resultHTML)
setIsLoading(false)
setInputState({ url: '', shortcutName: '' })
} catch (error) {
setIsLoading(false)
setMessage(error.response.data.message)
}
}
const handleChange = event => {
const inputStateNew = { ...inputState }
inputStateNew[event.target.name] = event.target.value
setInputState(inputStateNew)
}
if (!isAuth) {
return (
<p className='text-center'>
Vous devez être{' '}
<Link href='/users/login'>
<a>connecté</a>
</Link>{' '}
pour gérer des liens raccourcis.
</p>
)
}
return (
<div className='container-fluid'>
<div className='row'>
<div className='col-24'>
<form onSubmit={handleSubmit}>
<div className='form-group'>
<label className='form-label' htmlFor='url'>
Entrez le lien à raccourcir :
</label>
<input
onChange={handleChange}
type='text'
name='url'
id='url'
placeholder='(e.g : https://divlo.fr)'
className='form-control'
/>
</div>
<div className='form-group'>
<label className='form-label' htmlFor='shortcutName'>
Entrez le nom du raccourci :
</label>
<input
onChange={handleChange}
type='text'
name='shortcutName'
id='shortcutName'
placeholder='(e.g : divlo)'
className='form-control'
/>
</div>
<div className='form-group text-center'>
<button type='submit' className='btn btn-dark'>
Envoyer
</button>
</div>
</form>
</div>
</div>
<div className='form-result text-center'>
{isLoading ? <Loader /> : htmlParser(message)}
</div>
</div>
)
}
let pageLinks = 1
const LinksList = () => {
const { isAuth, user } = useContext(UserContext)
const [linksData, setLinksData] = useState({
hasMore: true,
rows: [],
totalItems: 0
})
const [isLoadingLinks, setLoadingLinks] = useState(true)
const [isEditing, setIsEditing] = useState(false)
const [defaultInputState, setDefaultInputState] = useState({
shortcutName: '',
url: '',
id: 1
})
const [message, setMessage] = useState('')
const [isLoading, setIsLoading] = useState(false)
const toggleModal = () => {
if (isEditing) {
setIsLoading(false)
setMessage('')
setDefaultInputState({ shortcutName: '', url: '', id: 1 })
}
setIsEditing(!isEditing)
}
// Récupère les liens initiales
useEffect(() => {
getLinksData().then(data => setLinksData(data))
}, [])
const handleChange = event => {
const inputStateNew = { ...defaultInputState }
inputStateNew[event.target.name] = event.target.value
setDefaultInputState(inputStateNew)
}
const handleRemoveLink = async linkId => {
try {
await api.delete(`/links/${linkId}`, {
headers: { Authorization: user.token }
})
const linksDataState = { ...linksData }
const deletedLinkIndex = linksData.rows.findIndex(link => {
return link.id === linkId
})
linksDataState.rows.splice(deletedLinkIndex, 1)
setLinksData(linksDataState)
let Notyf
if (typeof window !== 'undefined') {
Notyf = require('notyf')
}
const notyf = new Notyf.Notyf({
duration: 5000
})
notyf.success('Succès: lien raccourci supprimé!')
} catch {}
}
const handleEditLink = linkInfo => {
toggleModal()
setDefaultInputState({
shortcutName: linkInfo.shortcut,
url: linkInfo.url,
id: linkInfo.id
})
}
const handleEditSubmit = async event => {
setIsLoading(true)
event.preventDefault()
try {
const response = await api.put(
`/links/${defaultInputState.id}`,
defaultInputState,
{
headers: { Authorization: user.token }
}
)
const linksDataState = { ...linksData }
const editedLinkIndex = linksData.rows.findIndex(link => {
return link.id === defaultInputState.id
})
if (editedLinkIndex != null) {
linksDataState.rows[editedLinkIndex].shortcut =
defaultInputState.shortcutName
linksDataState.rows[editedLinkIndex].url = defaultInputState.url
setLinksData(linksDataState)
}
setMessage(response.data.resultHTML)
setIsLoading(false)
} catch (error) {
setIsLoading(false)
setMessage(error.response.data.message)
}
}
const getLinksData = async () => {
setLoadingLinks(true)
const { data } = await api.get(`/links?page=${pageLinks}&limit=20`, {
headers: { Authorization: user.token }
})
setLoadingLinks(false)
return data
}
// Permet la pagination au scroll
const observer = useRef()
const lastLinkRef = useCallback(
node => {
if (isLoadingLinks) return
if (observer.current) observer.current.disconnect()
observer.current = new window.IntersectionObserver(
entries => {
if (entries[0].isIntersecting && linksData.hasMore) {
pageLinks += 1
getLinksData().then(data => {
setLinksData(oldData => {
return {
hasMore: data.hasMore,
rows: [...oldData.rows, ...data.rows],
totalItems: data.totalItems
}
})
})
}
},
{ threshold: 1 }
)
if (node) observer.current.observe(node)
},
[isLoadingLinks, linksData.hasMore]
)
if (!isAuth) {
return (
<p className='text-center'>
Vous devez être{' '}
<Link href='/users/login'>
<a>connecté</a>
</Link>{' '}
pour gérer des liens raccourcis.
</p>
)
}
return (
<div className='container-fluid text-center'>
<div className='row justify-content-center'>
<div className='col-24'>
<h1>Gérer les liens</h1>
</div>
</div>
<div className='row justify-content-center'>
<div className='container-fluid'>
{!isEditing ? (
<div className='col-24 table-column'>
<table className='table' style={{ marginBottom: '40px' }}>
<thead>
<tr>
<th className='table-row' scope='col'>
Liens
</th>
<th className='table-row' scope='col'>
Nom
</th>
<th className='table-row' scope='col'>
Modifier
</th>
<th className='table-row' scope='col'>
Supprimer
</th>
</tr>
</thead>
<tbody>
{linksData.rows.map((link, index) => {
const linkJSX = (
<>
<td className='table-row'>
<a href={link.url}>{link.url}</a>
</td>
<td className='table-row'>{link.shortcut}</td>
<td
style={{ cursor: 'pointer' }}
onClick={() => handleEditLink(link)}
>
<FontAwesomeIcon
icon={faPen}
style={{ width: '1.5rem' }}
/>
</td>
<td
style={{ cursor: 'pointer' }}
onClick={() => handleRemoveLink(link.id)}
>
<FontAwesomeIcon
icon={faTrash}
style={{ width: '1.5rem' }}
/>
</td>
</>
)
// Si c'est le dernier élément
if (linksData.rows.length === index + 1) {
return (
<tr key={index} ref={lastLinkRef}>
{linkJSX}
</tr>
)
}
return <tr key={index}>{linkJSX}</tr>
})}
</tbody>
</table>
</div>
) : (
<Modal>
<div className='Admin__Modal__container container-fluid'>
<div className='Admin__Modal__row row'>
<div className='col-24'>
<div className='Admin__Modal-top-container row'>
<div className='col-24'>
<span
onClick={toggleModal}
style={{
cursor: 'pointer',
position: 'absolute',
left: 0
}}
>
<FontAwesomeIcon
icon={faTimes}
style={{ width: '1.5rem', color: 'red' }}
/>
</span>
</div>
</div>
</div>
<div className='col-24'>
<form onSubmit={handleEditSubmit}>
<div className='form-group'>
<label className='form-label' htmlFor='url'>
Entrez le lien à raccourcir :
</label>
<input
value={defaultInputState.url}
onChange={handleChange}
type='text'
name='url'
id='url'
placeholder='(e.g : https://divlo.fr)'
className='form-control'
/>
</div>
<div className='form-group'>
<label className='form-label' htmlFor='shortcutName'>
Entrez le nom du raccourci :
</label>
<input
value={defaultInputState.shortcutName}
onChange={handleChange}
type='text'
name='shortcutName'
id='shortcutName'
placeholder='(e.g : divlo)'
className='form-control'
/>
</div>
<div className='form-group text-center'>
<button type='submit' className='btn btn-dark'>
Envoyer
</button>
</div>
</form>
<div className='form-result text-center'>
{isLoading ? <Loader /> : htmlParser(message)}
</div>
</div>
</div>
</div>
</Modal>
)}
</div>
</div>
</div>
)
}
const FunctionTabManager = props => {
return (
<FunctionTabs
setSlideIndex={props.setSlideIndex}
slideIndex={props.slideIndex}
>
<div className='FunctionComponent__slide'>
<CreateLink />
</div>
<div className='FunctionComponent__slide'>
<LinksList />
</div>
<div className='FunctionComponent__slide'>
<FunctionArticle article={props.article} />
</div>
<div className='FunctionComponent__slide'>
<FunctionComments functionId={props.id} />
</div>
</FunctionTabs>
)
}
const linkShortener = props => (
<FunctionPage
FunctionTabManager={FunctionTabManager}
{...props}
tabNames={['⚙️ Utilisation', '📜 Liste', '📝 Article', '📬 Commentaires']}
/>
)
export async function getServerSideProps (context) {
return api
.get('/functions/linkShortener')
.then(response => ({ props: response.data }))
.catch(() => redirect(context, '/404'))
}
export default linkShortener