From 9bf4f4c568b2ff0adb0119b234566df077145913 Mon Sep 17 00:00:00 2001 From: Michael Fatemi Date: Thu, 15 Jul 2021 13:32:26 -0400 Subject: [PATCH] add group invite codes generator, resetor, etc. --- .../EventCreator/EventCreatorLink.tsx | 8 +- src/components/Group/Group.tsx | 77 ++++++++++++------- .../Group/GroupInviteCodeGenerator.tsx | 72 +++++++++++++++++ src/components/Group/GroupMembersLink.tsx | 12 ++- src/components/Group/GroupPage.tsx | 37 +-------- src/components/Group/GroupSettingsLink.tsx | 6 +- src/components/api.ts | 4 +- src/components/types.ts | 1 + 8 files changed, 144 insertions(+), 73 deletions(-) create mode 100644 src/components/Group/GroupInviteCodeGenerator.tsx diff --git a/src/components/EventCreator/EventCreatorLink.tsx b/src/components/EventCreator/EventCreatorLink.tsx index 9c73eda..ce0b10c 100644 --- a/src/components/EventCreator/EventCreatorLink.tsx +++ b/src/components/EventCreator/EventCreatorLink.tsx @@ -1,9 +1,11 @@ -import EventCreator from './EventCreator'; -import { IGroup } from '../types'; +import { useContext } from 'react'; +import { GroupContext } from '../Group/Group'; import useToggle from '../useToggle'; +import EventCreator from './EventCreator'; -export default function EventCreatorLink({ group }: { group: IGroup }) { +export default function EventCreatorLink() { const [open, toggle] = useToggle(false); + const { group } = useContext(GroupContext); return (
diff --git a/src/components/Group/Group.tsx b/src/components/Group/Group.tsx index f0ef167..beb2a75 100644 --- a/src/components/Group/Group.tsx +++ b/src/components/Group/Group.tsx @@ -1,38 +1,59 @@ +import { createContext, useEffect } from 'react'; +import { getGroup } from '../api'; import EventCreatorLink from '../EventCreator/EventCreatorLink'; import EventStream from '../EventStream'; -import GroupSettingsLink from './GroupSettingsLink'; import { IGroup } from '../types'; import UILink from '../UI/UILink'; +import useImmutable from '../useImmutable'; import GroupMembersLink from './GroupMembersLink'; +import GroupSettingsLink from './GroupSettingsLink'; + +const DEFAULT_GROUP = (): IGroup => ({ + id: 0, + name: '', + users: [], + events: [], + joinCode: null, +}); + +export const GroupContext = createContext({ group: DEFAULT_GROUP() }); + +export default function Group({ id }: { id: number }) { + const [group, setGroup] = useImmutable(DEFAULT_GROUP()); + + useEffect(() => { + getGroup(id).then(setGroup); + }, [id, setGroup]); -export default function Group({ group }: { group: IGroup }) { return ( -
-

{group.name}

- Home -
-
- -
- -
- -
+ +
+

{group.name}

+ Home +
+
+ +
+ +
+ +
- {group.events.length > 0 ? ( - - ) : ( - - There are no events yet. Click 'create event' above to add one! - - )} -
+ {group.events.length > 0 ? ( + + ) : ( + + There are no events yet. Click 'create event' above to add one! + + )} +
+ ); } diff --git a/src/components/Group/GroupInviteCodeGenerator.tsx b/src/components/Group/GroupInviteCodeGenerator.tsx new file mode 100644 index 0000000..caecffe --- /dev/null +++ b/src/components/Group/GroupInviteCodeGenerator.tsx @@ -0,0 +1,72 @@ +import { useCallback, useContext } from 'react'; +import { lightgrey } from '../../lib/colors'; +import { generateCode, resetCode } from '../api'; +import UIButton from '../UI/UIButton'; +import { GroupContext } from './Group'; + +export default function GroupInviteCodeGenerator() { + const { group } = useContext(GroupContext); + + const generateJoinCode = useCallback(() => { + generateCode(group.id).then((code) => { + group.joinCode = code; + }); + }, [group]); + + const resetJoinCode = useCallback(() => { + resetCode(group.id).then((code) => { + group.joinCode = null; + }); + }, [group]); + + if (group.joinCode) { + return ( + <> + + Join this group with the code{' '} + + {group.joinCode} + + +
+ + Reset + + + Regenerate + +
+ + ); + } else { + return ( + <> + This group has no way for new members to join. + + Generate a code + + + ); + } +} diff --git a/src/components/Group/GroupMembersLink.tsx b/src/components/Group/GroupMembersLink.tsx index 4cd2b6e..9c030a2 100644 --- a/src/components/Group/GroupMembersLink.tsx +++ b/src/components/Group/GroupMembersLink.tsx @@ -1,11 +1,14 @@ -import { useState } from 'react'; -import { IGroup } from '../types'; +import { useContext, useState } from 'react'; import UIPressable from '../UI/UIPressable'; import UISecondaryBox from '../UI/UISecondaryBox'; +import { GroupContext } from './Group'; +import GroupInviteCodeGenerator from './GroupInviteCodeGenerator'; -export default function GroupMembersLink({ group }: { group: IGroup }) { +export default function GroupMembersLink() { const [open, setOpen] = useState(false); + const { group } = useContext(GroupContext); + const handleClick = () => setOpen(!open); return ( @@ -16,6 +19,9 @@ export default function GroupMembersLink({ group }: { group: IGroup }) {

Members

+ + + {group.users.map(({ name }) => ( {name} ))} diff --git a/src/components/Group/GroupPage.tsx b/src/components/Group/GroupPage.tsx index bf69432..b7caf0e 100644 --- a/src/components/Group/GroupPage.tsx +++ b/src/components/Group/GroupPage.tsx @@ -1,43 +1,8 @@ -import { useEffect, useState } from 'react'; import { useParams } from 'react-router'; -import { Link } from 'react-router-dom'; -import { getGroup } from '../api'; -import { IGroup } from '../types'; import Group from './Group'; export default function GroupPage() { const { id } = useParams<{ id: string }>(); - const [loading, setLoading] = useState(true); - const [group, setGroup] = useState(null); - useEffect(() => { - if (isNaN(+id)) { - setLoading(false); - return; - } - - async function load() { - setLoading(true); - getGroup(+id) - .then(setGroup) - .finally(() => setLoading(false)); - } - - load(); - }, [id]); - - if (!group && !loading) { - return ( -
-

Group Not Found

- Home -
- ); - } - - if (!group) { - return null; - } - - return ; + return ; } diff --git a/src/components/Group/GroupSettingsLink.tsx b/src/components/Group/GroupSettingsLink.tsx index 7b97911..a3ad286 100644 --- a/src/components/Group/GroupSettingsLink.tsx +++ b/src/components/Group/GroupSettingsLink.tsx @@ -1,9 +1,11 @@ -import { IGroup } from '../types'; +import { useContext } from 'react'; import useToggle from '../useToggle'; +import { GroupContext } from './Group'; import GroupSettings from './GroupSettings'; -export default function GroupSettingsLink({ group }: { group: IGroup }) { +export default function GroupSettingsLink() { const [open, toggle] = useToggle(false); + const { group } = useContext(GroupContext); return (
diff --git a/src/components/api.ts b/src/components/api.ts index d4c98a5..b8c9de0 100644 --- a/src/components/api.ts +++ b/src/components/api.ts @@ -166,7 +166,9 @@ export async function joinGroup(id: number, code: string) { } export async function generateCode(groupId: number) { - return await post('/groups/' + groupId + '/generate_code', {}); + const { code } = await post(`/groups/${groupId}/generate_code`, {}); + + return code; } export async function resetCode(groupId: number) { diff --git a/src/components/types.ts b/src/components/types.ts index afa9c89..e6a05eb 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -54,6 +54,7 @@ export type IGroup = { id: number; name: string; }[]; + joinCode: string | null; }; /**