From 7107d329ba61ce77d3d41e32ad99808aeb4926c7 Mon Sep 17 00:00:00 2001 From: keyan Date: Thu, 14 Oct 2021 16:05:37 -0500 Subject: [PATCH] invites page --- api/resolvers/invite.js | 14 +++++- api/typeDefs/invite.js | 1 + components/accordian-item.js | 10 +++-- components/header.js | 4 ++ pages/invites/index.js | 83 +++++++++++++++++++++++++++++++++--- styles/invites.module.css | 27 ++++++++++++ 6 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 styles/invites.module.css diff --git a/api/resolvers/invite.js b/api/resolvers/invite.js index da640c13..056a356a 100644 --- a/api/resolvers/invite.js +++ b/api/resolvers/invite.js @@ -28,10 +28,22 @@ export default { return await models.invite.create({ data: { gift, limit, userId: me.id } }) + }, + revokeInvite: async (parent, { id }, { me, models }) => { + if (!me) { + throw new AuthenticationError('you must be logged in') + } + + return await models.invite.update({ + where: { id }, + data: { revoked: true } + }) } }, Invite: { - invitees: async (invite, args, { models }) => [] + invitees: async (invite, args, { me, models }) => { + return await models.user.findMany({ where: { inviteId: invite.id } }) + } } } diff --git a/api/typeDefs/invite.js b/api/typeDefs/invite.js index 23450db5..4c996776 100644 --- a/api/typeDefs/invite.js +++ b/api/typeDefs/invite.js @@ -7,6 +7,7 @@ export default gql` extend type Mutation { createInvite(gift: Int!, limit: Int): Invite + revokeInvite(id: ID!): Invite } type Invite { diff --git a/components/accordian-item.js b/components/accordian-item.js index 65561dc9..e079f98d 100644 --- a/components/accordian-item.js +++ b/components/accordian-item.js @@ -3,15 +3,17 @@ import ArrowRight from '../svgs/arrow-right-s-fill.svg' import ArrowDown from '../svgs/arrow-down-s-fill.svg' import { useEffect, useState } from 'react' -export default function AccordianItem ({ header, body, headerColor = 'grey' }) { - const [open, setOpen] = useState(false) +export default function AccordianItem ({ header, body, headerColor = 'grey', show }) { + const [open, setOpen] = useState(show) useEffect(() => { - setOpen(false) + setOpen(show) }, []) return ( - +
} eventKey='0' diff --git a/components/header.js b/components/header.js index 32e69761..7f25f64c 100644 --- a/components/header.js +++ b/components/header.js @@ -62,6 +62,10 @@ export default function Header () { wallet + + + invites +
diff --git a/pages/invites/index.js b/pages/invites/index.js index 0d23cf80..09441496 100644 --- a/pages/invites/index.js +++ b/pages/invites/index.js @@ -1,9 +1,11 @@ import Layout from '../../components/layout' import * as Yup from 'yup' -import { Form, Input, SubmitButton } from '../../components/form' +import { CopyInput, Form, Input, SubmitButton } from '../../components/form' import { InputGroup } from 'react-bootstrap' import { gql, useMutation, useQuery } from '@apollo/client' import { INVITE_FIELDS } from '../../fragments/invites' +import AccordianItem from '../../components/accordian-item' +import styles from '../../styles/invites.module.css' export const InviteSchema = Yup.object({ gift: Yup.number().typeError('must be a number') @@ -67,11 +69,74 @@ function InviteForm () { name='limit' /> - create + create ) } +function Invite ({ invite, active }) { + const [revokeInvite] = useMutation( + gql` + ${INVITE_FIELDS} + mutation revokeInvite($id: ID!) { + revokeInvite(id: $id) { + ...InviteFields + } + }` + ) + + return ( +
+ +
+ {invite.invitees.length} joined{invite.limit ? ` of ${invite.limit}` : ''} + {active + ? ( + <> + \ + revokeInvite({ variables: { id: invite.id } })} + >revoke + + ) + + : invite.revoked && ( + <> + \ + revoked + + )} +
+
+ ) +} + +function InviteList ({ name, invites }) { + return ( +
+ {name}
} body={ +
{invites.map(invite => { + return + })} +
+ } + /> +
+ ) +} + export default function Invites () { const { data } = useQuery( gql` @@ -82,12 +147,20 @@ export default function Invites () { } } `) + + const [active, inactive] = data && data.invites + ? data.invites.reduce((result, invite) => { + result[invite.revoked || (invite.limit && invite.invitees.length >= invite.limit) ? 1 : 0].push(invite) + return result + }, + [[], []]) + : [[], []] + return ( - {data && data.invites && data.invites.map(invite => { - return
{invite.id}
- })} + {active.length > 0 && } + {inactive.length > 0 && }
) } diff --git a/styles/invites.module.css b/styles/invites.module.css new file mode 100644 index 00000000..6a266d70 --- /dev/null +++ b/styles/invites.module.css @@ -0,0 +1,27 @@ +.invites { + background-color: rgba(0, 0, 0, 0.06); + border-radius: .4rem; + padding: .75rem; +} + +.invites { + margin-bottom: 0 !important; +} + +.other { + font-weight: 500; + font-size: 70%; + color: grey; +} + +.revoke { + cursor: pointer; +} + +.invite { + margin-bottom: .5rem; +} + +.invite:last-child { + margin-bottom: 0; +} \ No newline at end of file