add dialogs frfr

This commit is contained in:
Michael Fatemi 2021-08-11 19:50:42 -04:00
parent 8ad8726780
commit 97268397d6
13 changed files with 118 additions and 53 deletions

View File

@ -84,11 +84,11 @@ export default function EventCreator({ group }: { group: IGroup }) {
]);
return (
<UISecondaryBox style={{ textAlign: 'center' }}>
<h1 style={{ textAlign: 'center', marginBottom: '0.5rem' }}>
<UISecondaryBox style={{ textAlign: 'center', minWidth: '25rem' }}>
<h3 style={{ textAlign: 'center', marginBottom: '0.5rem' }}>
Create Event
</h1>
<h3 style={{ textAlign: 'center', marginTop: '0.5rem' }}>{group.name}</h3>
</h3>
<h4 style={{ textAlign: 'center', marginTop: '0.5rem' }}>{group.name}</h4>
Name
<UITextInput value={name} onChangeText={setName} disabled={creating} />
<br />

View File

@ -1,5 +1,6 @@
import { useContext } from 'react';
import { GroupContext } from '../Group/Group';
import UIDialogShell from '../UI/UIDialogShell';
import UIPressable from '../UI/UIPressable';
import useToggle from '../useToggle';
import EventCreator from './EventCreator';
@ -12,10 +13,9 @@ export default function EventCreatorLink() {
<>
<UIPressable onClick={toggle}>Create Event</UIPressable>
{open && (
<>
<br />
<UIDialogShell onClose={toggle}>
<EventCreator group={group} />
</>
</UIDialogShell>
)}
</>
);

View File

@ -30,7 +30,14 @@ export default function Group({ id }: { id: number }) {
useEffect(() => {
setLoading(true);
getGroup(id)
.then(setGroup)
.then((group) => {
// @ts-ignore
if ('status' in group && group.status === 'error') {
setGroup(null);
} else {
setGroup(group);
}
})
.finally(() => setLoading(false));
}, [id, setGroup]);
@ -54,7 +61,7 @@ export default function Group({ id }: { id: number }) {
style={{
display: 'flex',
flexDirection: 'column',
minWidth: '10rem',
minWidth: '15rem',
}}
>
<h1>{group.name}</h1>

View File

@ -1,6 +1,7 @@
import { useCallback, useContext, useMemo, useState } from 'react';
import { addGroupAdmin, removeGroupAdmin } from '../api';
import { useMe } from '../hooks';
import UIDialogShell from '../UI/UIDialogShell';
import UIPressable from '../UI/UIPressable';
import UISecondaryBox from '../UI/UISecondaryBox';
import { GroupContext } from './Group';
@ -47,9 +48,14 @@ export default function GroupMembersLink() {
<>
<UIPressable onClick={handleClick}>Members</UIPressable>
{open && (
<>
<br />
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
<UIDialogShell onClose={() => setOpen(false)}>
<UISecondaryBox
style={{
textAlign: 'center',
backgroundColor: '#fdfdfd',
}}
cancelClicks
>
<h3>Members</h3>
{group.users.map(({ name, id }) => (
@ -71,7 +77,7 @@ export default function GroupMembersLink() {
<GroupInviteCode />
</UISecondaryBox>
</>
</UIDialogShell>
)}
</>
);

View File

@ -9,6 +9,8 @@ export default function GroupSettings({ group }: { group: IGroup }) {
const [deletionSuccessful, setDeletionSuccessful] =
useState<boolean | null>(null);
const [confirmingDeletion, setConfirmingDeletion] = useState(false);
const onClickedDelete = useCallback(() => {
deleteGroup(group.id)
.then(({ status }) => {
@ -19,12 +21,29 @@ export default function GroupSettings({ group }: { group: IGroup }) {
});
}, [group.id]);
const confirmDeletion = useCallback(() => {
setConfirmingDeletion(false);
onClickedDelete();
}, [onClickedDelete]);
const cancelDeletion = useCallback(() => {
setConfirmingDeletion(false);
}, [setConfirmingDeletion]);
return (
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
<h1>Settings</h1>
{deletionSuccessful !== true && (
<UIPressable onClick={onClickedDelete}>Delete Group</UIPressable>
)}
<UISecondaryBox style={{ textAlign: 'center', minWidth: '20rem' }}>
<h3>Settings</h3>
{deletionSuccessful !== true &&
(confirmingDeletion ? (
<>
<UIPressable onClick={confirmDeletion}>Confirm</UIPressable>
<UIPressable onClick={cancelDeletion}>Cancel</UIPressable>
</>
) : (
<UIPressable onClick={() => setConfirmingDeletion(true)}>
Delete Group
</UIPressable>
))}
{deletionSuccessful !== null &&
(deletionSuccessful ? (
<span>

View File

@ -1,4 +1,5 @@
import { useContext } from 'react';
import UIDialogShell from '../UI/UIDialogShell';
import UIPressable from '../UI/UIPressable';
import useToggle from '../useToggle';
import { GroupContext } from './Group';
@ -12,10 +13,9 @@ export default function GroupSettingsLink() {
<>
<UIPressable onClick={toggle}>Settings</UIPressable>
{open && (
<>
<br />
<UIDialogShell onClose={toggle}>
<GroupSettings group={group} />
</>
</UIDialogShell>
)}
</>
);

View File

@ -28,7 +28,7 @@ export default function GroupCreator() {
const buttonEnabled = name.length > 0 && !creating;
return (
<UISecondaryBox style={{ width: '100%', boxSizing: 'border-box' }}>
<UISecondaryBox style={{ minWidth: '25rem' }}>
<h3 style={{ textAlign: 'center' }}>Create Group</h3>
Name
<UITextInput onChangeText={setName} value={name} />

View File

@ -1,25 +1,20 @@
import GroupCreator from './GroupCreator';
import UIButton from '../UI/UIButton';
import UIDialogShell from '../UI/UIDialogShell';
import useToggle from '../useToggle';
import GroupCreator from './GroupCreator';
export default function GroupCreatorLink() {
const [open, toggle] = useToggle(false);
return (
<div style={{ width: '100%', textAlign: 'center' }}>
<div
style={{
cursor: 'pointer',
userSelect: 'none',
}}
onClick={toggle}
>
<UIButton onClick={toggle} style={{ backgroundColor: '#f3f3f3' }}>
Create Group
</div>
</UIButton>
{open && (
<>
<br />
<UIDialogShell onClose={toggle}>
<GroupCreator />
</>
</UIDialogShell>
)}
</div>
);

View File

@ -2,7 +2,6 @@ import { useCallback, useEffect, useState } from 'react';
import { joinGroup, resolveCode } from './api';
import UIButton from './UI/UIButton';
import UIPressable from './UI/UIPressable';
import UISecondaryBox from './UI/UISecondaryBox';
import UITextInput from './UI/UITextInput';
import useToggle from './useToggle';
@ -11,19 +10,21 @@ export type GroupPreview = {
id: number;
};
function GroupJoiner() {
export function GroupJoiner() {
const [code, setCode] = useState('');
const [joining, setJoining] = useState(false);
const [group, setGroup] = useState<GroupPreview | null>(null);
useEffect(() => {
const initialCode = code;
resolveCode(code).then((group) => {
if (code === initialCode) {
setGroup(group);
}
});
if (code) {
const initialCode = code;
resolveCode(code).then((group) => {
if (code === initialCode) {
setGroup(group);
}
});
}
}, [code]);
const join = useCallback(() => {
@ -44,10 +45,13 @@ function GroupJoiner() {
const buttonEnabled = code.length > 0 && !joining;
return (
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
<h3>Join Group</h3>
Code
<UITextInput value={code} onChangeText={setCode} />
<div style={{ display: 'flex', flexDirection: 'column' }}>
<span style={{ fontSize: '0.875rem' }}>Join group with code:</span>
<UITextInput
value={code}
onChangeText={setCode}
style={{ border: '2px solid grey' }}
/>
{group && (
<>
<br />
@ -62,7 +66,7 @@ function GroupJoiner() {
</UIButton>
</>
)}
</UISecondaryBox>
</div>
);
}

View File

@ -1,8 +1,8 @@
import { useEffect, useState } from 'react';
import { getGroups } from '../api';
import { IGroup } from '../types';
import GroupCreatorLink from '../GroupCreator/GroupCreatorLink';
import GroupJoinerLink from '../GroupJoinerLink';
import { GroupJoiner } from '../GroupJoinerLink';
import { IGroup } from '../types';
import GroupList from './GroupList';
export default function Groups() {
@ -21,7 +21,7 @@ export default function Groups() {
}}
>
<h1 style={{ textAlign: 'center' }}>Groups</h1>
<GroupJoinerLink />
<GroupJoiner />
<br />
<GroupCreatorLink />
<br />

View File

@ -0,0 +1,23 @@
export default function UIDialogShell({
children,
onClose,
}: {
children: React.ReactNode;
onClose: () => void;
}) {
return (
<div
style={{
position: 'fixed',
zIndex: 100,
inset: 0,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
onClick={onClose}
>
{children}
</div>
);
}

View File

@ -13,9 +13,11 @@ const baseStyle: CSSProperties = {
export default function UISecondaryBox({
children,
style,
cancelClicks = true,
}: {
children: ReactNode;
style?: CSSProperties;
cancelClicks?: boolean;
}) {
const computedStyle = useMemo(() => {
if (!style) {
@ -23,5 +25,12 @@ export default function UISecondaryBox({
}
return { ...baseStyle, ...style };
}, [style]);
return <div style={computedStyle}>{children}</div>;
return (
<div
style={computedStyle}
{...(cancelClicks ? { onClick: (e) => e.stopPropagation() } : {})}
>
{children}
</div>
);
}

View File

@ -1,4 +1,4 @@
import { useCallback } from 'react';
import { CSSProperties, useCallback } from 'react';
const baseStyle = {
marginTop: '0.5em',
@ -13,10 +13,12 @@ export default function UITextInput({
value,
disabled = false,
onChangeText,
style,
}: {
value: string;
disabled?: boolean;
onChangeText: (text: string) => void;
style?: CSSProperties;
}) {
const onChange = useCallback(
(e) => onChangeText(e.target.value),
@ -24,7 +26,7 @@ export default function UITextInput({
);
return (
<input
style={baseStyle}
style={style ? { ...baseStyle, ...style } : baseStyle}
value={value}
disabled={disabled}
onChange={onChange}