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 (
|
||||
<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 />
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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} />
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 />
|
||||
|
|
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({
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue
Block a user