mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-16 00:50:18 -04:00
add dialogs frfr
This commit is contained in:
parent
8ad8726780
commit
97268397d6
|
@ -84,11 +84,11 @@ export default function EventCreator({ group }: { group: IGroup }) {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UISecondaryBox style={{ textAlign: 'center' }}>
|
<UISecondaryBox style={{ textAlign: 'center', minWidth: '25rem' }}>
|
||||||
<h1 style={{ textAlign: 'center', marginBottom: '0.5rem' }}>
|
<h3 style={{ textAlign: 'center', marginBottom: '0.5rem' }}>
|
||||||
Create Event
|
Create Event
|
||||||
</h1>
|
</h3>
|
||||||
<h3 style={{ textAlign: 'center', marginTop: '0.5rem' }}>{group.name}</h3>
|
<h4 style={{ textAlign: 'center', marginTop: '0.5rem' }}>{group.name}</h4>
|
||||||
Name
|
Name
|
||||||
<UITextInput value={name} onChangeText={setName} disabled={creating} />
|
<UITextInput value={name} onChangeText={setName} disabled={creating} />
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { GroupContext } from '../Group/Group';
|
import { GroupContext } from '../Group/Group';
|
||||||
|
import UIDialogShell from '../UI/UIDialogShell';
|
||||||
import UIPressable from '../UI/UIPressable';
|
import UIPressable from '../UI/UIPressable';
|
||||||
import useToggle from '../useToggle';
|
import useToggle from '../useToggle';
|
||||||
import EventCreator from './EventCreator';
|
import EventCreator from './EventCreator';
|
||||||
|
@ -12,10 +13,9 @@ export default function EventCreatorLink() {
|
||||||
<>
|
<>
|
||||||
<UIPressable onClick={toggle}>Create Event</UIPressable>
|
<UIPressable onClick={toggle}>Create Event</UIPressable>
|
||||||
{open && (
|
{open && (
|
||||||
<>
|
<UIDialogShell onClose={toggle}>
|
||||||
<br />
|
|
||||||
<EventCreator group={group} />
|
<EventCreator group={group} />
|
||||||
</>
|
</UIDialogShell>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,7 +30,14 @@ export default function Group({ id }: { id: number }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
getGroup(id)
|
getGroup(id)
|
||||||
.then(setGroup)
|
.then((group) => {
|
||||||
|
// @ts-ignore
|
||||||
|
if ('status' in group && group.status === 'error') {
|
||||||
|
setGroup(null);
|
||||||
|
} else {
|
||||||
|
setGroup(group);
|
||||||
|
}
|
||||||
|
})
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
}, [id, setGroup]);
|
}, [id, setGroup]);
|
||||||
|
|
||||||
|
@ -54,7 +61,7 @@ export default function Group({ id }: { id: number }) {
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
minWidth: '10rem',
|
minWidth: '15rem',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h1>{group.name}</h1>
|
<h1>{group.name}</h1>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useCallback, useContext, useMemo, useState } from 'react';
|
import { useCallback, useContext, useMemo, useState } from 'react';
|
||||||
import { addGroupAdmin, removeGroupAdmin } from '../api';
|
import { addGroupAdmin, removeGroupAdmin } from '../api';
|
||||||
import { useMe } from '../hooks';
|
import { useMe } from '../hooks';
|
||||||
|
import UIDialogShell from '../UI/UIDialogShell';
|
||||||
import UIPressable from '../UI/UIPressable';
|
import UIPressable from '../UI/UIPressable';
|
||||||
import UISecondaryBox from '../UI/UISecondaryBox';
|
import UISecondaryBox from '../UI/UISecondaryBox';
|
||||||
import { GroupContext } from './Group';
|
import { GroupContext } from './Group';
|
||||||
|
@ -47,9 +48,14 @@ export default function GroupMembersLink() {
|
||||||
<>
|
<>
|
||||||
<UIPressable onClick={handleClick}>Members</UIPressable>
|
<UIPressable onClick={handleClick}>Members</UIPressable>
|
||||||
{open && (
|
{open && (
|
||||||
<>
|
<UIDialogShell onClose={() => setOpen(false)}>
|
||||||
<br />
|
<UISecondaryBox
|
||||||
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
|
style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
backgroundColor: '#fdfdfd',
|
||||||
|
}}
|
||||||
|
cancelClicks
|
||||||
|
>
|
||||||
<h3>Members</h3>
|
<h3>Members</h3>
|
||||||
|
|
||||||
{group.users.map(({ name, id }) => (
|
{group.users.map(({ name, id }) => (
|
||||||
|
@ -71,7 +77,7 @@ export default function GroupMembersLink() {
|
||||||
|
|
||||||
<GroupInviteCode />
|
<GroupInviteCode />
|
||||||
</UISecondaryBox>
|
</UISecondaryBox>
|
||||||
</>
|
</UIDialogShell>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,6 +9,8 @@ export default function GroupSettings({ group }: { group: IGroup }) {
|
||||||
const [deletionSuccessful, setDeletionSuccessful] =
|
const [deletionSuccessful, setDeletionSuccessful] =
|
||||||
useState<boolean | null>(null);
|
useState<boolean | null>(null);
|
||||||
|
|
||||||
|
const [confirmingDeletion, setConfirmingDeletion] = useState(false);
|
||||||
|
|
||||||
const onClickedDelete = useCallback(() => {
|
const onClickedDelete = useCallback(() => {
|
||||||
deleteGroup(group.id)
|
deleteGroup(group.id)
|
||||||
.then(({ status }) => {
|
.then(({ status }) => {
|
||||||
|
@ -19,12 +21,29 @@ export default function GroupSettings({ group }: { group: IGroup }) {
|
||||||
});
|
});
|
||||||
}, [group.id]);
|
}, [group.id]);
|
||||||
|
|
||||||
|
const confirmDeletion = useCallback(() => {
|
||||||
|
setConfirmingDeletion(false);
|
||||||
|
onClickedDelete();
|
||||||
|
}, [onClickedDelete]);
|
||||||
|
|
||||||
|
const cancelDeletion = useCallback(() => {
|
||||||
|
setConfirmingDeletion(false);
|
||||||
|
}, [setConfirmingDeletion]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
|
<UISecondaryBox style={{ textAlign: 'center', minWidth: '20rem' }}>
|
||||||
<h1>Settings</h1>
|
<h3>Settings</h3>
|
||||||
{deletionSuccessful !== true && (
|
{deletionSuccessful !== true &&
|
||||||
<UIPressable onClick={onClickedDelete}>Delete Group</UIPressable>
|
(confirmingDeletion ? (
|
||||||
)}
|
<>
|
||||||
|
<UIPressable onClick={confirmDeletion}>Confirm</UIPressable>
|
||||||
|
<UIPressable onClick={cancelDeletion}>Cancel</UIPressable>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<UIPressable onClick={() => setConfirmingDeletion(true)}>
|
||||||
|
Delete Group
|
||||||
|
</UIPressable>
|
||||||
|
))}
|
||||||
{deletionSuccessful !== null &&
|
{deletionSuccessful !== null &&
|
||||||
(deletionSuccessful ? (
|
(deletionSuccessful ? (
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
import UIDialogShell from '../UI/UIDialogShell';
|
||||||
import UIPressable from '../UI/UIPressable';
|
import UIPressable from '../UI/UIPressable';
|
||||||
import useToggle from '../useToggle';
|
import useToggle from '../useToggle';
|
||||||
import { GroupContext } from './Group';
|
import { GroupContext } from './Group';
|
||||||
|
@ -12,10 +13,9 @@ export default function GroupSettingsLink() {
|
||||||
<>
|
<>
|
||||||
<UIPressable onClick={toggle}>Settings</UIPressable>
|
<UIPressable onClick={toggle}>Settings</UIPressable>
|
||||||
{open && (
|
{open && (
|
||||||
<>
|
<UIDialogShell onClose={toggle}>
|
||||||
<br />
|
|
||||||
<GroupSettings group={group} />
|
<GroupSettings group={group} />
|
||||||
</>
|
</UIDialogShell>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default function GroupCreator() {
|
||||||
const buttonEnabled = name.length > 0 && !creating;
|
const buttonEnabled = name.length > 0 && !creating;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UISecondaryBox style={{ width: '100%', boxSizing: 'border-box' }}>
|
<UISecondaryBox style={{ minWidth: '25rem' }}>
|
||||||
<h3 style={{ textAlign: 'center' }}>Create Group</h3>
|
<h3 style={{ textAlign: 'center' }}>Create Group</h3>
|
||||||
Name
|
Name
|
||||||
<UITextInput onChangeText={setName} value={name} />
|
<UITextInput onChangeText={setName} value={name} />
|
||||||
|
|
|
@ -1,25 +1,20 @@
|
||||||
import GroupCreator from './GroupCreator';
|
import UIButton from '../UI/UIButton';
|
||||||
|
import UIDialogShell from '../UI/UIDialogShell';
|
||||||
import useToggle from '../useToggle';
|
import useToggle from '../useToggle';
|
||||||
|
import GroupCreator from './GroupCreator';
|
||||||
|
|
||||||
export default function GroupCreatorLink() {
|
export default function GroupCreatorLink() {
|
||||||
const [open, toggle] = useToggle(false);
|
const [open, toggle] = useToggle(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '100%', textAlign: 'center' }}>
|
<div style={{ width: '100%', textAlign: 'center' }}>
|
||||||
<div
|
<UIButton onClick={toggle} style={{ backgroundColor: '#f3f3f3' }}>
|
||||||
style={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
userSelect: 'none',
|
|
||||||
}}
|
|
||||||
onClick={toggle}
|
|
||||||
>
|
|
||||||
Create Group
|
Create Group
|
||||||
</div>
|
</UIButton>
|
||||||
{open && (
|
{open && (
|
||||||
<>
|
<UIDialogShell onClose={toggle}>
|
||||||
<br />
|
|
||||||
<GroupCreator />
|
<GroupCreator />
|
||||||
</>
|
</UIDialogShell>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { useCallback, useEffect, useState } from 'react';
|
||||||
import { joinGroup, resolveCode } from './api';
|
import { joinGroup, resolveCode } from './api';
|
||||||
import UIButton from './UI/UIButton';
|
import UIButton from './UI/UIButton';
|
||||||
import UIPressable from './UI/UIPressable';
|
import UIPressable from './UI/UIPressable';
|
||||||
import UISecondaryBox from './UI/UISecondaryBox';
|
|
||||||
import UITextInput from './UI/UITextInput';
|
import UITextInput from './UI/UITextInput';
|
||||||
import useToggle from './useToggle';
|
import useToggle from './useToggle';
|
||||||
|
|
||||||
|
@ -11,19 +10,21 @@ export type GroupPreview = {
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
function GroupJoiner() {
|
export function GroupJoiner() {
|
||||||
const [code, setCode] = useState('');
|
const [code, setCode] = useState('');
|
||||||
const [joining, setJoining] = useState(false);
|
const [joining, setJoining] = useState(false);
|
||||||
|
|
||||||
const [group, setGroup] = useState<GroupPreview | null>(null);
|
const [group, setGroup] = useState<GroupPreview | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initialCode = code;
|
if (code) {
|
||||||
resolveCode(code).then((group) => {
|
const initialCode = code;
|
||||||
if (code === initialCode) {
|
resolveCode(code).then((group) => {
|
||||||
setGroup(group);
|
if (code === initialCode) {
|
||||||
}
|
setGroup(group);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}, [code]);
|
}, [code]);
|
||||||
|
|
||||||
const join = useCallback(() => {
|
const join = useCallback(() => {
|
||||||
|
@ -44,10 +45,13 @@ function GroupJoiner() {
|
||||||
const buttonEnabled = code.length > 0 && !joining;
|
const buttonEnabled = code.length > 0 && !joining;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
<h3>Join Group</h3>
|
<span style={{ fontSize: '0.875rem' }}>Join group with code:</span>
|
||||||
Code
|
<UITextInput
|
||||||
<UITextInput value={code} onChangeText={setCode} />
|
value={code}
|
||||||
|
onChangeText={setCode}
|
||||||
|
style={{ border: '2px solid grey' }}
|
||||||
|
/>
|
||||||
{group && (
|
{group && (
|
||||||
<>
|
<>
|
||||||
<br />
|
<br />
|
||||||
|
@ -62,7 +66,7 @@ function GroupJoiner() {
|
||||||
</UIButton>
|
</UIButton>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</UISecondaryBox>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { getGroups } from '../api';
|
import { getGroups } from '../api';
|
||||||
import { IGroup } from '../types';
|
|
||||||
import GroupCreatorLink from '../GroupCreator/GroupCreatorLink';
|
import GroupCreatorLink from '../GroupCreator/GroupCreatorLink';
|
||||||
import GroupJoinerLink from '../GroupJoinerLink';
|
import { GroupJoiner } from '../GroupJoinerLink';
|
||||||
|
import { IGroup } from '../types';
|
||||||
import GroupList from './GroupList';
|
import GroupList from './GroupList';
|
||||||
|
|
||||||
export default function Groups() {
|
export default function Groups() {
|
||||||
|
@ -21,7 +21,7 @@ export default function Groups() {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h1 style={{ textAlign: 'center' }}>Groups</h1>
|
<h1 style={{ textAlign: 'center' }}>Groups</h1>
|
||||||
<GroupJoinerLink />
|
<GroupJoiner />
|
||||||
<br />
|
<br />
|
||||||
<GroupCreatorLink />
|
<GroupCreatorLink />
|
||||||
<br />
|
<br />
|
||||||
|
|
23
src/components/UI/UIDialogShell.tsx
Normal file
23
src/components/UI/UIDialogShell.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
|
@ -13,9 +13,11 @@ const baseStyle: CSSProperties = {
|
||||||
export default function UISecondaryBox({
|
export default function UISecondaryBox({
|
||||||
children,
|
children,
|
||||||
style,
|
style,
|
||||||
|
cancelClicks = true,
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
|
cancelClicks?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const computedStyle = useMemo(() => {
|
const computedStyle = useMemo(() => {
|
||||||
if (!style) {
|
if (!style) {
|
||||||
|
@ -23,5 +25,12 @@ export default function UISecondaryBox({
|
||||||
}
|
}
|
||||||
return { ...baseStyle, ...style };
|
return { ...baseStyle, ...style };
|
||||||
}, [style]);
|
}, [style]);
|
||||||
return <div style={computedStyle}>{children}</div>;
|
return (
|
||||||
|
<div
|
||||||
|
style={computedStyle}
|
||||||
|
{...(cancelClicks ? { onClick: (e) => e.stopPropagation() } : {})}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback } from 'react';
|
import { CSSProperties, useCallback } from 'react';
|
||||||
|
|
||||||
const baseStyle = {
|
const baseStyle = {
|
||||||
marginTop: '0.5em',
|
marginTop: '0.5em',
|
||||||
|
@ -13,10 +13,12 @@ export default function UITextInput({
|
||||||
value,
|
value,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
onChangeText,
|
onChangeText,
|
||||||
|
style,
|
||||||
}: {
|
}: {
|
||||||
value: string;
|
value: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onChangeText: (text: string) => void;
|
onChangeText: (text: string) => void;
|
||||||
|
style?: CSSProperties;
|
||||||
}) {
|
}) {
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(e) => onChangeText(e.target.value),
|
(e) => onChangeText(e.target.value),
|
||||||
|
@ -24,7 +26,7 @@ export default function UITextInput({
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
style={baseStyle}
|
style={style ? { ...baseStyle, ...style } : baseStyle}
|
||||||
value={value}
|
value={value}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user