From aee37d0d649a56c1b911549e97209c098b3fa22c Mon Sep 17 00:00:00 2001 From: Nonimart Date: Thu, 28 May 2026 17:53:23 +0200 Subject: [PATCH] FEATURE Big toolbar refactor to handle share like and cita buttons directly from carhop theme --- css/login-style.css | 38 +++- resources/js/single-revue.ts | 28 +-- resources/js/singles/cite-button.ts | 49 ------ resources/js/singles/like-button.ts | 252 --------------------------- resources/js/singles/search-revue.ts | 12 +- resources/js/singles/share-button.ts | 36 ---- resources/js/singles/singles.ts | 3 - single-articles.php | 2 +- single-revues.php | 2 +- template-tutorial.php | 58 ++++++ 10 files changed, 112 insertions(+), 368 deletions(-) delete mode 100644 resources/js/singles/cite-button.ts delete mode 100644 resources/js/singles/like-button.ts delete mode 100644 resources/js/singles/share-button.ts create mode 100644 template-tutorial.php diff --git a/css/login-style.css b/css/login-style.css index 5b57825..40e3278 100644 --- a/css/login-style.css +++ b/css/login-style.css @@ -1 +1,37 @@ -#login h1 a,.login h1 a{background-image:url(../resources/img/logo_client.svg);height:100px;width:300px;background-size:300px 100px;background-repeat:no-repeat;padding-bottom:10px}#wp-submit{--tw-border-opacity:1;border-color:rgb(19 111 99/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(19 111 99/var(--tw-bg-opacity))}#backtoblog a,#nav a{--tw-text-opacity:1;color:rgb(19 111 99/var(--tw-text-opacity))}#loginform{border:none}.wp-pwd span{--tw-text-opacity:1;color:rgb(19 111 99/var(--tw-text-opacity))} \ No newline at end of file +body { + /* @apply bg-primary; */ +} + +#login h1 a, +.login h1 a { + background-image: url("../resources/img/logo_client.svg"); + height: 100px; + width: 300px; + background-size: 300px 100px; + background-repeat: no-repeat; + padding-bottom: 10px; +} + +#wp-submit { + --tw-border-opacity: 1; + border-color: rgb(19 111 99 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(19 111 99 / var(--tw-bg-opacity)); +} + +#nav a, +#backtoblog a { + /* color: var(--red) !important; */ + --tw-text-opacity: 1; + color: rgb(19 111 99 / var(--tw-text-opacity)); +} + +#loginform { + border: none; +} + +.wp-pwd span { + --tw-text-opacity: 1; + color: rgb(19 111 99 / var(--tw-text-opacity)); + /* color: var(--red) !important; */ +} diff --git a/resources/js/single-revue.ts b/resources/js/single-revue.ts index e232cf4..30eb669 100644 --- a/resources/js/single-revue.ts +++ b/resources/js/single-revue.ts @@ -3,25 +3,22 @@ interface RevueAuthorsResponse { } export default function singleRevue(): void { - const isSingleRevue: HTMLElement | null = - document.querySelector('.page--single-revue'); + const isSingleRevue: HTMLElement | null = document.querySelector('.page--single-revue'); if (!isSingleRevue) return; hydrateRevueAuthors(); handleAuthorsButton(); } function getRevueID(): string | null { - const revueElement: HTMLElement | null = - document.querySelector('.page--single-revue'); + const revueElement: HTMLElement | null = document.querySelector('.page--single-revue'); if (!revueElement) { return null; } - return revueElement.getAttribute('data-revue-id'); + return revueElement.getAttribute('data-post-id'); } function handleAuthorsButton(): void { - const authorsButton: HTMLButtonElement | null = - document.querySelector('.authors-button'); + const authorsButton: HTMLButtonElement | null = document.querySelector('.authors-button'); if (authorsButton) { authorsButton.addEventListener('click', () => { hydrateRevueAuthors(); @@ -35,25 +32,18 @@ async function hydrateRevueAuthors(): Promise { try { const response = await fetch( - `/wp-json/dynamiques-datas/v1/build/revue/authors?revue-id=${revueID}` + `/wp-json/dynamiques-datas/v1/build/revue/authors?revue-id=${revueID}`, ); if (!response.ok) { - throw new Error( - `HTTP error! status: ${response.status}` - ); + throw new Error(`HTTP error! status: ${response.status}`); } - const revueAuthors: RevueAuthorsResponse = - await response.json(); + const revueAuthors: RevueAuthorsResponse = await response.json(); - const authorsList: HTMLElement | null = - document.querySelector('.authors-list'); + const authorsList: HTMLElement | null = document.querySelector('.authors-list'); if (authorsList) { authorsList.innerHTML = revueAuthors.html_template; } } catch (error) { - console.error( - 'Failed to fetch and hydrate revue authors:', - error - ); + console.error('Failed to fetch and hydrate revue authors:', error); } } diff --git a/resources/js/singles/cite-button.ts b/resources/js/singles/cite-button.ts deleted file mode 100644 index d2ccc22..0000000 --- a/resources/js/singles/cite-button.ts +++ /dev/null @@ -1,49 +0,0 @@ -export default function handleCiteButton(): void { - const citeButton: HTMLElement | null = document.querySelector('.socials-buttons__button--cite'); - const citeReference: HTMLElement | null = document.querySelector('#cite-reference'); - if (!citeButton || !citeReference) return; - - if (!window.isSecureContext) { - citeButton.setAttribute('disabled', 'true'); - citeButton.setAttribute( - 'title', - 'Vous devez utiliser un navigation sécurisé (https) pour copier la citation' - ); - } - - citeButton.addEventListener('click', () => { - const textToCopy = citeReference.textContent; - if (!textToCopy) return; - - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard - .writeText(textToCopy) - .then(() => { - const notyf = new Notyf({ - duration: 4000, - ripple: false, - dismissible: true, - types: [ - { - type: 'success', - icon: { - className: 'notyf__icon--success', - tagName: 'i', - }, - }, - ], - position: { - x: 'right', - y: 'top', - }, - }); - notyf.success( - 'Citation copiée dans le presse-papiers !
Vous pouvez maintenant la coller dans votre document.' - ); - }) - .catch((err) => { - console.error('Failed to copy text: ', err); - }); - } - }); -} diff --git a/resources/js/singles/like-button.ts b/resources/js/singles/like-button.ts deleted file mode 100644 index 2eaed29..0000000 --- a/resources/js/singles/like-button.ts +++ /dev/null @@ -1,252 +0,0 @@ -// ============================================================================= -// TYPE DECLARATIONS -// ============================================================================= - -declare var Notyf: any; - -// ============================================================================= -// UTILITY FUNCTIONS -// ============================================================================= - -function getPostType() { - const isSingleArticle = document.querySelector('.page--single-articles'); - const isSingleRevue = document.querySelector('.page--single-revue'); - if (isSingleArticle) { - return 'article'; - } else if (isSingleRevue) { - return 'revue'; - } - return null; -} - -function getPostId() { - const postType = getPostType(); - if (!postType) return; - const postId = - postType === 'article' - ? document.querySelector('.page--single-articles')?.getAttribute('data-article-id') - : document.querySelector('.page--single-revue')?.getAttribute('data-revue-id'); - return postId; -} - -// ============================================================================= -// LIKE TRACKING FUNCTIONS -// ============================================================================= - -/** - * Clé localStorage pour stocker les posts likés - */ -const LIKED_POSTS_KEY = 'dynamiques_liked_posts'; - -/** - * Récupère la liste des posts likés depuis localStorage - */ -function getLikedPosts(): string[] { - try { - const likedPosts = localStorage.getItem(LIKED_POSTS_KEY); - return likedPosts ? JSON.parse(likedPosts) : []; - } catch (error) { - console.error('Erreur lecture localStorage:', error); - return []; - } -} - -/** - * Ajoute un post à la liste des posts likés - */ -function addLikedPost(postId: string): void { - try { - const likedPosts = getLikedPosts(); - if (!likedPosts.includes(postId)) { - likedPosts.push(postId); - localStorage.setItem(LIKED_POSTS_KEY, JSON.stringify(likedPosts)); - } - } catch (error) { - console.error('Erreur sauvegarde localStorage:', error); - } -} - -/** - * Vérifie si un post a déjà été liké - */ -function isPostLiked(postId: string): boolean { - const likedPosts = getLikedPosts(); - return likedPosts.includes(postId); -} - -// ============================================================================= -// LIKE API FUNCTIONS -// ============================================================================= - -async function likePost(postId: string): Promise { - // Vérifier si le post a déjà été liké - if (isPostLiked(postId)) { - console.log(`Post ${postId} déjà liké !`); - showAlreadyLikedMessage(); - return false; - } - - try { - const response = await fetch(`/wp-json/dynamiques-datas/v1/build/articles/like`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - post_id: postId, - }), - }); - const data = await response.json(); - - if (data.success) { - console.log(`Post ${postId} liké ! Nouveau total: ${data.likes_count} likes`); - - // Sauvegarder le like dans localStorage - addLikedPost(postId); - - // Mettre à jour l'interface utilisateur - updateLikeDisplay(data.likes_count); - updateLikeButtonState(); - - // Afficher message de succès - showLikeSuccessMessage(data.likes_count); - - return true; - } else { - console.error('Erreur API:', data); - return false; - } - } catch (error) { - console.error('Erreur lors du like:', error); - return false; - } -} - -// ============================================================================= -// UI UPDATE FUNCTIONS -// ============================================================================= - -function updateLikeDisplay(likesCount: number) { - // Mettre à jour l'affichage du compteur de likes dans l'interface - const likeCountElement = document.querySelector('.socials-buttons .likes-count'); - const likeButton = document.querySelector('.socials-buttons__button--like'); - - if (likeCountElement && likeButton) { - likeButton.setAttribute('data-likes-count', `${likesCount}`); - likeButton.classList.add('is-disabled'); - likeCountElement.textContent = `${likesCount}`; - } -} - -function updateLikeButtonState() { - const postId = getPostId(); - const likeButton = document.querySelector('.socials-buttons__button--like'); - if (!postId || !likeButton) return; - - const hasAlreadyLiked = isPostLiked(postId); - if (hasAlreadyLiked) { - const actionText = likeButton.querySelector('.button-action-text'); - if (actionText) { - actionText.textContent = 'Déjà liké'; - } - likeButton.setAttribute('title', 'Déjà liké !'); - return; - } - - if (!hasAlreadyLiked) { - likeButton.classList.remove('is-disabled'); - } -} - -function updateLikesCountIndicator() { - const likesCountIndicator = likeButton.querySelector('.likes-count'); - const likesCount = likeButton.getAttribute('data-likes-count'); - - if (likesCount && likesCountIndicator) { - likesCountIndicator.textContent = `${parseInt(likesCount) + 1}`; - } -} - -function showAlreadyLikedMessage() { - const notyf = new Notyf({ - duration: 3000, - ripple: false, - dismissible: true, - types: [ - { - type: 'error', - background: '#ff6b6b', - icon: { - className: 'notyf__icon--error', - tagName: 'i', - // Pas de text personnalisé pour garder l'icône d'erreur par défaut - }, - }, - ], - position: { - x: 'right', - y: 'top', - }, - }); - - notyf.error(' Vous avez déjà liké ce post ! ❤️'); -} - -function showLikeSuccessMessage(likesCount: number) { - const notyf = new Notyf({ - duration: 2000, - ripple: false, - dismissible: true, - types: [ - { - type: 'success', - background: '#10B981', - icon: { - className: 'notyf__icon--success', - tagName: 'i', - text: '❤️', - }, - }, - ], - position: { - x: 'right', - y: 'top', - }, - }); - - notyf.success( - `Merci pour votre like !
Total: ${likesCount} like${likesCount > 1 ? 's' : ''}` - ); -} - -// ============================================================================= -// MAIN INITIALIZATION FUNCTION -// ============================================================================= - -export default function handleLikeButton(): void { - const likeButton: HTMLElement | null = document.querySelector( - '.socials-buttons .socials-buttons__button--like' - ); - const postType = getPostType(); - const postId = getPostId(); - if (!postType || !postId || !likeButton) return; - - updateLikeButtonState(); - - // Ajouter l'événement click - likeButton.addEventListener('click', async (e) => { - e.preventDefault(); // Empêcher comportement par défaut - - const hasAlreadyLiked = isPostLiked(postId); - if (hasAlreadyLiked) return showAlreadyLikedMessage(); - // Désactiver temporairement le bouton pour éviter les clics multiples - likeButton.style.pointerEvents = 'none'; - - const success = await likePost(postId); - - // Réactiver le bouton - setTimeout(() => { - likeButton.style.pointerEvents = 'auto'; - }, 1000); - }); -} diff --git a/resources/js/singles/search-revue.ts b/resources/js/singles/search-revue.ts index 8abfd0a..d3086d8 100644 --- a/resources/js/singles/search-revue.ts +++ b/resources/js/singles/search-revue.ts @@ -1,19 +1,19 @@ export default function handleSearchRevue() { const searchRevue = document.querySelector( - '.page--single-revue .sidebar .search-field input' + '.page--single-revue .sidebar .search-field input', ) as HTMLInputElement; const contentArea = document.querySelector('.page--single-revue .content-area') as HTMLElement; const currentRevueId = document .querySelector('.page--single-revue') - ?.getAttribute('data-revue-id') as string; + ?.getAttribute('data-post-id') as string; const revueToolbarButtons = document.querySelectorAll( - '.page--single-revue .revue-toolbar button' + '.page--single-revue .revue-toolbar button', ) as NodeListOf; if (!searchRevue || !contentArea) return; const resetSearchButton = document.querySelector( - '.page--single-revue .sidebar .search-field .reset-search-button' + '.page--single-revue .sidebar .search-field .reset-search-button', ) as HTMLButtonElement; if (!resetSearchButton) return; @@ -41,8 +41,8 @@ export default function handleSearchRevue() { try { const response = await fetch( `/wp-json/dynamiques-datas/v1/build/revues/${currentRevueId}/articles?search=${encodeURIComponent( - searchValue - )}` + searchValue, + )}`, ); const data = await response.json(); diff --git a/resources/js/singles/share-button.ts b/resources/js/singles/share-button.ts deleted file mode 100644 index cc03b61..0000000 --- a/resources/js/singles/share-button.ts +++ /dev/null @@ -1,36 +0,0 @@ -export default function handleShareButton() { - const shareButton = document.querySelector('.socials-buttons__button--share'); - if (!shareButton) return; - - shareButton.addEventListener('click', () => { - const isOpen = shareButton.classList.contains('is-open'); - if (!isOpen) { - shareButton.classList.add('is-open'); - } else { - shareButton.classList.remove('is-open'); - } - }); - handleCopyLinkButton(); -} - -function handleCopyLinkButton() { - const copyLinkButton = document.querySelector('.share-button--copy-link a'); - if (!copyLinkButton) return; - - copyLinkButton.addEventListener('click', (e) => { - e.preventDefault(); - const url = copyLinkButton.getAttribute('data-url'); - if (!url) return; - navigator.clipboard.writeText(url); - const notyf = new Notyf({ - duration: 4000, - ripple: false, - dismissible: true, - position: { - x: 'right', - y: 'top', - }, - }); - notyf.success('Lien copié !'); - }); -} diff --git a/resources/js/singles/singles.ts b/resources/js/singles/singles.ts index c33f02a..47fcdcf 100644 --- a/resources/js/singles/singles.ts +++ b/resources/js/singles/singles.ts @@ -16,11 +16,8 @@ export default function singles(): void { handleIndexPanel(); handleFootnoteFormat(); - handleCiteButton(); - handleLikeButton(); handleArticleToolbar(); handleRevueToolbar(); - handleShareButton(); handleArticleReader(); handleSearchRevue(); diff --git a/single-articles.php b/single-articles.php index fdc191f..4d08ba9 100644 --- a/single-articles.php +++ b/single-articles.php @@ -3,7 +3,7 @@ get_header(); $revueID = get_field('related_revue', get_the_ID()); ?> -
+
ID); ?> -
+
diff --git a/template-tutorial.php b/template-tutorial.php new file mode 100644 index 0000000..1d7090c --- /dev/null +++ b/template-tutorial.php @@ -0,0 +1,58 @@ + + +
+ + +
+ + +
+ + get_the_ID() + )); ?> + get_the_ID() + )); ?> + + $revueID + )); ?> + + $revueID + )); ?> + + get_the_ID() + )); ?> +
+
+ + + '); ?> + + + + + + + + + +
+ +