diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-10-03 19:36:03 +0200 | 
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-11 18:14:41 +0100 | 
| commit | 0e60743d140aff66eca6df712f653ee20f5d4ef3 (patch) | |
| tree | e72bc8bf2314a26ba3c8e27e571d72e203bbf0c8 /src | |
| parent | a3fb0aa94717aafae897ac293488c43a099c0b2b (diff) | |
refactor(components): rewrite SocialLink component
* replace default label with a label prop
* rename name prop to icon prop
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/atoms/links/social-link.test.tsx | 19 | ||||
| -rw-r--r-- | src/components/atoms/links/social-link.tsx | 51 | ||||
| -rw-r--r-- | src/components/atoms/links/social-link/index.ts | 1 | ||||
| -rw-r--r-- | src/components/atoms/links/social-link/social-link.module.scss (renamed from src/components/atoms/links/social-link.module.scss) | 15 | ||||
| -rw-r--r-- | src/components/atoms/links/social-link/social-link.stories.tsx (renamed from src/components/atoms/links/social-link.stories.tsx) | 27 | ||||
| -rw-r--r-- | src/components/atoms/links/social-link/social-link.test.tsx | 62 | ||||
| -rw-r--r-- | src/components/atoms/links/social-link/social-link.tsx | 65 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media.stories.tsx | 8 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media.test.tsx | 12 | ||||
| -rw-r--r-- | src/components/organisms/widgets/social-media.tsx | 10 | ||||
| -rw-r--r-- | src/i18n/en.json | 32 | ||||
| -rw-r--r-- | src/i18n/fr.json | 32 | ||||
| -rw-r--r-- | src/pages/contact.tsx | 33 | ||||
| -rw-r--r-- | src/pages/cv.tsx | 34 | ||||
| -rw-r--r-- | src/pages/projets/[slug].tsx | 37 | 
15 files changed, 312 insertions, 126 deletions
| diff --git a/src/components/atoms/links/social-link.test.tsx b/src/components/atoms/links/social-link.test.tsx deleted file mode 100644 index d2609ca..0000000 --- a/src/components/atoms/links/social-link.test.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../tests/utils'; -import { SocialLink } from './social-link'; - -/** - * Next.js mock images to use next/image component. So for now, I need to mock - * the svg files manually. - */ -jest.mock('@assets/images/social-media/github.svg', () => 'svg-file'); -jest.mock('@assets/images/social-media/gitlab.svg', () => 'svg-file'); -jest.mock('@assets/images/social-media/linkedin.svg', () => 'svg-file'); -jest.mock('@assets/images/social-media/twitter.svg', () => 'svg-file'); - -describe('SocialLink', () => { -  it('render a social link', () => { -    render(<SocialLink name="Github" url="#" />); -    expect(screen.getByRole('link')).toHaveAccessibleName('Github'); -  }); -}); diff --git a/src/components/atoms/links/social-link.tsx b/src/components/atoms/links/social-link.tsx deleted file mode 100644 index 9f8feb6..0000000 --- a/src/components/atoms/links/social-link.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { FC } from 'react'; -import GithubIcon from '../../../assets/images/social-media/github.svg'; -import GitlabIcon from '../../../assets/images/social-media/gitlab.svg'; -import LinkedInIcon from '../../../assets/images/social-media/linkedin.svg'; -import TwitterIcon from '../../../assets/images/social-media/twitter.svg'; -import styles from './social-link.module.scss'; - -export type SocialWebsite = 'Github' | 'Gitlab' | 'LinkedIn' | 'Twitter'; - -export type SocialLinkProps = { -  /** -   * The social website name. -   */ -  name: SocialWebsite; -  /** -   * The social profile url. -   */ -  url: string; -}; - -/** - * SocialLink component - * - * Render a social icon link. - */ -export const SocialLink: FC<SocialLinkProps> = ({ name, url }) => { -  /** -   * Retrieve a social link icon by id. -   * @param {string} id - The social website id. -   */ -  const getIcon = (id: string) => { -    switch (id) { -      case 'Github': -        return <GithubIcon className={styles.icon} aria-hidden="true" />; -      case 'Gitlab': -        return <GitlabIcon className={styles.icon} aria-hidden="true" />; -      case 'LinkedIn': -        return <LinkedInIcon className={styles.icon} aria-hidden="true" />; -      case 'Twitter': -        return <TwitterIcon className={styles.icon} aria-hidden="true" />; -      default: -        break; -    } -  }; - -  return ( -    <a aria-label={name} className={styles.link} href={url}> -      {getIcon(name)} -    </a> -  ); -}; diff --git a/src/components/atoms/links/social-link/index.ts b/src/components/atoms/links/social-link/index.ts new file mode 100644 index 0000000..9ac1b3b --- /dev/null +++ b/src/components/atoms/links/social-link/index.ts @@ -0,0 +1 @@ +export * from './social-link'; diff --git a/src/components/atoms/links/social-link.module.scss b/src/components/atoms/links/social-link/social-link.module.scss index 57dcf42..1aeab91 100644 --- a/src/components/atoms/links/social-link.module.scss +++ b/src/components/atoms/links/social-link/social-link.module.scss @@ -1,11 +1,11 @@ -@use "../../../styles/abstracts/functions" as fun; +@use "../../../../styles/abstracts/functions" as fun;  .link {    display: flex;    width: var(--link-size, #{fun.convert-px(60)});    height: var(--link-size, #{fun.convert-px(60)}); -  box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) -      var(--color-shadow), +  box-shadow: +    fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) var(--color-shadow),      fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-1)        var(--color-shadow),      fun.convert-px(3) fun.convert-px(4) fun.convert-px(4) fun.convert-px(-3) @@ -15,8 +15,8 @@    &:hover,    &:focus { -    box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) -        var(--color-shadow), +    box-shadow: +      fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) var(--color-shadow),        fun.convert-px(1) fun.convert-px(1) fun.convert-px(2) fun.convert-px(-1)          var(--color-shadow-light),        fun.convert-px(3) fun.convert-px(3) fun.convert-px(4) fun.convert-px(-4) @@ -36,8 +36,3 @@      transform: scale(0.9);    }  } - -.icon { -  max-width: 100%; -  max-height: 100%; -} diff --git a/src/components/atoms/links/social-link.stories.tsx b/src/components/atoms/links/social-link/social-link.stories.tsx index b627e9f..cfb4ac7 100644 --- a/src/components/atoms/links/social-link.stories.tsx +++ b/src/components/atoms/links/social-link/social-link.stories.tsx @@ -1,24 +1,13 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { ComponentMeta, ComponentStory } from '@storybook/react';  import { SocialLink } from './social-link';  /**   * SocialLink - Storybook Meta   */  export default { -  title: 'Atoms/Buttons/Social', +  title: 'Atoms/Links/Social',    component: SocialLink,    argTypes: { -    name: { -      control: { -        type: 'select', -      }, -      description: 'Social website name.', -      options: ['Github', 'Gitlab', 'LinkedIn', 'Twitter'], -      type: { -        name: 'string', -        required: true, -      }, -    },      url: {        control: {          type: null, @@ -41,7 +30,8 @@ const Template: ComponentStory<typeof SocialLink> = (args) => (   */  export const Github = Template.bind({});  Github.args = { -  name: 'Github', +  icon: 'Github', +  label: 'Github profile',    url: '#',  }; @@ -50,7 +40,8 @@ Github.args = {   */  export const Gitlab = Template.bind({});  Gitlab.args = { -  name: 'Gitlab', +  icon: 'Gitlab', +  label: 'Gitlab profile',    url: '#',  }; @@ -59,7 +50,8 @@ Gitlab.args = {   */  export const LinkedIn = Template.bind({});  LinkedIn.args = { -  name: 'LinkedIn', +  icon: 'LinkedIn', +  label: 'LinkedIn profile',    url: '#',  }; @@ -68,6 +60,7 @@ LinkedIn.args = {   */  export const Twitter = Template.bind({});  Twitter.args = { -  name: 'Twitter', +  icon: 'Twitter', +  label: 'Twitter profile',    url: '#',  }; diff --git a/src/components/atoms/links/social-link/social-link.test.tsx b/src/components/atoms/links/social-link/social-link.test.tsx new file mode 100644 index 0000000..9129c27 --- /dev/null +++ b/src/components/atoms/links/social-link/social-link.test.tsx @@ -0,0 +1,62 @@ +import { describe, expect, it } from '@jest/globals'; +import { render, screen as rtlScreen } from '@testing-library/react'; +import { SocialLink } from './social-link'; + +/** + * Next.js mock images to use next/image component. So for now, I need to mock + * the svg files manually. + */ +jest.mock('@assets/images/social-media/github.svg', () => 'svg-file'); +jest.mock('@assets/images/social-media/gitlab.svg', () => 'svg-file'); +jest.mock('@assets/images/social-media/linkedin.svg', () => 'svg-file'); +jest.mock('@assets/images/social-media/twitter.svg', () => 'svg-file'); + +describe('SocialLink', () => { +  it('render a Github social link', () => { +    const label = 'sed ea impedit'; +    const target = '/voluptas'; + +    render(<SocialLink icon="Github" label={label} url={target} />); + +    expect(rtlScreen.getByRole('link', { name: label })).toHaveAttribute( +      'href', +      target +    ); +  }); + +  it('render a Gitlab social link', () => { +    const label = 'rerum velit asperiores'; +    const target = '/enim'; + +    render(<SocialLink icon="Gitlab" label={label} url={target} />); + +    expect(rtlScreen.getByRole('link', { name: label })).toHaveAttribute( +      'href', +      target +    ); +  }); + +  it('render a LinkedIn social link', () => { +    const label = 'in dolores sed'; +    const target = '/ut'; + +    render(<SocialLink icon="LinkedIn" label={label} url={target} />); + +    expect(rtlScreen.getByRole('link', { name: label })).toHaveAttribute( +      'href', +      target +    ); +  }); + +  it('render a Twitter social link', () => { +    const label = 'voluptatibus temporibus expedita'; +    const target = '/magni'; + +    render(<SocialLink icon="Twitter" label={label} url={target} />); + +    expect(rtlScreen.getByRole('link', { name: label })).toHaveAttribute( +      'href', +      target +    ); +  }); +}); diff --git a/src/components/atoms/links/social-link/social-link.tsx b/src/components/atoms/links/social-link/social-link.tsx new file mode 100644 index 0000000..1da1e7d --- /dev/null +++ b/src/components/atoms/links/social-link/social-link.tsx @@ -0,0 +1,65 @@ +import type { AnchorHTMLAttributes, FC } from 'react'; +import GithubIcon from '../../../../assets/images/social-media/github.svg'; +import GitlabIcon from '../../../../assets/images/social-media/gitlab.svg'; +import LinkedInIcon from '../../../../assets/images/social-media/linkedin.svg'; +import TwitterIcon from '../../../../assets/images/social-media/twitter.svg'; +import styles from './social-link.module.scss'; + +export type SocialWebsite = 'Github' | 'Gitlab' | 'LinkedIn' | 'Twitter'; + +export type SocialLinkProps = Omit< +  AnchorHTMLAttributes<HTMLAnchorElement>, +  'aria-label' | 'children' | 'href' +> & { +  /** +   * The social link icon. +   */ +  icon: SocialWebsite; +  /** +   * An accessible label for the link. +   */ +  label: string; +  /** +   * The social profile url. +   */ +  url: string; +}; + +/** + * SocialLink component + * + * Render a social icon link. + */ +export const SocialLink: FC<SocialLinkProps> = ({ +  className = '', +  icon, +  label, +  url, +  ...props +}) => { +  const linkClass = `${styles.link} ${className}`; + +  /** +   * Retrieve a social link icon by id. +   * @param {string} id - The social website id. +   */ +  const getIcon = (id: string) => { +    switch (id) { +      case 'Github': +        return <GithubIcon aria-hidden className={styles.icon} />; +      case 'Gitlab': +        return <GitlabIcon aria-hidden className={styles.icon} />; +      case 'LinkedIn': +        return <LinkedInIcon aria-hidden className={styles.icon} />; +      case 'Twitter': +      default: +        return <TwitterIcon aria-hidden className={styles.icon} />; +    } +  }; + +  return ( +    <a {...props} aria-label={label} className={linkClass} href={url}> +      {getIcon(icon)} +    </a> +  ); +}; diff --git a/src/components/organisms/widgets/social-media.stories.tsx b/src/components/organisms/widgets/social-media.stories.tsx index f012554..6da3f3a 100644 --- a/src/components/organisms/widgets/social-media.stories.tsx +++ b/src/components/organisms/widgets/social-media.stories.tsx @@ -1,5 +1,5 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { SocialMedia as SocialMediaWidget, Media } from './social-media'; +import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import { SocialMedia as SocialMediaWidget, type Media } from './social-media';  /**   * SocialMedia - Storybook Meta @@ -46,8 +46,8 @@ const Template: ComponentStory<typeof SocialMediaWidget> = (args) => (  );  const media: Media[] = [ -  { name: 'Github', url: '#' }, -  { name: 'LinkedIn', url: '#' }, +  { icon: 'Github', id: 'github', label: 'Github', url: '#' }, +  { icon: 'LinkedIn', id: 'gitlab', label: 'Gitlab', url: '#' },  ];  /** diff --git a/src/components/organisms/widgets/social-media.test.tsx b/src/components/organisms/widgets/social-media.test.tsx index c0786ad..2cd3afb 100644 --- a/src/components/organisms/widgets/social-media.test.tsx +++ b/src/components/organisms/widgets/social-media.test.tsx @@ -1,10 +1,10 @@  import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../tests/utils'; -import { SocialMedia, Media } from './social-media'; +import { render, screen as rtlScreen } from '../../../../tests/utils'; +import { SocialMedia, type Media } from './social-media';  const media: Media[] = [ -  { name: 'Github', url: '#' }, -  { name: 'LinkedIn', url: '#' }, +  { icon: 'Github', id: 'github', label: 'Github', url: '#' }, +  { icon: 'LinkedIn', id: 'gitlab', label: 'Gitlab', url: '#' },  ];  const title = 'Dolores ut ut';  const titleLevel = 2; @@ -22,7 +22,7 @@ describe('SocialMedia', () => {    it('renders the widget title', () => {      render(<SocialMedia media={media} title={title} level={titleLevel} />);      expect( -      screen.getByRole('heading', { +      rtlScreen.getByRole('heading', {          level: titleLevel,          name: new RegExp(title, 'i'),        }) @@ -31,6 +31,6 @@ describe('SocialMedia', () => {    it('renders the correct number of items', () => {      render(<SocialMedia media={media} title={title} level={titleLevel} />); -    expect(screen.getAllByRole('listitem')).toHaveLength(media.length); +    expect(rtlScreen.getAllByRole('listitem')).toHaveLength(media.length);    });  }); diff --git a/src/components/organisms/widgets/social-media.tsx b/src/components/organisms/widgets/social-media.tsx index f9dea58..ddeb09c 100644 --- a/src/components/organisms/widgets/social-media.tsx +++ b/src/components/organisms/widgets/social-media.tsx @@ -3,7 +3,9 @@ import { List, ListItem, SocialLink, type SocialLinkProps } from '../../atoms';  import { Widget, type WidgetProps } from '../../molecules';  import styles from './social-media.module.scss'; -export type Media = SocialLinkProps; +export type Media = Required< +  Pick<SocialLinkProps, 'icon' | 'id' | 'label' | 'url'> +>;  export type SocialMediaProps = Pick<WidgetProps, 'level' | 'title'> & {    media: Media[]; @@ -22,9 +24,9 @@ export const SocialMedia: FC<SocialMediaProps> = ({ media, ...props }) => {     * @returns {JSX.Element[]} The social links.     */    const getItems = (links: Media[]): JSX.Element[] => -    links.map((link, index) => ( -      <ListItem key={`media-${index}`}> -        <SocialLink name={link.name} url={link.url} /> +    links.map(({ id, ...link }) => ( +      <ListItem key={id}> +        <SocialLink {...link} />        </ListItem>      )); diff --git a/src/i18n/en.json b/src/i18n/en.json index 640fbdc..e50be99 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -1,4 +1,8 @@  { +  "++U2Hm": { +    "defaultMessage": "Gitlab profile", +    "description": "CVPage: Gitlab profile link" +  },    "+Dre5J": {      "defaultMessage": "Open-source projects",      "description": "CVPage: social media widget title" @@ -43,6 +47,10 @@      "defaultMessage": "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.",      "description": "BlogPage: SEO - Meta description"    }, +  "1V3CJf": { +    "defaultMessage": "Gitlab profile", +    "description": "ContactPage: Gitlab profile link" +  },    "1dCuCx": {      "defaultMessage": "Name:",      "description": "ContactForm: name label" @@ -111,6 +119,10 @@      "defaultMessage": "This comment is awaiting moderation...",      "description": "Comment: awaiting moderation"    }, +  "75FYp7": { +    "defaultMessage": "Github profile", +    "description": "ContactPage: Github profile link" +  },    "7AnwZ7": {      "defaultMessage": "Gitlab",      "description": "HomePage: Gitlab link" @@ -235,6 +247,10 @@      "defaultMessage": "Submitting...",      "description": "CommentForm: spinner message on submit"    }, +  "Jm0a6H": { +    "defaultMessage": "Github profile", +    "description": "CVPage: Github profile link" +  },    "JpC3JH": {      "defaultMessage": "Other topics",      "description": "TopicPage: other topics list widget title" @@ -275,6 +291,10 @@      "defaultMessage": "Share on Twitter",      "description": "Sharing: Twitter sharing link"    }, +  "Nx8Jo5": { +    "defaultMessage": "Github profile", +    "description": "ProjectsPage: Github profile link" +  },    "OF5cPz": {      "defaultMessage": "{postsCount, plural, =0 {No articles} one {# article} other {# articles}}",      "description": "BlogPage: posts count meta" @@ -299,6 +319,10 @@      "defaultMessage": "Table of contents sidebar",      "description": "PageLayout: accessible name for ToC sidebar"    }, +  "Q3oEQn": { +    "defaultMessage": "LinkedIn profile", +    "description": "ContactPage: LinkedIn profile link" +  },    "QCW3cy": {      "defaultMessage": "Open settings",      "description": "Settings: Open label" @@ -327,6 +351,10 @@      "defaultMessage": "Loading the repository popularity...",      "description": "ProjectsPage: loading repository popularity"    }, +  "Sm2wCk": { +    "defaultMessage": "LinkedIn profile", +    "description": "CVPage: LinkedIn profile link" +  },    "T4YA64": {      "defaultMessage": "Subscribe",      "description": "HomePage: RSS feed subscription text" @@ -583,6 +611,10 @@      "defaultMessage": "No comments.",      "description": "PageLayout: no comments text"    }, +  "sECHDg": { +    "defaultMessage": "Gitlab profile", +    "description": "ProjectsPage: Gitlab profile link" +  },    "sI7gJK": {      "defaultMessage": "{starsCount, plural, =0 {No stars on Github} one {# star on Github} other {# stars on Github}}",      "description": "ProjectsPage: Github stars count" diff --git a/src/i18n/fr.json b/src/i18n/fr.json index ebdc3ad..4e10be0 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -1,4 +1,8 @@  { +  "++U2Hm": { +    "defaultMessage": "Profil Gitlab", +    "description": "CVPage: Gitlab profile link" +  },    "+Dre5J": {      "defaultMessage": "Projets open-source",      "description": "CVPage: social media widget title" @@ -43,6 +47,10 @@      "defaultMessage": "Découvrez les articles d’{websiteName}. Il écrit à propos de développement web, de Linux et du libre essentiellement.",      "description": "BlogPage: SEO - Meta description"    }, +  "1V3CJf": { +    "defaultMessage": "Profil Gitlab", +    "description": "ContactPage: Gitlab profile link" +  },    "1dCuCx": {      "defaultMessage": "Nom :",      "description": "ContactForm: name label" @@ -111,6 +119,10 @@      "defaultMessage": "Ce commentaire est en attente de modération…",      "description": "Comment: awaiting moderation"    }, +  "75FYp7": { +    "defaultMessage": "Profil Github", +    "description": "ContactPage: Github profile link" +  },    "7AnwZ7": {      "defaultMessage": "Gitlab",      "description": "HomePage: Gitlab link" @@ -235,6 +247,10 @@      "defaultMessage": "En cours d’envoi…",      "description": "CommentForm: spinner message on submit"    }, +  "Jm0a6H": { +    "defaultMessage": "Profil Github", +    "description": "CVPage: Github profile link" +  },    "JpC3JH": {      "defaultMessage": "Autres sujets",      "description": "TopicPage: other topics list widget title" @@ -275,6 +291,10 @@      "defaultMessage": "Partager sur Twitter",      "description": "Sharing: Twitter sharing link"    }, +  "Nx8Jo5": { +    "defaultMessage": "Profil Github", +    "description": "ProjectsPage: Github profile link" +  },    "OF5cPz": {      "defaultMessage": "{postsCount, plural, =0 {0 article} one {# article} other {# articles}}",      "description": "BlogPage: posts count meta" @@ -299,6 +319,10 @@      "defaultMessage": "Barre latérale de la table des matières",      "description": "PageLayout: accessible name for ToC sidebar"    }, +  "Q3oEQn": { +    "defaultMessage": "Profil LinkedIn", +    "description": "ContactPage: LinkedIn profile link" +  },    "QCW3cy": {      "defaultMessage": "Ouvrir les réglages",      "description": "Settings: Open label" @@ -327,6 +351,10 @@      "defaultMessage": "Chargement de la popularité du dépôt…",      "description": "ProjectsPage: loading repository popularity"    }, +  "Sm2wCk": { +    "defaultMessage": "Profil LinkedIn", +    "description": "CVPage: LinkedIn profile link" +  },    "T4YA64": {      "defaultMessage": "Vous abonner",      "description": "HomePage: RSS feed subscription text" @@ -583,6 +611,10 @@      "defaultMessage": "Aucun commentaire.",      "description": "PageLayout: no comments text"    }, +  "sECHDg": { +    "defaultMessage": "Profil Gitlab", +    "description": "ProjectsPage: Gitlab profile link" +  },    "sI7gJK": {      "defaultMessage": "{starsCount, plural, =0 {0 étoile sur Github} one {# étoile sur Github} other {# étoiles sur Github}}",      "description": "ProjectsPage: Github stars count" diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index 679896c..519bcac 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -65,6 +65,21 @@ const ContactPage: NextPageWithLayout = () => {      title,    });    const schemaJsonLd = getSchemaJson([webpageSchema, contactSchema]); +  const githubLabel = intl.formatMessage({ +    defaultMessage: 'Github profile', +    description: 'ContactPage: Github profile link', +    id: '75FYp7', +  }); +  const gitlabLabel = intl.formatMessage({ +    defaultMessage: 'Gitlab profile', +    description: 'ContactPage: Gitlab profile link', +    id: '1V3CJf', +  }); +  const linkedinLabel = intl.formatMessage({ +    defaultMessage: 'LinkedIn profile', +    description: 'ContactPage: LinkedIn profile link', +    id: 'Q3oEQn', +  });    const widgets = [      <SocialMedia @@ -73,10 +88,22 @@ const ContactPage: NextPageWithLayout = () => {        title={socialMediaTitle}        level={2}        media={[ -        { name: 'Github', url: 'https://github.com/ArmandPhilippot' }, -        { name: 'Gitlab', url: 'https://gitlab.com/ArmandPhilippot' },          { -          name: 'LinkedIn', +          icon: 'Github', +          id: 'github', +          label: githubLabel, +          url: 'https://github.com/ArmandPhilippot', +        }, +        { +          icon: 'Gitlab', +          id: 'gitlab', +          label: gitlabLabel, +          url: 'https://gitlab.com/ArmandPhilippot', +        }, +        { +          icon: 'LinkedIn', +          id: 'linkedin', +          label: linkedinLabel,            url: 'https://www.linkedin.com/in/armandphilippot',          },        ]} diff --git a/src/pages/cv.tsx b/src/pages/cv.tsx index b23c7a2..84a1bb9 100644 --- a/src/pages/cv.tsx +++ b/src/pages/cv.tsx @@ -179,6 +179,22 @@ const CVPage: NextPageWithLayout = () => {      }    ); +  const githubLabel = intl.formatMessage({ +    defaultMessage: 'Github profile', +    description: 'CVPage: Github profile link', +    id: 'Jm0a6H', +  }); +  const gitlabLabel = intl.formatMessage({ +    defaultMessage: 'Gitlab profile', +    description: 'CVPage: Gitlab profile link', +    id: '++U2Hm', +  }); +  const linkedinLabel = intl.formatMessage({ +    defaultMessage: 'LinkedIn profile', +    description: 'CVPage: LinkedIn profile link', +    id: 'Sm2wCk', +  }); +    const widgets = [      <ImageWidget        // eslint-disable-next-line react/jsx-no-literals -- Key allowed @@ -196,10 +212,22 @@ const CVPage: NextPageWithLayout = () => {        title={socialMediaTitle}        level={2}        media={[ -        { name: 'Github', url: PERSONAL_LINKS.GITHUB }, -        { name: 'Gitlab', url: PERSONAL_LINKS.GITLAB },          { -          name: 'LinkedIn', +          icon: 'Github', +          id: 'github', +          label: githubLabel, +          url: PERSONAL_LINKS.GITHUB, +        }, +        { +          icon: 'Gitlab', +          id: 'gitlab', +          label: gitlabLabel, +          url: PERSONAL_LINKS.GITLAB, +        }, +        { +          icon: 'LinkedIn', +          id: 'linkedin', +          label: linkedinLabel,            url: PERSONAL_LINKS.LINKEDIN,          },        ]} diff --git a/src/pages/projets/[slug].tsx b/src/pages/projets/[slug].tsx index 89891b3..ee86c7b 100644 --- a/src/pages/projets/[slug].tsx +++ b/src/pages/projets/[slug].tsx @@ -19,7 +19,6 @@ import {    type ResponsiveImageProps,    Sharing,    SocialLink, -  type SocialWebsite,    Spinner,    type MetaData,    Heading, @@ -30,7 +29,6 @@ import styles from '../../styles/pages/project.module.scss';  import type { NextPageWithLayout, ProjectPreview, Repos } from '../../types';  import { ROUTES } from '../../utils/constants';  import { -  capitalize,    getSchemaJson,    getSinglePageSchema,    getWebPageSchema, @@ -182,13 +180,34 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {     */    const getReposLinks = (repositories: Repos): JSX.Element[] => {      const links = []; - -    for (const [name, url] of Object.entries(repositories)) { -      const socialWebsite = capitalize(name) as SocialWebsite; -      const socialUrl = `https://${name}.com/${url}`; - -      links.push(<SocialLink name={socialWebsite} url={socialUrl} />); -    } +    const githubLabel = intl.formatMessage({ +      defaultMessage: 'Github profile', +      description: 'ProjectsPage: Github profile link', +      id: 'Nx8Jo5', +    }); +    const gitlabLabel = intl.formatMessage({ +      defaultMessage: 'Gitlab profile', +      description: 'ProjectsPage: Gitlab profile link', +      id: 'sECHDg', +    }); + +    if (repositories.github) +      links.push( +        <SocialLink +          icon="Github" +          label={githubLabel} +          url={repositories.github} +        /> +      ); + +    if (repositories.gitlab) +      links.push( +        <SocialLink +          icon="Gitlab" +          label={gitlabLabel} +          url={repositories.gitlab} +        /> +      );      return links;    }; | 
