diff --git a/frontend/.pnp.cjs b/frontend/.pnp.cjs index ed7d15b43..cd7303598 100755 --- a/frontend/.pnp.cjs +++ b/frontend/.pnp.cjs @@ -58,7 +58,6 @@ const RAW_RUNTIME_STATE = ["file-saver", "npm:2.0.5"],\ ["happy-dom", "npm:15.10.2"],\ ["history", "npm:5.3.0"],\ - ["next-share", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:0.27.0"],\ ["prop-types", "npm:15.8.1"],\ ["qs", "npm:6.11.2"],\ ["react", "npm:18.3.1"],\ @@ -68,6 +67,7 @@ const RAW_RUNTIME_STATE = ["react-router", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:6.25.1"],\ ["react-router-dom", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:6.25.1"],\ ["react-select", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:5.7.4"],\ + ["react-share", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:5.1.1"],\ ["react-transition-group", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:4.4.5"],\ ["sass", "npm:1.69.5"],\ ["storybook", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:8.4.2"],\ @@ -6672,7 +6672,6 @@ const RAW_RUNTIME_STATE = ["file-saver", "npm:2.0.5"],\ ["happy-dom", "npm:15.10.2"],\ ["history", "npm:5.3.0"],\ - ["next-share", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:0.27.0"],\ ["prop-types", "npm:15.8.1"],\ ["qs", "npm:6.11.2"],\ ["react", "npm:18.3.1"],\ @@ -6682,6 +6681,7 @@ const RAW_RUNTIME_STATE = ["react-router", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:6.25.1"],\ ["react-router-dom", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:6.25.1"],\ ["react-select", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:5.7.4"],\ + ["react-share", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:5.1.1"],\ ["react-transition-group", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:4.4.5"],\ ["sass", "npm:1.69.5"],\ ["storybook", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:8.4.2"],\ @@ -7392,6 +7392,13 @@ const RAW_RUNTIME_STATE = ["classnames", "npm:2.3.2"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:2.5.1", {\ + "packageLocation": "../../../.yarn/berry/cache/classnames-npm-2.5.1-c7273f3423-10c0.zip/node_modules/classnames/",\ + "packageDependencies": [\ + ["classnames", "npm:2.5.1"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["clean-stack", [\ @@ -10427,29 +10434,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["next-share", [\ - ["npm:0.27.0", {\ - "packageLocation": "../../../.yarn/berry/cache/next-share-npm-0.27.0-d99b540b06-10c0.zip/node_modules/next-share/",\ - "packageDependencies": [\ - ["next-share", "npm:0.27.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:0.27.0", {\ - "packageLocation": "./.yarn/__virtual__/next-share-virtual-d999f4e289/4/.yarn/berry/cache/next-share-npm-0.27.0-d99b540b06-10c0.zip/node_modules/next-share/",\ - "packageDependencies": [\ - ["next-share", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:0.27.0"],\ - ["@types/react", "npm:18.3.3"],\ - ["jsonp", "npm:0.2.1"],\ - ["react", "npm:18.3.1"]\ - ],\ - "packagePeers": [\ - "@types/react",\ - "react"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["node-gyp", [\ ["npm:10.0.1", {\ "packageLocation": "./.yarn/unplugged/node-gyp-npm-10.0.1-48708ce70b/node_modules/node-gyp/",\ @@ -11230,6 +11214,30 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["react-share", [\ + ["npm:5.1.1", {\ + "packageLocation": "../../../.yarn/berry/cache/react-share-npm-5.1.1-e8817154ac-10c0.zip/node_modules/react-share/",\ + "packageDependencies": [\ + ["react-share", "npm:5.1.1"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:5.1.1", {\ + "packageLocation": "./.yarn/__virtual__/react-share-virtual-d8e080ab99/4/.yarn/berry/cache/react-share-npm-5.1.1-e8817154ac-10c0.zip/node_modules/react-share/",\ + "packageDependencies": [\ + ["react-share", "virtual:74792effab46f58ba1849ed2d34bd613b5659d762979dea959819ade1937f6e3f71378429c07ee0ed12a2f529924b755998205bbacdbe5f616b371b307f52d67#npm:5.1.1"],\ + ["@types/react", "npm:18.3.3"],\ + ["classnames", "npm:2.5.1"],\ + ["jsonp", "npm:0.2.1"],\ + ["react", "npm:18.3.1"]\ + ],\ + "packagePeers": [\ + "@types/react",\ + "react"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["react-side-effect", [\ ["npm:2.1.2", {\ "packageLocation": "../../../.yarn/berry/cache/react-side-effect-npm-2.1.2-c18e5fd8bd-10c0.zip/node_modules/react-side-effect/",\ diff --git a/frontend/package.json b/frontend/package.json index 3603fb001..40974fa32 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,7 +10,6 @@ "classnames": "^2.2.6", "email-validator": "^2.0.4", "file-saver": "^2.0.5", - "next-share": "^0.27.0", "qs": "^6.10.3", "react": "18.3.1", "react-dom": "18.3.1", @@ -19,6 +18,7 @@ "react-router": "^6.25.1", "react-router-dom": "^6.25.1", "react-select": "^5.4.0", + "react-share": "^5.1.1", "react-transition-group": "^4.4.5", "sass": "^1.69.5", "typescript": "^5.3.3", diff --git a/frontend/src/components/Social/Social.test.tsx b/frontend/src/components/Social/Social.test.tsx index 9e4fe3628..e93759b63 100644 --- a/frontend/src/components/Social/Social.test.tsx +++ b/frontend/src/components/Social/Social.test.tsx @@ -27,19 +27,19 @@ describe('Social Component', () => { it('renders all social media buttons when all apps are included', () => { render(); - expect(screen.getByTestId('facebook-share')).toBeDefined(); - expect(screen.getByTestId('whatsapp-share')).toBeDefined(); - expect(screen.getByTestId('twitter-share')).toBeDefined(); - expect(screen.getByTestId('weibo-share')).toBeDefined(); + expect(document.querySelector('.fa-facebook-f')).toBeDefined(); + expect(document.querySelector('.fa-whatsapp')).toBeDefined(); + expect(document.querySelector('.fa-x-twitter')).toBeDefined(); + expect(document.querySelector('.fa-weibo')).toBeDefined(); }); it('renders only specified social media buttons', () => { const limitedSocial: ISocial = { ...mockSocial, channels: ['facebook', 'twitter'] }; render(); - expect(screen.getByTestId('facebook-share')).toBeDefined(); - expect(screen.getByTestId('twitter-share')).toBeDefined(); - expect(screen.queryByTestId('whatsapp-share')).toBeNull(); - expect(screen.queryByTestId('weibo-share')).toBeNull(); + expect(document.querySelector('.fa-facebook-f')).toBeDefined(); + expect(document.querySelector('.fa-x-twitter')).toBeDefined(); + expect(document.querySelector('.fa-whatsapp')).toBeNull(); + expect(document.querySelector('.fa-weibo')).toBeNull(); }); it('renders share button when navigator.share is available', () => { diff --git a/frontend/src/components/Social/Social.tsx b/frontend/src/components/Social/Social.tsx index 0d86fdc74..31fbba7ec 100644 --- a/frontend/src/components/Social/Social.tsx +++ b/frontend/src/components/Social/Social.tsx @@ -1,7 +1,7 @@ import { useRef } from "react"; import { FacebookShareButton, TwitterShareButton, WeiboShareButton, WhatsappShareButton -} from 'next-share' +} from 'react-share' import ISocial from "@/types/Social"; export interface SocialProps { @@ -42,7 +42,6 @@ const Social = ({ social }: SocialProps) => { url={social.url} title={social.content} hashtag={social.tags[0]} - blankTarget={true} > @@ -51,7 +50,6 @@ const Social = ({ social }: SocialProps) => { @@ -61,7 +59,6 @@ const Social = ({ social }: SocialProps) => { url={social.url} title={social.content} hashtags={social.tags} - blankTarget={true} > @@ -70,7 +67,6 @@ const Social = ({ social }: SocialProps) => { diff --git a/frontend/src/stories/Social.stories.tsx b/frontend/src/stories/Social.stories.tsx new file mode 100644 index 000000000..db06b85a1 --- /dev/null +++ b/frontend/src/stories/Social.stories.tsx @@ -0,0 +1,98 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import Social from '@/components/Social/Social'; +import ISocial from '@/types/Social'; + +const meta: Meta = { + title: 'Components/Social', + component: Social, + parameters: { + layout: 'centered', + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +}; + +export default meta; +type Story = StoryObj; + +const defaultSocialProps: ISocial = { + channels: ['facebook', 'twitter', 'whatsapp', 'weibo', 'share', 'clipboard'], + url: 'https://example.com/share', + content: 'Check out this awesome content!', + tags: ['storybook', 'testing', 'react'], +}; + +export const AllChannels: Story = { + args: { + social: defaultSocialProps, + }, +}; + +export const SocialMediaOnly: Story = { + args: { + social: { + ...defaultSocialProps, + channels: ['facebook', 'twitter', 'whatsapp', 'weibo'], + }, + }, +}; + +export const MinimalChannels: Story = { + args: { + social: { + ...defaultSocialProps, + channels: ['facebook', 'twitter'], + }, + }, +}; + +export const SystemShareOnly: Story = { + args: { + social: { + ...defaultSocialProps, + channels: ['share', 'clipboard'], + }, + }, +}; + +export const CustomContent: Story = { + args: { + social: { + ...defaultSocialProps, + content: '🎉 Amazing news! Join us for this special event!', + tags: ['event', 'special', 'celebration'], + }, + }, +}; + +export const LongUrl: Story = { + args: { + social: { + ...defaultSocialProps, + url: 'https://example.com/very/long/url/with/multiple/parameters?param1=value1¶m2=value2¶m3=value3', + }, + }, +}; + +export const NoTags: Story = { + args: { + social: { + ...defaultSocialProps, + tags: [], + }, + }, +}; + +export const SingleChannel: Story = { + args: { + social: { + ...defaultSocialProps, + channels: ['facebook'], + }, + }, +}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index a25f29e1c..2db527a70 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -4363,7 +4363,6 @@ __metadata: file-saver: "npm:^2.0.5" happy-dom: "npm:^15.10.2" history: "npm:^5.3.0" - next-share: "npm:^0.27.0" prop-types: "npm:15.8.1" qs: "npm:^6.10.3" react: "npm:18.3.1" @@ -4373,6 +4372,7 @@ __metadata: react-router: "npm:^6.25.1" react-router-dom: "npm:^6.25.1" react-select: "npm:^5.4.0" + react-share: "npm:^5.1.1" react-transition-group: "npm:^4.4.5" sass: "npm:^1.69.5" storybook: "npm:^8.4.2" @@ -4978,6 +4978,13 @@ __metadata: languageName: node linkType: hard +"classnames@npm:^2.3.2": + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: 10c0/afff4f77e62cea2d79c39962980bf316bacb0d7c49e13a21adaadb9221e1c6b9d3cdb829d8bb1b23c406f4e740507f37e1dcf506f7e3b7113d17c5bab787aa69 + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -7631,17 +7638,6 @@ __metadata: languageName: node linkType: hard -"next-share@npm:^0.27.0": - version: 0.27.0 - resolution: "next-share@npm:0.27.0" - dependencies: - jsonp: "npm:^0.2.1" - peerDependencies: - react: ">=17.0.2" - checksum: 10c0/0b1e6a408f1cacf42d4f9d63c31ad52939f8838a6239e46031ea64565483f01528dde730fcccb1a607ba1061a7ff169bdfb33df5ff0d33eec4dba9cd402904e7 - languageName: node - linkType: hard - "node-gyp@npm:latest": version: 10.0.1 resolution: "node-gyp@npm:10.0.1" @@ -8224,6 +8220,18 @@ __metadata: languageName: node linkType: hard +"react-share@npm:^5.1.1": + version: 5.1.1 + resolution: "react-share@npm:5.1.1" + dependencies: + classnames: "npm:^2.3.2" + jsonp: "npm:^0.2.1" + peerDependencies: + react: ^17 || ^18 + checksum: 10c0/f2959d324d456197f29779d95333110fa1f2708ea5859bf0e02efd7ea09346bb12e2577217279162813a75542e11cfcb0159bf5c9718187018dc968efccafdb8 + languageName: node + linkType: hard + "react-side-effect@npm:^2.1.0": version: 2.1.2 resolution: "react-side-effect@npm:2.1.2"