From 26235158fa9cd09d23b3f792e4d0da7d69b28711 Mon Sep 17 00:00:00 2001 From: Yen Colon Date: Fri, 15 Jan 2021 10:25:28 -0400 Subject: [PATCH 1/5] reactions cells --- .../PartReactionsCell/PartReactionsCell.js | 22 ++++++++++++++++ .../PartReactionsCell.mock.js | 6 +++++ .../PartReactionsCell.stories.js | 20 ++++++++++++++ .../PartReactionsCell.test.js | 26 +++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 web/src/components/PartReactionsCell/PartReactionsCell.js create mode 100644 web/src/components/PartReactionsCell/PartReactionsCell.mock.js create mode 100644 web/src/components/PartReactionsCell/PartReactionsCell.stories.js create mode 100644 web/src/components/PartReactionsCell/PartReactionsCell.test.js diff --git a/web/src/components/PartReactionsCell/PartReactionsCell.js b/web/src/components/PartReactionsCell/PartReactionsCell.js new file mode 100644 index 0000000..1d311e2 --- /dev/null +++ b/web/src/components/PartReactionsCell/PartReactionsCell.js @@ -0,0 +1,22 @@ +export const QUERY = gql` + query PartReactionsQuery { + partReactions { + id + emote + user { + id + name + } + } + } +` + +export const Loading = () =>
Loading...
+ +export const Empty = () =>
Empty
+ +export const Failure = ({ error }) =>
Error: {error.message}
+ +export const Success = ({ partReactions }) => { + return JSON.stringify(partReactions) +} diff --git a/web/src/components/PartReactionsCell/PartReactionsCell.mock.js b/web/src/components/PartReactionsCell/PartReactionsCell.mock.js new file mode 100644 index 0000000..d96dad4 --- /dev/null +++ b/web/src/components/PartReactionsCell/PartReactionsCell.mock.js @@ -0,0 +1,6 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + partReactions: { + id: 42, + }, +}) diff --git a/web/src/components/PartReactionsCell/PartReactionsCell.stories.js b/web/src/components/PartReactionsCell/PartReactionsCell.stories.js new file mode 100644 index 0000000..dfd7507 --- /dev/null +++ b/web/src/components/PartReactionsCell/PartReactionsCell.stories.js @@ -0,0 +1,20 @@ +import { Loading, Empty, Failure, Success } from './PartReactionsCell' +import { standard } from './PartReactionsCell.mock' + +export const loading = () => { + return Loading ? : null +} + +export const empty = () => { + return Empty ? : null +} + +export const failure = () => { + return Failure ? : null +} + +export const success = () => { + return Success ? : null +} + +export default { title: 'Cells/PartReactionsCell' } diff --git a/web/src/components/PartReactionsCell/PartReactionsCell.test.js b/web/src/components/PartReactionsCell/PartReactionsCell.test.js new file mode 100644 index 0000000..0b9b0d1 --- /dev/null +++ b/web/src/components/PartReactionsCell/PartReactionsCell.test.js @@ -0,0 +1,26 @@ +import { render, screen } from '@redwoodjs/testing' +import { Loading, Empty, Failure, Success } from './PartReactionsCell' +import { standard } from './PartReactionsCell.mock' + +describe('PartReactionsCell', () => { + test('Loading renders successfully', () => { + render() + // Use screen.debug() to see output + expect(screen.getByText('Loading...')).toBeInTheDocument() + }) + + test('Empty renders successfully', async () => { + render() + expect(screen.getByText('Empty')).toBeInTheDocument() + }) + + test('Failure renders successfully', async () => { + render() + expect(screen.getByText(/Oh no/i)).toBeInTheDocument() + }) + + test('Success renders successfully', async () => { + render() + expect(screen.getByText(/42/i)).toBeInTheDocument() + }) +}) -- 2.39.5 From 136f2966b5389e2490374e0f1618f43852517415 Mon Sep 17 00:00:00 2001 From: Yen Colon Date: Tue, 19 Jan 2021 22:19:40 -0400 Subject: [PATCH 2/5] adding fetch preactions by partId --- api/src/graphql/partReactions.sdl.js | 1 + .../services/partReactions/partReactions.js | 6 ++ .../components/ReactionList/ReactionList.js | 72 +++++++++++++++++++ .../ReactionList/ReactionList.test.js | 0 4 files changed, 79 insertions(+) create mode 100644 web/src/components/ReactionList/ReactionList.js create mode 100644 web/src/components/ReactionList/ReactionList.test.js diff --git a/api/src/graphql/partReactions.sdl.js b/api/src/graphql/partReactions.sdl.js index 4eaaa26..b27334e 100644 --- a/api/src/graphql/partReactions.sdl.js +++ b/api/src/graphql/partReactions.sdl.js @@ -13,6 +13,7 @@ export const schema = gql` type Query { partReactions: [PartReaction!]! partReaction(id: String!): PartReaction + partReactionsByPartId(partId: String!): [PartReaction!]! } input TogglePartReactionInput { diff --git a/api/src/services/partReactions/partReactions.js b/api/src/services/partReactions/partReactions.js index 9116014..6adac0f 100644 --- a/api/src/services/partReactions/partReactions.js +++ b/api/src/services/partReactions/partReactions.js @@ -15,6 +15,12 @@ export const partReaction = ({ id }) => { }) } +export const partReactionsByPartId = ({ partId }) => { + return db.partReaction.findMany({ + where: { partId: partId }, + }) +} + export const togglePartReaction = async ({ input }) => { // if write fails emote_userId_partId @@unique constraint, then delete it instead requireAuth() diff --git a/web/src/components/ReactionList/ReactionList.js b/web/src/components/ReactionList/ReactionList.js new file mode 100644 index 0000000..3aeaa8a --- /dev/null +++ b/web/src/components/ReactionList/ReactionList.js @@ -0,0 +1,72 @@ +import { useState } from 'react' +import Dialog from '@material-ui/core/Dialog' +import Tab from '@material-ui/core/Tab' +import Tabs from '@material-ui/core/Tabs' + +export const QUERY = gql` + query FIND_PART_BY_USERNAME_TITLE( + $userName: String! + $partTitle: String + $currentUserId: String + ) { + userPart: userName(userName: $userName) { + id + name + userName + bio + image + Part(partTitle: $partTitle) { + id + title + description + code + mainImage + createdAt + updatedAt + userId + Reaction { + emote + user { + userName + image + } + } + userReactions: Reaction(userId: $currentUserId) { + emote + } + Comment { + id + text + user { + userName + image + } + } + } + } + } +` + +const emojiMenu = ['all', '❤️', '👍', '😄', '🙌'] + +const ReactionList = ({}) => { + return ( + + {}} + variant="scrollable" + scrollButtons="off" + textColor="primary" + indicatorColor="primary" + > + {emojiMenu.map((emoji, i) => ( + + ))} + +
List
+
+ ) +} + +export default ReactionList diff --git a/web/src/components/ReactionList/ReactionList.test.js b/web/src/components/ReactionList/ReactionList.test.js new file mode 100644 index 0000000..e69de29 -- 2.39.5 From dcf376754b4c8d4c75b89748f861dc9da02521b1 Mon Sep 17 00:00:00 2001 From: Yen Colon Date: Tue, 19 Jan 2021 22:23:11 -0400 Subject: [PATCH 3/5] implementing reactions cell and component --- .../components/PartReactions/PartReactions.js | 69 ++++++++++++++++++ .../PartReactions.test.js} | 0 .../PartReactionsCell/PartReactionsCell.js | 14 ++-- .../components/ReactionList/ReactionList.js | 72 ------------------- 4 files changed, 78 insertions(+), 77 deletions(-) create mode 100644 web/src/components/PartReactions/PartReactions.js rename web/src/components/{ReactionList/ReactionList.test.js => PartReactions/PartReactions.test.js} (100%) delete mode 100644 web/src/components/ReactionList/ReactionList.js diff --git a/web/src/components/PartReactions/PartReactions.js b/web/src/components/PartReactions/PartReactions.js new file mode 100644 index 0000000..d47e878 --- /dev/null +++ b/web/src/components/PartReactions/PartReactions.js @@ -0,0 +1,69 @@ +import { useState } from 'react' +import Tab from '@material-ui/core/Tab' +import Tabs from '@material-ui/core/Tabs' +import { Link, routes } from '@redwoodjs/router' +import { countEmotes } from 'src/helpers/emote' +import ImageUploader from 'src/components/ImageUploader' + +const PartReactions = ({ reactions }) => { + const emotes = countEmotes(reactions) + const [tab, setTab] = useState(0) + const onTabChange = (_, newValue) => { + setTab(newValue) + } + + return ( + <> +
+ + {emotes.map((emote, i) => ( + + ))} + +
    + {reactions + .filter((reaction) => reaction.emote === emotes[tab].emoji) + .map((reactionPart, i) => ( +
  • +
    + +
    +
    +
    + + {reactionPart.user?.userName} + +
    +
    +
  • + ))} +
+
+ + ) +} + +export default PartReactions diff --git a/web/src/components/ReactionList/ReactionList.test.js b/web/src/components/PartReactions/PartReactions.test.js similarity index 100% rename from web/src/components/ReactionList/ReactionList.test.js rename to web/src/components/PartReactions/PartReactions.test.js diff --git a/web/src/components/PartReactionsCell/PartReactionsCell.js b/web/src/components/PartReactionsCell/PartReactionsCell.js index 1d311e2..d0f4bc9 100644 --- a/web/src/components/PartReactionsCell/PartReactionsCell.js +++ b/web/src/components/PartReactionsCell/PartReactionsCell.js @@ -1,12 +1,16 @@ +import PartReactions from 'src/components/PartReactions' + export const QUERY = gql` - query PartReactionsQuery { - partReactions { + query PartReactionsQuery($partId: String!) { + partReactionsByPartId(partId: $partId) { id emote user { id - name + userName + image } + updatedAt } } ` @@ -17,6 +21,6 @@ export const Empty = () =>
Empty
export const Failure = ({ error }) =>
Error: {error.message}
-export const Success = ({ partReactions }) => { - return JSON.stringify(partReactions) +export const Success = ({ partReactionsByPartId }) => { + return //JSON.stringify(partReactions) } diff --git a/web/src/components/ReactionList/ReactionList.js b/web/src/components/ReactionList/ReactionList.js deleted file mode 100644 index 3aeaa8a..0000000 --- a/web/src/components/ReactionList/ReactionList.js +++ /dev/null @@ -1,72 +0,0 @@ -import { useState } from 'react' -import Dialog from '@material-ui/core/Dialog' -import Tab from '@material-ui/core/Tab' -import Tabs from '@material-ui/core/Tabs' - -export const QUERY = gql` - query FIND_PART_BY_USERNAME_TITLE( - $userName: String! - $partTitle: String - $currentUserId: String - ) { - userPart: userName(userName: $userName) { - id - name - userName - bio - image - Part(partTitle: $partTitle) { - id - title - description - code - mainImage - createdAt - updatedAt - userId - Reaction { - emote - user { - userName - image - } - } - userReactions: Reaction(userId: $currentUserId) { - emote - } - Comment { - id - text - user { - userName - image - } - } - } - } - } -` - -const emojiMenu = ['all', '❤️', '👍', '😄', '🙌'] - -const ReactionList = ({}) => { - return ( - - {}} - variant="scrollable" - scrollButtons="off" - textColor="primary" - indicatorColor="primary" - > - {emojiMenu.map((emoji, i) => ( - - ))} - -
List
-
- ) -} - -export default ReactionList -- 2.39.5 From f5e588fbc4ed95b949de3130be2237033d2a5cee Mon Sep 17 00:00:00 2001 From: Yen Colon Date: Tue, 19 Jan 2021 23:44:15 -0400 Subject: [PATCH 4/5] improving part reactions ui --- .../components/PartReactions/PartReactions.js | 70 ++++++++++--------- .../PartReactionsCell/PartReactionsCell.js | 2 +- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/web/src/components/PartReactions/PartReactions.js b/web/src/components/PartReactions/PartReactions.js index d47e878..37e343a 100644 --- a/web/src/components/PartReactions/PartReactions.js +++ b/web/src/components/PartReactions/PartReactions.js @@ -13,32 +13,35 @@ const PartReactions = ({ reactions }) => { } return ( - <> -
- - {emotes.map((emote, i) => ( - - ))} - -
    - {reactions - .filter((reaction) => reaction.emote === emotes[tab].emoji) - .map((reactionPart, i) => ( -
  • +
    + + + {emotes.map((emote, i) => ( + + ))} + +
      + {reactions + .filter((reaction) => + tab === 0 ? true : reaction.emote === emotes[tab - 1].emoji + ) + .map((reactionPart, i) => ( +
    • +
      { />
      -
      +
      {
      -
    • - ))} -
    -
    - +
+
+ {reactionPart.emote} +
+ + ))} + + ) } diff --git a/web/src/components/PartReactionsCell/PartReactionsCell.js b/web/src/components/PartReactionsCell/PartReactionsCell.js index d0f4bc9..2cf4c0c 100644 --- a/web/src/components/PartReactionsCell/PartReactionsCell.js +++ b/web/src/components/PartReactionsCell/PartReactionsCell.js @@ -22,5 +22,5 @@ export const Empty = () =>
Empty
export const Failure = ({ error }) =>
Error: {error.message}
export const Success = ({ partReactionsByPartId }) => { - return //JSON.stringify(partReactions) + return } -- 2.39.5 From 02032c280447652921ed39e870c0ef32f862384d Mon Sep 17 00:00:00 2001 From: Yen Colon Date: Tue, 19 Jan 2021 23:46:36 -0400 Subject: [PATCH 5/5] exposing who likes a part --- .../components/EmojiReaction/EmojiReaction.js | 26 +++++++++++-------- web/src/components/PartProfile/PartProfile.js | 12 +++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/web/src/components/EmojiReaction/EmojiReaction.js b/web/src/components/EmojiReaction/EmojiReaction.js index ce254b9..dbc931a 100644 --- a/web/src/components/EmojiReaction/EmojiReaction.js +++ b/web/src/components/EmojiReaction/EmojiReaction.js @@ -20,6 +20,7 @@ const EmojiReaction = ({ emotes, userEmotes, onEmote = () => {}, + onShowPartReactions, className, }) => { const { currentUser } = useAuth() @@ -107,17 +108,20 @@ const EmojiReaction = ({ horizontal: 'left', }} > -
- {emojiMenu.map((emoji, i) => ( - - ))} +
+
+ {emojiMenu.map((emoji, i) => ( + + ))} +
+
diff --git a/web/src/components/PartProfile/PartProfile.js b/web/src/components/PartProfile/PartProfile.js index 7ff2d8e..222a47b 100644 --- a/web/src/components/PartProfile/PartProfile.js +++ b/web/src/components/PartProfile/PartProfile.js @@ -2,12 +2,14 @@ import { useState, useEffect, useRef } from 'react' import { useAuth } from '@redwoodjs/auth' import { Link, navigate, routes } from '@redwoodjs/router' import Editor from 'rich-markdown-editor' +import Dialog from '@material-ui/core/Dialog' import ImageUploader from 'src/components/ImageUploader' import ConfirmDialog from 'src/components/ConfirmDialog' import Breadcrumb from 'src/components/Breadcrumb' import EmojiReaction from 'src/components/EmojiReaction' import Button from 'src/components/Button' +import PartReactionsCell from '../PartReactionsCell' import { countEmotes } from 'src/helpers/emote' import { getActiveClasses } from 'get-active-classes' @@ -21,6 +23,7 @@ const PartProfile = ({ }) => { const [comment, setComment] = useState('') const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false) + const [isReactionsModalOpen, setIsReactionsModalOpen] = useState(false) const [isInvalid, setIsInvalid] = useState(false) const { currentUser } = useAuth() const editorRef = useRef(null) @@ -94,6 +97,7 @@ const PartProfile = ({ emotes={emotes} userEmotes={userEmotes} onEmote={onReaction} + onShowPartReactions={() => setIsReactionsModalOpen(true)} />