Add Part comments

This commit is contained in:
Kurt Hutten
2020-11-08 17:24:43 +11:00
parent 9ff1d5043d
commit 5034cf98c3
7 changed files with 103 additions and 13 deletions

View File

@@ -1,13 +1,15 @@
import { getActiveClasses } from 'get-active-classes'
import Svg from 'src/components/Svg'
const Button = ({onClick, iconName, children, className, shouldAnimateHover}) => {
const Button = ({onClick, iconName, children, className, shouldAnimateHover, disabled}) => {
return (
<button
disabled={disabled}
className={getActiveClasses(
"flex items-center bg-opacity-50 rounded-xl p-2 px-6 text-indigo-600",
{'mx-px transform hover:-translate-y-px transition-all duration-150': shouldAnimateHover},
className
{'mx-px transform hover:-translate-y-px transition-all duration-150': shouldAnimateHover && !disabled},
className,
{"bg-gray-300 shadow-none hover:shadow-none": disabled},
)}
onClick={onClick}
>

View File

@@ -1,6 +1,7 @@
import { useState } from 'react'
import { getActiveClasses } from "get-active-classes"
import Popover from '@material-ui/core/Popover'
import { useAuth } from '@redwoodjs/auth'
import Svg from 'src/components/Svg'
@@ -14,6 +15,7 @@ const noEmotes =[{
const textShadow = {textShadow: '0 4px 6px rgba(0, 0, 0, 0.3)'}
const EmojiReaction = ({ emotes, userEmotes, onEmote = () => {}, className }) => {
const { currentUser } = useAuth()
const [isOpen, setIsOpen] = useState(false)
const [anchorEl, setAnchorEl] = useState(null)
const [popoverId, setPopoverId] = useState(undefined)
@@ -39,7 +41,8 @@ const EmojiReaction = ({ emotes, userEmotes, onEmote = () => {}, className }) =>
}
const handleEmojiClick = (emoji) => {
onEmote(emoji)
// TODO handle user not signed in better, maybe open up a modal, I danno think about it.
currentUser && onEmote(emoji)
closePopover()
}
@@ -61,7 +64,7 @@ const EmojiReaction = ({ emotes, userEmotes, onEmote = () => {}, className }) =>
<span
className={getActiveClasses(
"rounded-full tracking-wide hover:bg-indigo-100 p-1 mx-px transform hover:-translate-y-px transition-all duration-150 border-indigo-400",
{'border': userEmotes.includes(emote.emoji)}
{'border': currentUser && userEmotes.includes(emote.emoji)}
)}
style={textShadow}
key={`${emote.emoji}--${i}`}

View File

@@ -5,7 +5,7 @@ import { useAuth } from '@redwoodjs/auth'
import PartProfile from 'src/components/PartProfile'
export const QUERY = gql`
query FIND_PART_BY_USERNAME_TITLE($userName: String!, $partTitle: String!, $currentUserId: String!) {
query FIND_PART_BY_USERNAME_TITLE($userName: String!, $partTitle: String!, $currentUserId: String) {
userPart: userName(userName: $userName) {
id
name
@@ -27,6 +27,14 @@ export const QUERY = gql`
userReactions: Reaction(userId: $currentUserId) {
emote
}
Comment {
id
text
user {
userName
image
}
}
}
}
}
@@ -52,6 +60,14 @@ const TOGGLE_REACTION_MUTATION = gql`
}
}
`
const CREATE_COMMENT_MUTATION = gql`
mutation CreateCommentMutation($input: CreateCommentInput!) {
createComment(input: $input) {
id
text
}
}
`
export const Loading = () => <div>Loading...</div>
@@ -73,7 +89,7 @@ export const Success = ({ userPart, variables: {isEditable}, refetch}) => {
}
const [toggleReaction] = useMutation(TOGGLE_REACTION_MUTATION, {
onCompleted: (hey) => refetch()
onCompleted: () => refetch()
})
const onReaction = (emote) => toggleReaction({variables: {input: {
emote,
@@ -81,6 +97,15 @@ export const Success = ({ userPart, variables: {isEditable}, refetch}) => {
partId: userPart?.Part?.id,
}}})
const [createComment] = useMutation(CREATE_COMMENT_MUTATION, {
onCompleted: () => refetch()
})
const onComment = (text) => createComment({variables: {input: {
text,
userId: currentUser.sub,
partId: userPart?.Part?.id,
}}})
return <PartProfile
userPart={userPart}
onSave={onSave}
@@ -88,5 +113,6 @@ export const Success = ({ userPart, variables: {isEditable}, refetch}) => {
error={error}
isEditable={isEditable}
onReaction={onReaction}
onComment={onComment}
/>
}

View File

@@ -1,6 +1,6 @@
import {useState, useEffect} from 'react'
import { useAuth } from '@redwoodjs/auth'
import { navigate, routes } from '@redwoodjs/router'
import { Link, navigate, routes } from '@redwoodjs/router'
import Editor from "rich-markdown-editor";
import ImageUploader from 'src/components/ImageUploader'
@@ -8,8 +8,18 @@ import Breadcrumb from 'src/components/Breadcrumb'
import EmojiReaction from 'src/components/EmojiReaction'
import Button from 'src/components/Button'
import { countEmotes } from 'src/helpers/emote'
import { getActiveClasses } from 'get-active-classes';
const PartProfile = ({userPart, isEditable, onSave, loading, error, onReaction}) => {
const PartProfile = ({
userPart,
isEditable,
onSave,
loading,
error,
onReaction,
onComment,
}) => {
const [comment, setComment] = useState('')
const { currentUser } = useAuth()
const canEdit = currentUser?.sub === userPart.id
const part = userPart?.Part
@@ -51,7 +61,7 @@ const PartProfile = ({userPart, isEditable, onSave, loading, error, onReaction})
imageUrl={userPart.image}
width={300}
/>
<h4 className="text-indigo-800 text-xl underline text-right py-4">{userPart?.name}</h4>
<h4 className="text-indigo-800 text-xl underline text-right py-4"><Link to={routes.user2({userName: userPart.userName})}>{userPart?.name}</Link></h4>
<div className="h-px bg-indigo-200 mb-4" />
<EmojiReaction
emotes={emotes}
@@ -103,6 +113,55 @@ const PartProfile = ({userPart, isEditable, onSave, loading, error, onReaction})
onChange={onDescriptionChange}
/>
</div>
{/* comments */}
{ !isEditable && <>
<div className="h-px bg-indigo-200 mt-8" />
<h3 className="text-indigo-800 text-lg font-roboto tracking-wider mb-4" >Comments</h3>
<ul>
{part.Comment.map(({text, user, id}) => (
<li key={id} className="flex mb-6">
<div className="w-8 h-8 overflow-hidden rounded-full border border-indigo-300 shadow flex-shrink-0">
<ImageUploader
className=""
onImageUpload={() => {}}
aspectRatio={1}
imageUrl={user?.image}
width={50}
/>
</div>
<div className="ml-4 font-roboto">
<div className="text-gray-800 font-bold text-lg mb-1"><Link to={routes.user2({userName: user.userName})}>
{user.userName}
</Link></div>
<div className="text-gray-700 p-3 rounded bg-gray-200 shadow">
{text}
</div>
</div>
</li>
))}
</ul>
{currentUser && <>
<div className="mt-12 ml-12">
<textarea
className="w-full h-32 rounded-lg shadow-inner outline-none resize-none p-3"
placeholder="Leave a comment"
value={comment}
onChange={({target}) => setComment(target.value)}
/>
</div>
<Button
className={getActiveClasses("ml-auto hover:shadow-lg bg-gray-300 mt-4 mb-20", {'bg-indigo-200': currentUser})}
shouldAnimateHover
disabled={!currentUser}
iconName={'save'}
onClick={() => onComment(comment)}
>Comment</Button>
</>}
</>}
</section>
</div>

View File

@@ -14,7 +14,7 @@ const PartsList = ({ parts }) => {
to={routes.part2({userName: user?.userName, partTitle: title})}
>
<div className="flex items-center p-2 bg-gray-200 border-gray-300 rounded-t-lg border-t border-l border-r">
<div className="w-8 h-8 overflow-hidden rounded-full border border-indigo-300 shadow max-w-xs">
<div className="w-8 h-8 overflow-hidden rounded-full border border-indigo-300 shadow">
<ImageUploader
className=""
onImageUpload={() => {}}

View File

@@ -10,7 +10,7 @@ const EditPart2Page = ({userName, partTitle}) => {
<Part2Cell
userName={userName}
partTitle={partTitle}
currentUserId={currentUser.sub}
currentUserId={currentUser?.sub}
isEditable
/>
</MainLayout>

View File

@@ -10,7 +10,7 @@ const Part2Page = ({userName, partTitle}) => {
<Part2Cell
userName={userName}
partTitle={partTitle}
currentUserId={currentUser.sub}
currentUserId={currentUser?.sub}
/>
</MainLayout>
)