Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature/blog share option #3928

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions components/icons/Bluesky.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

const IconBlueSky = ({className=''}) => {
return (
<img className={className} src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg" alt="Bluesky Logo" />
)
}

export default IconBlueSky;
Comment on lines +1 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix linting and formatting issues.

There are multiple linting and formatting issues that need to be addressed:

  1. Missing semicolon after import statement
  2. Missing space after opening curly brace in props destructuring
  3. Using double quotes instead of single quotes for JSX attributes
-import React from 'react'
+import React from 'react';

-const IconBlueSky = ({className=''}) => {
+const IconBlueSky = ({ className='' }) => {
  return (
-    <img className={className} src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg" alt="Bluesky Logo" />
+    <img className={className} src='https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg' alt='Bluesky Logo' />
 )
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import React from 'react'
const IconBlueSky = ({className=''}) => {
return (
<img className={className} src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg" alt="Bluesky Logo" />
)
}
export default IconBlueSky;
import React from 'react';
const IconBlueSky = ({ className='' }) => {
return (
<img className={className} src='https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg' alt='Bluesky Logo' />
)
}
export default IconBlueSky;
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project

[error] 1-7: Prettier formatting check failed. Multiple formatting issues detected including missing semicolons and spacing errors.


[error] 1-1: ESLint: Missing semicolon. (semi)


[error] 3-3: ESLint: A space is required after '{'. (object-curly-spacing)


[error] 5-5: ESLint: Unexpected usage of doublequote. (jsx-quotes)

11 changes: 11 additions & 0 deletions components/icons/Facebook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const IconFacebook = ({ className = '' }) => {
return (
<svg className={className} fill='currentColor' viewBox='0 0 23 23'>
<path d='M16.5 3.5H13.25V7H16.5V10H13.25V19.5H9.5V10H6.5V7H9.5V4.5C9.5 2.02 11.02 0.5 13.5 0.5C14.63 0.5 15.66 0.7 16.5 0.85V3.5Z' />
</svg>
);
};

export default IconFacebook;
8 changes: 8 additions & 0 deletions components/layout/BlogLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ShareIcon } from '@heroicons/react/outline';
import moment from 'moment';
import ErrorPage from 'next/error';
import HtmlHead from 'next/head';
Expand All @@ -11,6 +12,7 @@ import AuthorAvatars from '../AuthorAvatars';
import AnnouncementHero from '../campaigns/AnnouncementHero';
import Head from '../Head';
import TOC from '../TOC';
import SharePopup from '../tools/SharePopup';
import Container from './Container';

interface IBlogLayoutProps {
Expand All @@ -30,6 +32,7 @@ export default function BlogLayout({
// eslint-disable-next-line unused-imports/no-unused-vars, no-unused-vars
navItems
}: IBlogLayoutProps) {
const [showShare, setShowShare] = React.useState(false);
const router = useRouter();

if (!post) return <ErrorPage statusCode={404} />;
Expand Down Expand Up @@ -81,7 +84,12 @@ export default function BlogLayout({
<span>{post.readingTime} min read</span>
</div>
</div>
<ShareIcon
className='ml-auto size-6 cursor-pointer text-gray-500 hover:text-gray-800'
onClick={() => setShowShare(true)}
/>
</div>
{showShare && <SharePopup closeSharePop={() => setShowShare(false)} posttitle={post.title} />}
</header>
<article className='mb-32'>
<Head title={post.title} description={post.excerpt} image={post.cover} />
Expand Down
6 changes: 3 additions & 3 deletions components/navigation/MobileNavMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export default function MobileNavMenu({
<div className='space-y-2 px-5 py-2' onClick={() => showMenu('learning')} data-testid='MobileNav-docs'>
<h4 className='flex justify-between font-medium text-gray-800'>
{' '}
<Link href='/docs' className='cursor-pointer flex'>
<Link href='/docs' className='flex cursor-pointer'>
Docs
</Link>
<NavItemDropdown />
Expand All @@ -95,7 +95,7 @@ export default function MobileNavMenu({
<div className='space-y-2 px-5 py-2' onClick={() => showMenu('tooling')} data-testid='MobileNav-tools'>
<h4 className='flex justify-between font-medium text-gray-800'>
{' '}
<Link href='/tools' className='cursor-pointer flex'>
<Link href='/tools' className='flex cursor-pointer'>
Tools
</Link>
<NavItemDropdown />
Expand All @@ -104,7 +104,7 @@ export default function MobileNavMenu({
</div>
<div className='space-y-2 px-5 py-2' onClick={() => showMenu('community')} data-testid='MobileNav-community'>
<h4 className='flex justify-between font-medium text-gray-800'>
<Link href='/community' className='cursor-pointer flex'>
<Link href='/community' className='flex cursor-pointer'>
Community
</Link>
<NavItemDropdown />
Expand Down
81 changes: 81 additions & 0 deletions components/tools/SharePopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react';

import IconLinkedIn from '../icons/LinkedIn';
import IconTwitter from '../icons/Twitter';
import IconBlueSky from '../icons/Bluesky';
Comment on lines +3 to +5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix import sorting according to linting rules.

The imports need to be sorted according to the project's linting rules.

import React from 'react';

-import IconLinkedIn from '../icons/LinkedIn';
-import IconTwitter from '../icons/Twitter';
import IconBlueSky from '../icons/Bluesky';
+import IconLinkedIn from '../icons/LinkedIn';
+import IconTwitter from '../icons/Twitter';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import IconLinkedIn from '../icons/LinkedIn';
import IconTwitter from '../icons/Twitter';
import IconBlueSky from '../icons/Bluesky';
import React from 'react';
import IconBlueSky from '../icons/Bluesky';
import IconLinkedIn from '../icons/LinkedIn';
import IconTwitter from '../icons/Twitter';


interface SharePopupProps {
closeSharePop: () => void;
posttitle: string;
}

const SharePopup = ({ closeSharePop, posttitle }: SharePopupProps) => {
const [copied, setCopied] = React.useState(false);

const handleCopyLink = () => {
const copyText = document.querySelector('input') as HTMLInputElement;

copyText.select();
navigator.clipboard.writeText(copyText.value).then(() => {
setCopied(true);
}
);
};

return (
<div className=' fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
<div className=' absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:-translate-y-[20%] md:scale-125'>
Comment on lines +26 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix Tailwind CSS arbitrary value warning.

The arbitrary value class name md:-translate-y-[20%] should not start with a dash.

-    <div className=' fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
-      <div className=' absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:-translate-y-[20%] md:scale-125'>
+    <div className='fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
+      <div className='absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:translate-y-[-20%] md:scale-125'>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className=' fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
<div className=' absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:-translate-y-[20%] md:scale-125'>
<div className='fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
<div className='absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:translate-y-[-20%] md:scale-125'>
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project

[warning] 27-27: Arbitrary value classname 'md:-translate-y-[20%]' should not start with a dash (-) (tailwindcss/enforces-negative-arbitrary-values)

<section className='flex items-center justify-between border-b border-gray-200 p-2'>
<h3 className='text-2xl font-bold'>Share</h3>
<button className='text-3xl' onClick={() => closeSharePop()}>
&#215;
</button>
</section>
<section className='p-2'>
<h4 className='text-sm'>Share this Blog link via</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<a
href={`https://twitter.com/intent/tweet?url=${window.location.href}&text=${posttitle}`}
target='_blank'
Comment on lines +38 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add URL encoding for sharing parameters.

The URL and title parameters in sharing links should be properly URL-encoded to handle special characters.

            <a
-              href={`https://twitter.com/intent/tweet?url=${window.location.href}&text=${posttitle}`}
+              href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(window.location.href)}&text=${encodeURIComponent(posttitle)}`}
              target='_blank'
              rel='noreferrer'
              className='flex items-center justify-center rounded-full border border-gray-600 p-4'
            >
              <IconTwitter className='h-6' />
            </a>
            <a
-              href={`https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}&title=${posttitle}`}
+              href={`https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(window.location.href)}&title=${encodeURIComponent(posttitle)}`}
              target='_blank'
              rel='noreferrer'
              className='flex items-center justify-center rounded-full border border-gray-600 p-4 text-blue-700'
            >
              <IconLinkedIn className='h-6' />
            </a>
            <a
-              href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
+              href={`https://bsky.app/share?url=${encodeURIComponent(window.location.href)}&title=${encodeURIComponent(posttitle)}`}
              target="_blank"
              rel="noreferrer"
              className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
            >
              <IconBlueSky className="h-6" />
            </a>

Also applies to: 46-47, 54-55

rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4'
>
<IconTwitter className='h-6' />
</a>
<a
href={`https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}&title=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4 text-blue-700'
>
<IconLinkedIn className='h-6' />
</a>
<a
href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
>
<IconBlueSky className="h-6" />
</a>
Comment on lines +53 to +60
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix quote style for Bluesky link attributes.

The project's linting rules require using single quotes instead of double quotes in JSX attributes.

            <a
              href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
-              target="_blank"
-              rel="noreferrer"
-              className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
+              target='_blank'
+              rel='noreferrer'
+              className='flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700'
            >
-              <IconBlueSky className="h-6" />
+              <IconBlueSky className='h-6' />
            </a>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<a
href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
>
<IconBlueSky className="h-6" />
</a>
<a
href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700'
>
<IconBlueSky className='h-6' />
</a>
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project

[error] 55-55: ESLint: Unexpected usage of doublequote. (jsx-quotes)


</div>
</section>
<section className='p-2'>
<h4 className='text-sm'>Copy Link</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<input type='text' value={window.location.href} className='w-3/4 rounded-lg border border-gray-600 p-2' />
<button
className='rounded-lg border bg-blue-600 p-2 text-white hover:bg-blue-500'
onClick={() => handleCopyLink()}
>
{copied ? 'copied' : 'copy'}
</button>
</div>
</section>
</div>
</div>
Comment on lines +25 to +77
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add keyboard accessibility features to the modal.

The modal is missing keyboard navigation support and proper ARIA attributes for accessibility.

Enhance the accessibility by adding:

  1. The ESC key listener to close the modal
  2. Focus trapping within the modal
  3. Proper ARIA roles and attributes

Here's how to implement the ESC key handler:

  const SharePopup = ({ closeSharePop, posttitle }: SharePopupProps) => {
    const [copied, setCopied] = React.useState(false);
+   
+   React.useEffect(() => {
+     const handleEscKey = (event: KeyboardEvent) => {
+       if (event.key === 'Escape') {
+         closeSharePop();
+       }
+     };
+     
+     document.addEventListener('keydown', handleEscKey);
+     return () => {
+       document.removeEventListener('keydown', handleEscKey);
+     };
+   }, [closeSharePop]);

    // Rest of the component

And update the modal wrapper div:

-    <div className='fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
+    <div 
+      role='dialog'
+      aria-modal='true'
+      aria-labelledby='share-dialog-title'
+      className='fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'
+    >
       <div className='absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:translate-y-[-20%] md:scale-125'>
         <section className='flex items-center  justify-between border-b border-gray-200 p-2'>
-          <h3 className='text-2xl font-bold'>Share</h3>
+          <h3 id='share-dialog-title' className='text-2xl font-bold'>Share</h3>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return (
<div className=' fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
<div className=' absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:-translate-y-[20%] md:scale-125'>
<section className='flex items-center justify-between border-b border-gray-200 p-2'>
<h3 className='text-2xl font-bold'>Share</h3>
<button className='text-3xl' onClick={() => closeSharePop()}>
&#215;
</button>
</section>
<section className='p-2'>
<h4 className='text-sm'>Share this Blog link via</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<a
href={`https://twitter.com/intent/tweet?url=${window.location.href}&text=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4'
>
<IconTwitter className='h-6' />
</a>
<a
href={`https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}&title=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4 text-blue-700'
>
<IconLinkedIn className='h-6' />
</a>
<a
href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
>
<IconBlueSky className="h-6" />
</a>
</div>
</section>
<section className='p-2'>
<h4 className='text-sm'>Copy Link</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<input type='text' value={window.location.href} className='w-3/4 rounded-lg border border-gray-600 p-2' />
<button
className='rounded-lg border bg-blue-600 p-2 text-white hover:bg-blue-500'
onClick={() => handleCopyLink()}
>
{copied ? 'copied' : 'copy'}
</button>
</div>
</section>
</div>
</div>
const SharePopup = ({ closeSharePop, posttitle }: SharePopupProps) => {
const [copied, setCopied] = React.useState(false);
React.useEffect(() => {
const handleEscKey = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
closeSharePop();
}
};
document.addEventListener('keydown', handleEscKey);
return () => {
document.removeEventListener('keydown', handleEscKey);
};
}, [closeSharePop]);
return (
<div
role='dialog'
aria-modal='true'
aria-labelledby='share-dialog-title'
className='fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'
>
<div className='absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:-translate-y-[20%] md:scale-125'>
<section className='flex items-center justify-between border-b border-gray-200 p-2'>
<h3 id='share-dialog-title' className='text-2xl font-bold'>Share</h3>
<button className='text-3xl' onClick={() => closeSharePop()}>
&#215;
</button>
</section>
<section className='p-2'>
<h4 className='text-sm'>Share this Blog link via</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<a
href={`https://twitter.com/intent/tweet?url=${window.location.href}&text=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4'
>
<IconTwitter className='h-6' />
</a>
<a
href={`https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}&title=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4 text-blue-700'
>
<IconLinkedIn className='h-6' />
</a>
<a
href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
>
<IconBlueSky className="h-6" />
</a>
</div>
</section>
<section className='p-2'>
<h4 className='text-sm'>Copy Link</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<input type='text' value={window.location.href} className='w-3/4 rounded-lg border border-gray-600 p-2' />
<button
className='rounded-lg border bg-blue-600 p-2 text-white hover:bg-blue-500'
onClick={() => handleCopyLink()}
>
{copied ? 'copied' : 'copy'}
</button>
</div>
</section>
</div>
</div>
);
};
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project

[warning] 27-27: Arbitrary value classname 'md:-translate-y-[20%]' should not start with a dash (-) (tailwindcss/enforces-negative-arbitrary-values)


[error] 55-55: ESLint: Unexpected usage of doublequote. (jsx-quotes)

);
};

export default SharePopup;
Comment on lines +1 to +81
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add server-side rendering compatibility.

The component uses window.location.href directly, which will cause issues during server-side rendering because window is not available on the server.

Use a React hook to safely access the window object only in the client:

 import React from 'react';
+import { useEffect, useState } from 'react';
 
 import IconBlueSky from '../icons/Bluesky';
 import IconLinkedIn from '../icons/LinkedIn';
 import IconTwitter from '../icons/Twitter';
 
 interface SharePopupProps {
   closeSharePop: () => void;
   posttitle: string;
 }
 
 const SharePopup = ({ closeSharePop, posttitle }: SharePopupProps) => {
   const [copied, setCopied] = React.useState(false);
+  const [currentUrl, setCurrentUrl] = useState('');
+  
+  useEffect(() => {
+    // Only access window in the client
+    setCurrentUrl(window.location.href);
+  }, []);
 
   const handleCopyLink = () => {
     // ... updated copy logic
   };
 
   return (
     // ... in the JSX:
-    <input type='text' value={window.location.href} className='w-3/4 rounded-lg border border-gray-600 p-2' />
+    <input type='text' value={currentUrl} className='w-3/4 rounded-lg border border-gray-600 p-2' />
     // ... and in the sharing links:
-    href={`https://twitter.com/intent/tweet?url=${window.location.href}&text=${posttitle}`}
+    href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(currentUrl)}&text=${encodeURIComponent(posttitle)}`}
     // ... other social links similarly updated
   );
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import React from 'react';
import IconLinkedIn from '../icons/LinkedIn';
import IconTwitter from '../icons/Twitter';
import IconBlueSky from '../icons/Bluesky';
interface SharePopupProps {
closeSharePop: () => void;
posttitle: string;
}
const SharePopup = ({ closeSharePop, posttitle }: SharePopupProps) => {
const [copied, setCopied] = React.useState(false);
const handleCopyLink = () => {
const copyText = document.querySelector('input') as HTMLInputElement;
copyText.select();
navigator.clipboard.writeText(copyText.value).then(() => {
setCopied(true);
}
);
};
return (
<div className=' fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80'>
<div className=' absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:-translate-y-[20%] md:scale-125'>
<section className='flex items-center justify-between border-b border-gray-200 p-2'>
<h3 className='text-2xl font-bold'>Share</h3>
<button className='text-3xl' onClick={() => closeSharePop()}>
&#215;
</button>
</section>
<section className='p-2'>
<h4 className='text-sm'>Share this Blog link via</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<a
href={`https://twitter.com/intent/tweet?url=${window.location.href}&text=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4'
>
<IconTwitter className='h-6' />
</a>
<a
href={`https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}&title=${posttitle}`}
target='_blank'
rel='noreferrer'
className='flex items-center justify-center rounded-full border border-gray-600 p-4 text-blue-700'
>
<IconLinkedIn className='h-6' />
</a>
<a
href={`https://bsky.app/share?url=${window.location.href}&title=${posttitle}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
>
<IconBlueSky className="h-6" />
</a>
</div>
</section>
<section className='p-2'>
<h4 className='text-sm'>Copy Link</h4>
<div className='flex items-center justify-center gap-4 p-2'>
<input type='text' value={window.location.href} className='w-3/4 rounded-lg border border-gray-600 p-2' />
<button
className='rounded-lg border bg-blue-600 p-2 text-white hover:bg-blue-500'
onClick={() => handleCopyLink()}
>
{copied ? 'copied' : 'copy'}
</button>
</div>
</section>
</div>
</div>
);
};
export default SharePopup;
import React, { useEffect, useState } from 'react';
import IconLinkedIn from '../icons/LinkedIn';
import IconTwitter from '../icons/Twitter';
import IconBlueSky from '../icons/Bluesky';
interface SharePopupProps {
closeSharePop: () => void;
posttitle: string;
}
const SharePopup = ({ closeSharePop, posttitle }: SharePopupProps) => {
const [copied, setCopied] = React.useState(false);
const [currentUrl, setCurrentUrl] = useState('');
useEffect(() => {
// Only access window in the client
setCurrentUrl(window.location.href);
}, []);
const handleCopyLink = () => {
const copyText = document.querySelector('input') as HTMLInputElement;
copyText.select();
navigator.clipboard.writeText(copyText.value).then(() => {
setCopied(true);
});
};
return (
<div className=" fixed left-0 top-0 z-50 flex size-full items-center justify-center bg-gray-800/80">
<div className=" absolute left-1/2 top-1/2 w-[300px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-2 shadow-lg md:-translate-y-[20%] md:scale-125">
<section className="flex items-center justify-between border-b border-gray-200 p-2">
<h3 className="text-2xl font-bold">Share</h3>
<button className="text-3xl" onClick={() => closeSharePop()}>
&#215;
</button>
</section>
<section className="p-2">
<h4 className="text-sm">Share this Blog link via</h4>
<div className="flex items-center justify-center gap-4 p-2">
<a
href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(
currentUrl
)}&text=${encodeURIComponent(posttitle)}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4"
>
<IconTwitter className="h-6" />
</a>
<a
href={`https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(
currentUrl
)}&title=${encodeURIComponent(posttitle)}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-blue-700"
>
<IconLinkedIn className="h-6" />
</a>
<a
href={`https://bsky.app/share?url=${encodeURIComponent(
currentUrl
)}&title=${encodeURIComponent(posttitle)}`}
target="_blank"
rel="noreferrer"
className="flex items-center justify-center rounded-full border border-gray-600 p-4 text-orange-700"
>
<IconBlueSky className="h-6" />
</a>
</div>
</section>
<section className="p-2">
<h4 className="text-sm">Copy Link</h4>
<div className="flex items-center justify-center gap-4 p-2">
<input
type="text"
value={currentUrl}
className="w-3/4 rounded-lg border border-gray-600 p-2"
/>
<button
className="rounded-lg border bg-blue-600 p-2 text-white hover:bg-blue-500"
onClick={() => handleCopyLink()}
>
{copied ? 'copied' : 'copy'}
</button>
</div>
</section>
</div>
</div>
);
};
export default SharePopup;
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project

[error] 1-1: ESLint: Run autofix to sort these imports! (simple-import-sort/imports)


[warning] 27-27: Arbitrary value classname 'md:-translate-y-[20%]' should not start with a dash (-) (tailwindcss/enforces-negative-arbitrary-values)


[error] 55-55: ESLint: Unexpected usage of doublequote. (jsx-quotes)

Loading