aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/templates/page
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-15 17:45:41 +0200
committerArmand Philippot <git@armandphilippot.com>2022-05-15 19:06:42 +0200
commitc95cce04393080a52a54191cff7be8fec68af4b0 (patch)
tree1022bc574c8fc8e657be922b26c1cf16cbfd9071 /src/components/templates/page
parent235fe67d770f83131c9ec10b99012319440db690 (diff)
chore: add Article pages
Diffstat (limited to 'src/components/templates/page')
-rw-r--r--src/components/templates/page/page-layout.stories.tsx6
-rw-r--r--src/components/templates/page/page-layout.tsx95
2 files changed, 90 insertions, 11 deletions
diff --git a/src/components/templates/page/page-layout.stories.tsx b/src/components/templates/page/page-layout.stories.tsx
index 480c76e..8e518aa 100644
--- a/src/components/templates/page/page-layout.stories.tsx
+++ b/src/components/templates/page/page-layout.stories.tsx
@@ -85,12 +85,12 @@ export default {
},
id: {
control: {
- type: 'text',
+ type: 'number',
},
description: 'The page id.',
type: {
- name: 'string',
- required: true,
+ name: 'number',
+ required: false,
},
},
intro: {
diff --git a/src/components/templates/page/page-layout.tsx b/src/components/templates/page/page-layout.tsx
index ac021ba..045b8c1 100644
--- a/src/components/templates/page/page-layout.tsx
+++ b/src/components/templates/page/page-layout.tsx
@@ -1,4 +1,5 @@
import Heading from '@components/atoms/headings/heading';
+import Notice, { type NoticeKind } from '@components/atoms/layout/notice';
import Sidebar from '@components/atoms/layout/sidebar';
import PageFooter, {
type PageFooterProps,
@@ -9,15 +10,19 @@ import PageHeader, {
import Breadcrumb, {
type BreadcrumbItem,
} from '@components/molecules/nav/breadcrumb';
-import CommentForm from '@components/organisms/forms/comment-form';
+import CommentForm, {
+ type CommentFormProps,
+} from '@components/organisms/forms/comment-form';
import CommentsList, {
type CommentsListProps,
} from '@components/organisms/layout/comments-list';
import TableOfContents from '@components/organisms/widgets/table-of-contents';
+import { type SendCommentVars } from '@services/graphql/api';
+import { sendComment } from '@services/graphql/comments';
import useIsMounted from '@utils/hooks/use-is-mounted';
-import { FC, ReactNode, useRef } from 'react';
+import { FC, ReactNode, useRef, useState } from 'react';
import { useIntl } from 'react-intl';
-import Layout, { LayoutProps } from '../layout/layout';
+import Layout, { type LayoutProps } from '../layout/layout';
import styles from './page-layout.module.scss';
export type PageLayoutProps = {
@@ -46,6 +51,10 @@ export type PageLayoutProps = {
*/
headerMeta?: PageHeaderProps['meta'];
/**
+ * The page id.
+ */
+ id?: number;
+ /**
* The page introduction.
*/
intro?: PageHeaderProps['intro'];
@@ -79,6 +88,7 @@ const PageLayout: FC<PageLayoutProps> = ({
comments,
footerMeta,
headerMeta,
+ id,
intro,
isHome = false,
widgets,
@@ -106,8 +116,56 @@ const PageLayout: FC<PageLayoutProps> = ({
? 'article--has-comments'
: 'article--no-comments';
- const saveComment = () => {
- return null;
+ const [status, setStatus] = useState<NoticeKind>('info');
+ const [statusMessage, setStatusMessage] = useState<string>('');
+ const isReplyRef = useRef<boolean>(false);
+
+ const saveComment: CommentFormProps['saveComment'] = async (data, reset) => {
+ if (!id) throw new Error('Page id missing. Cannot save comment.');
+
+ const { comment: commentBody, email, name, parentId, website } = data;
+ const commentData: SendCommentVars = {
+ author: name,
+ authorEmail: email,
+ authorUrl: website || '',
+ clientMutationId: 'contact',
+ commentOn: id,
+ content: commentBody,
+ parent: parentId,
+ };
+ const { comment, success } = await sendComment(commentData);
+
+ isReplyRef.current = !!parentId;
+
+ if (success) {
+ setStatus('success');
+ const successPrefix = intl.formatMessage({
+ defaultMessage: 'Thanks, your comment was successfully sent.',
+ description: 'PageLayout: comment form success message',
+ id: 'B290Ph',
+ });
+ const successMessage = comment?.approved
+ ? intl.formatMessage({
+ defaultMessage: 'It has been approved.',
+ id: 'g3+Ahv',
+ description: 'PageLayout: comment approved.',
+ })
+ : intl.formatMessage({
+ defaultMessage: 'It is now awaiting moderation.',
+ id: 'Vmj5cw',
+ description: 'PageLayout: comment awaiting moderation',
+ });
+ setStatusMessage(`${successPrefix} ${successMessage}`);
+ reset();
+ } else {
+ const error = intl.formatMessage({
+ defaultMessage: 'An error occurred:',
+ description: 'PageLayout: comment form error message',
+ id: 'fkcTGp',
+ });
+ setStatus('error');
+ setStatusMessage(error);
+ }
};
return (
@@ -154,15 +212,36 @@ const PageLayout: FC<PageLayoutProps> = ({
<section className={styles.comments__section}>
<Heading level={2}>{commentsTitle}</Heading>
<CommentsList
- saveComment={saveComment}
comments={comments}
- depth={2}
+ depth={1}
+ Notice={
+ isReplyRef.current === true ? (
+ <Notice
+ kind={status}
+ message={statusMessage}
+ className={styles.notice}
+ />
+ ) : undefined
+ }
+ saveComment={saveComment}
/>
</section>
)}
{allowComments && (
<section className={styles.comments__section}>
- <CommentForm saveComment={saveComment} title={commentFormTitle} />
+ <CommentForm
+ saveComment={saveComment}
+ title={commentFormTitle}
+ Notice={
+ isReplyRef.current === false ? (
+ <Notice
+ kind={status}
+ message={statusMessage}
+ className={styles.notice}
+ />
+ ) : undefined
+ }
+ />
</section>
)}
</div>