Add Post Comment in Frontity

Create new file calledĀ comments.jsĀ inĀ my-app/packages/mars-theme/src/html/components and add below code

With Frontity v1.0 this code will be replaced by frontity extension. Right now there is no custom extension is not supported, so I followed this approach.

import React, { useEffect, useState } from "react";
import { connect, styled } from "frontity";

const Comments = ({ libraries, state }) => {
    
    // Post Id for single post
    const postId = state.source.dataMap[state.router.path].id;

    const [ comments, setComments ] = useState( [] );
    const [ loading, setLoading ] = useState( true );

    useEffect(() => {

        libraries.source.api.get({
            endpoint: "comments",
            params: { post: postId, _embed: false, per_page: 100 }
        })
        .then(response => {
            response.json().then( data => {
                setComments( data );
                setLoading( false )
            });
        });

    }, []);

    return (
        <CommentBox className="comment">
            <h3>Comments</h3>
            {loading && (<div>Loading...</div>)}
            {!loading && (
                <div>
                    {comments.length === 0 && (<p>Comment not found</p>)}
                    {comments.length > 0 && (
                        <>
                            {comments.map(item => {
                                const date = new Date(item.date);
                                return (
                                    <SingleComment key={item.id}>
                                        <Author>
                                            By <b>{item.author_name}</b>
                                        </Author>
                                        <Fecha>
                                            {" "}
                                            on <b>{date.toDateString()}</b>
                                        </Fecha>

                                        <SingleCommentContent dangerouslySetInnerHTML={{
                                            __html: item.content.rendered
                                        }}
                                        />
                                    </SingleComment>
                                )
                            })}
                        </>
                    )}
                </div>
            )}

        </CommentBox>
    );
}

export default connect(Comments);


const CommentBox = styled.div`
  display: block;
  margin: 20px 0;
`;

const SingleComment = styled.div`
  background: #fff;
  -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.04);
  box-shadow: 0 1px 4px rgba(0,0,0,.04);
  border: 1px solid rgba(0,0,0,.09);
  -webkit-border-radius: 3px;
  border-radius: 3px;
  margin: 10px 0;
  padding: 10px;
`;

const Author = styled.p`
  font-size: 0.8em;
  display: inline;
`;

const Fecha = styled.p`
  font-size: 0.8em;
  display: inline;
`;

const SingleCommentContent = styled.div`
  font-size: 0.9em;
  p {
    margin: 7px 0;
  }
`;

Add below code in my-app/packages/mars-theme/src/html/components/post.js after <Body tag

import Comments from "./comments";


<Comments />

Now post.js file will be look like

import React, { useEffect } from "react";
import { connect, styled } from "frontity";
import List from "./list";
import Comments from "./comments";

const Post = ({ state, actions }) => {

  // Get info of current post.
  const data = state.source.data(state.router.path);

  // Get the the post.
  const post = state.source[data.type][data.id];
  // Get the author.
  const author = state.source.author[post.author];
  const date = new Date(post.date);

  // Prefetch home posts and the list component.
  useEffect(() => {
    actions.source.fetch("/");
    List.preload();
  }, []);

  return data.isReady ? (
    <Container>
      <Head>
        <Title>{post.title.rendered}</Title>
        {data.isPost && (
          <>
            <Author>
              By <b>{author.name}</b>
            </Author>
            <Fecha>
              {" "}
              on <b>{date.toDateString()}</b>
            </Fecha>
          </>
        )}
      </Head>
      <Body
        dangerouslySetInnerHTML={{
          __html: post.content.rendered
        }}
      />
      <Comments />
    </Container>
  ) : null;
};

export default connect(Post);

const Container = styled.div`
  width: 800px;
  margin: 0;
  padding: 24px;
`;

const Head = styled.div``;

const Title = styled.h1`
  margin: 0;
  margin-top: 24px;
  margin-bottom: 8px;
  color: rgba(12, 17, 43);
`;

const Author = styled.p`
  color: rgba(12, 17, 43, 0.9);
  font-size: 0.9em;
  display: inline;
`;

const Fecha = styled.p`
  color: rgba(12, 17, 43, 0.9);
  font-size: 0.9em;
  display: inline;
`;

const Body = styled.div`
  line-height: 1.6em;
  color: rgba(12, 17, 43, 0.8);

  * {
    max-width: 100%;
  }

  img {
    width: 100%;
    object-fit: cover;
    object-position: center;
  }

  figure {
    margin: 24px 0;
    /* next line overrides an inline style of the figure element. */
    width: 100% !important;
    figcaption {
      font-size: 0.7em;
    }
  }

  iframe {
    display: block;
    margin: auto;
  }

  blockquote {
    margin: 16px 0;
    background-color: rgba(0, 0, 0, 0.1);
    border-left: 4px solid rgba(12, 17, 43);
    padding: 4px 16px;
  }

  a {
    color: rgb(31, 56, 197);
    text-decoration: underline;
  }
`;

Out put

Leave a Reply