From 70efcfeaa0603415dd992cb662d8efb960e6e49a Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Tue, 26 Sep 2023 15:54:28 +0200
Subject: refactor(routes): replace hardcoded routes with constants

It makes it easier to change a route if needed and it avoid typo
mistakes.
I also refactored a bit the concerned files to be complient with the
new ESlint config. However, I should rewrite the pages to reduce
the number of statements.
---
 src/pages/contact.tsx | 102 +++++++++++++++++++++++++++++---------------------
 1 file changed, 60 insertions(+), 42 deletions(-)

(limited to 'src/pages/contact.tsx')

diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx
index 92c58cc..d187a93 100644
--- a/src/pages/contact.tsx
+++ b/src/pages/contact.tsx
@@ -1,8 +1,9 @@
-import { GetStaticProps } from 'next';
+/* eslint-disable max-statements */
+import type { GetStaticProps } from 'next';
 import Head from 'next/head';
 import { useRouter } from 'next/router';
 import Script from 'next/script';
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
 import { useIntl } from 'react-intl';
 import {
   ContactForm,
@@ -16,7 +17,8 @@ import {
 import { meta } from '../content/pages/contact.mdx';
 import { sendMail } from '../services/graphql';
 import styles from '../styles/pages/contact.module.scss';
-import { type NextPageWithLayout } from '../types';
+import type { NextPageWithLayout } from '../types';
+import { ROUTES } from '../utils/constants';
 import {
   getSchemaJson,
   getSinglePageSchema,
@@ -30,9 +32,14 @@ const ContactPage: NextPageWithLayout = () => {
   const intl = useIntl();
   const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({
     title,
-    url: `/contact`,
+    url: ROUTES.CONTACT,
   });
 
+  const pageTitle = intl.formatMessage({
+    defaultMessage: 'Contact',
+    description: 'ContactPage: page title',
+    id: 'AN9iy7',
+  });
   const socialMediaTitle = intl.formatMessage({
     defaultMessage: 'Find me elsewhere',
     description: 'ContactPage: social media widget title',
@@ -61,6 +68,7 @@ const ContactPage: NextPageWithLayout = () => {
 
   const widgets = [
     <SocialMedia
+      // eslint-disable-next-line react/jsx-no-literals -- Key allowed
       key="social-media"
       title={socialMediaTitle}
       level={2}
@@ -75,56 +83,66 @@ const ContactPage: NextPageWithLayout = () => {
     />,
   ];
 
-  const [status, setStatus] = useState<NoticeKind>('info');
+  const [statusKind, setStatusKind] = useState<NoticeKind>('info');
   const [statusMessage, setStatusMessage] = useState<string>('');
 
-  const submitMail: ContactFormProps['sendMail'] = async (data, reset) => {
-    const { email, message, name, object } = data;
-    const messageHTML = message.replace(/\r?\n/g, '<br />');
-    const body = `Message received from ${name} <${email}> on ${website.url}.<br /><br />${messageHTML}`;
-    const replyTo = `${name} <${email}>`;
-    const mailData = {
-      body,
-      clientMutationId: 'contact',
-      replyTo,
-      subject: object,
-    };
-    const { message: mutationMessage, sent } = await sendMail(mailData);
+  const submitMail: ContactFormProps['sendMail'] = useCallback(
+    async (data, reset) => {
+      const { email, message, name, object } = data;
+      const messageHTML = message.replace(/\r?\n/g, '<br />');
+      const body = `Message received from ${name} <${email}> on ${website.url}.<br /><br />${messageHTML}`;
+      const replyTo = `${name} <${email}>`;
+      const mailData = {
+        body,
+        clientMutationId: 'contact',
+        replyTo,
+        subject: object,
+      };
+      const { message: mutationMessage, sent } = await sendMail(mailData);
 
-    if (sent) {
-      setStatus('success');
-      setStatusMessage(
-        intl.formatMessage({
-          defaultMessage:
-            'Thanks. Your message was successfully sent. I will answer it as soon as possible.',
-          description: 'Contact: success message',
-          id: '3Pipok',
-        })
-      );
-      reset();
-    } else {
-      const errorPrefix = intl.formatMessage({
-        defaultMessage: 'An error occurred:',
-        description: 'Contact: error message',
-        id: 'TpyFZ6',
-      });
-      const error = `${errorPrefix} ${mutationMessage}`;
-      setStatus('error');
-      setStatusMessage(error);
-    }
+      if (sent) {
+        setStatusKind('success');
+        setStatusMessage(
+          intl.formatMessage({
+            defaultMessage:
+              'Thanks. Your message was successfully sent. I will answer it as soon as possible.',
+            description: 'Contact: success message',
+            id: '3Pipok',
+          })
+        );
+        reset();
+      } else {
+        const errorPrefix = intl.formatMessage({
+          defaultMessage: 'An error occurred:',
+          description: 'Contact: error message',
+          id: 'TpyFZ6',
+        });
+        const error = `${errorPrefix} ${mutationMessage}`;
+        setStatusKind('error');
+        setStatusMessage(error);
+      }
+    },
+    [intl, website.url]
+  );
+  const page = {
+    title: `${seo.title} - ${website.name}`,
+    url: `${website.url}${asPath}`,
   };
 
   return (
     <>
       <Head>
-        <title>{`${seo.title} - ${website.name}`}</title>
+        <title>{page.title}</title>
+        {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */}
         <meta name="description" content={seo.description} />
-        <meta property="og:url" content={`${website.url}${asPath}`} />
+        <meta property="og:url" content={page.url} />
+        {/*eslint-disable-next-line react/jsx-no-literals -- Content allowed */}
         <meta property="og:type" content="article" />
         <meta property="og:title" content={title} />
         <meta property="og:description" content={intro} />
       </Head>
       <Script
+        // eslint-disable-next-line react/jsx-no-literals -- Id allowed
         id="schema-contact"
         type="application/ld+json"
         dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
@@ -133,7 +151,7 @@ const ContactPage: NextPageWithLayout = () => {
         breadcrumb={breadcrumbItems}
         breadcrumbSchema={breadcrumbSchema}
         intro={intro}
-        title="Contact"
+        title={pageTitle}
         widgets={widgets}
       >
         <ContactForm
@@ -141,7 +159,7 @@ const ContactPage: NextPageWithLayout = () => {
           Notice={
             statusMessage ? (
               <Notice
-                kind={status}
+                kind={statusKind}
                 message={statusMessage}
                 className={styles.notice}
               />
-- 
cgit v1.2.3

