add group invite codes generator, resetor, etc.

This commit is contained in:
Michael Fatemi 2021-07-15 13:32:26 -04:00
parent 9bcc29ac13
commit 9bf4f4c568
8 changed files with 144 additions and 73 deletions

View File

@ -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 (
<div>

View File

@ -1,12 +1,32 @@
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<IGroup>(DEFAULT_GROUP());
useEffect(() => {
getGroup(id).then(setGroup);
}, [id, setGroup]);
export default function Group({ group }: { group: IGroup }) {
return (
<GroupContext.Provider value={{ group }}>
<div
style={{
textAlign: 'center',
@ -19,11 +39,11 @@ export default function Group({ group }: { group: IGroup }) {
<UILink href="/">Home</UILink>
<br />
<br />
<GroupMembersLink group={group} />
<GroupMembersLink />
<br />
<GroupSettingsLink group={group} />
<GroupSettingsLink />
<br />
<EventCreatorLink group={group} />
<EventCreatorLink />
<br />
{group.events.length > 0 ? (
@ -34,5 +54,6 @@ export default function Group({ group }: { group: IGroup }) {
</span>
)}
</div>
</GroupContext.Provider>
);
}

View File

@ -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 (
<>
<span>
Join this group with the code{' '}
<b>
<code>{group.joinCode}</code>
</b>
</span>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<UIButton
onClick={resetJoinCode}
style={{
backgroundColor: lightgrey,
margin: '0.5rem',
flex: 1,
}}
>
Reset
</UIButton>
<UIButton
onClick={generateJoinCode}
style={{
backgroundColor: lightgrey,
margin: '0.5rem',
flex: 1,
}}
>
Regenerate
</UIButton>
</div>
</>
);
} else {
return (
<>
This group has no way for new members to join.
<UIButton
onClick={generateJoinCode}
style={{
backgroundColor: lightgrey,
marginTop: '0.5rem',
marginBottom: '0.5rem',
}}
>
Generate a code
</UIButton>
</>
);
}
}

View File

@ -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 }) {
<br />
<UISecondaryBox>
<h1>Members</h1>
<GroupInviteCodeGenerator />
{group.users.map(({ name }) => (
<span key={name}>{name}</span>
))}

View File

@ -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<IGroup | null>(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 (
<div style={{ textAlign: 'center' }}>
<h1>Group Not Found</h1>
<Link to="/">Home</Link>
</div>
);
}
if (!group) {
return null;
}
return <Group group={group} />;
return <Group id={+id} />;
}

View File

@ -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 (
<div>

View File

@ -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) {

View File

@ -54,6 +54,7 @@ export type IGroup = {
id: number;
name: string;
}[];
joinCode: string | null;
};
/**