mirror of
https://github.com/kremalicious/umami.git
synced 2024-12-22 17:23:54 +01:00
Toast notifications.
This commit is contained in:
parent
2837251db7
commit
aec012fb79
1
assets/times.svg
Normal file
1
assets/times.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
|
After Width: | Height: | Size: 468 B |
26
components/common/Toast.js
Normal file
26
components/common/Toast.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import { useSpring, animated } from 'react-spring';
|
||||||
|
import styles from './Toast.module.css';
|
||||||
|
import Icon from 'components/common/Icon';
|
||||||
|
import Close from 'assets/times.svg';
|
||||||
|
|
||||||
|
export default function Toast({ message, timeout = 3000, onClose }) {
|
||||||
|
const props = useSpring({
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translate3d(0,0px,0)',
|
||||||
|
from: { opacity: 0, transform: 'translate3d(0,-40px,0)' },
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(onClose, timeout);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return ReactDOM.createPortal(
|
||||||
|
<animated.div className={styles.toast} style={props} onClick={onClose}>
|
||||||
|
<div className={styles.message}>{message}</div>
|
||||||
|
<Icon className={styles.close} icon={<Close />} size="small" />
|
||||||
|
</animated.div>,
|
||||||
|
document.getElementById('__modals'),
|
||||||
|
);
|
||||||
|
}
|
25
components/common/Toast.module.css
Normal file
25
components/common/Toast.module.css
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.toast {
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 300px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 16px;
|
||||||
|
color: var(--gray50);
|
||||||
|
background: var(--green400);
|
||||||
|
margin: auto;
|
||||||
|
z-index: 2;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-size: var(--font-size-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
@ -14,12 +14,14 @@ import Plus from 'assets/plus.svg';
|
|||||||
import Trash from 'assets/trash.svg';
|
import Trash from 'assets/trash.svg';
|
||||||
import Check from 'assets/check.svg';
|
import Check from 'assets/check.svg';
|
||||||
import styles from './AccountSettings.module.css';
|
import styles from './AccountSettings.module.css';
|
||||||
|
import Toast from '../common/Toast';
|
||||||
|
|
||||||
export default function AccountSettings() {
|
export default function AccountSettings() {
|
||||||
const [addAccount, setAddAccount] = useState();
|
const [addAccount, setAddAccount] = useState();
|
||||||
const [editAccount, setEditAccount] = useState();
|
const [editAccount, setEditAccount] = useState();
|
||||||
const [deleteAccount, setDeleteAccount] = useState();
|
const [deleteAccount, setDeleteAccount] = useState();
|
||||||
const [saved, setSaved] = useState(0);
|
const [saved, setSaved] = useState(0);
|
||||||
|
const [message, setMessage] = useState();
|
||||||
const { data } = useFetch(`/api/accounts`, {}, { update: [saved] });
|
const { data } = useFetch(`/api/accounts`, {}, { update: [saved] });
|
||||||
|
|
||||||
const Checkmark = ({ is_admin }) => (is_admin ? <Icon icon={<Check />} size="medium" /> : null);
|
const Checkmark = ({ is_admin }) => (is_admin ? <Icon icon={<Check />} size="medium" /> : null);
|
||||||
@ -52,6 +54,7 @@ export default function AccountSettings() {
|
|||||||
|
|
||||||
function handleSave() {
|
function handleSave() {
|
||||||
setSaved(state => state + 1);
|
setSaved(state => state + 1);
|
||||||
|
setMessage('Saved successfully.');
|
||||||
handleClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +100,7 @@ export default function AccountSettings() {
|
|||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
|
{message && <Toast message={message} onClose={() => setMessage(null)} />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,19 @@ import Button from 'components/common/Button';
|
|||||||
import ChangePasswordForm from '../forms/ChangePasswordForm';
|
import ChangePasswordForm from '../forms/ChangePasswordForm';
|
||||||
import Modal from 'components/common/Modal';
|
import Modal from 'components/common/Modal';
|
||||||
import Dots from 'assets/ellipsis-h.svg';
|
import Dots from 'assets/ellipsis-h.svg';
|
||||||
|
import Toast from '../common/Toast';
|
||||||
|
|
||||||
export default function ProfileSettings() {
|
export default function ProfileSettings() {
|
||||||
const user = useSelector(state => state.user);
|
const user = useSelector(state => state.user);
|
||||||
const [changePassword, setChangePassword] = useState(false);
|
const [changePassword, setChangePassword] = useState(false);
|
||||||
|
const [message, setMessage] = useState();
|
||||||
const { user_id } = user;
|
const { user_id } = user;
|
||||||
|
|
||||||
|
function handleSave() {
|
||||||
|
setChangePassword(false);
|
||||||
|
setMessage('Saved successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHeader>
|
<PageHeader>
|
||||||
@ -27,11 +34,12 @@ export default function ProfileSettings() {
|
|||||||
<Modal title="Change password">
|
<Modal title="Change password">
|
||||||
<ChangePasswordForm
|
<ChangePasswordForm
|
||||||
values={{ user_id }}
|
values={{ user_id }}
|
||||||
onSave={() => setChangePassword(false)}
|
onSave={handleSave}
|
||||||
onClose={() => setChangePassword(false)}
|
onClose={() => setChangePassword(false)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
|
{message && <Toast message={message} onClose={() => setMessage(null)} />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import Code from 'assets/code.svg';
|
|||||||
import Link from 'assets/link.svg';
|
import Link from 'assets/link.svg';
|
||||||
import styles from './WebsiteSettings.module.css';
|
import styles from './WebsiteSettings.module.css';
|
||||||
import useFetch from '../../hooks/useFetch';
|
import useFetch from '../../hooks/useFetch';
|
||||||
|
import Toast from '../common/Toast';
|
||||||
|
|
||||||
export default function WebsiteSettings() {
|
export default function WebsiteSettings() {
|
||||||
const [editWebsite, setEditWebsite] = useState();
|
const [editWebsite, setEditWebsite] = useState();
|
||||||
@ -25,6 +26,7 @@ export default function WebsiteSettings() {
|
|||||||
const [showCode, setShowCode] = useState();
|
const [showCode, setShowCode] = useState();
|
||||||
const [showUrl, setShowUrl] = useState();
|
const [showUrl, setShowUrl] = useState();
|
||||||
const [saved, setSaved] = useState(0);
|
const [saved, setSaved] = useState(0);
|
||||||
|
const [message, setMessage] = useState();
|
||||||
const { data } = useFetch(`/api/websites`, {}, { update: [saved] });
|
const { data } = useFetch(`/api/websites`, {}, { update: [saved] });
|
||||||
|
|
||||||
const Buttons = row => (
|
const Buttons = row => (
|
||||||
@ -66,6 +68,7 @@ export default function WebsiteSettings() {
|
|||||||
|
|
||||||
function handleSave() {
|
function handleSave() {
|
||||||
setSaved(state => state + 1);
|
setSaved(state => state + 1);
|
||||||
|
setMessage('Saved successfully.');
|
||||||
handleClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +130,7 @@ export default function WebsiteSettings() {
|
|||||||
<ShareUrlForm values={showUrl} onClose={handleClose} />
|
<ShareUrlForm values={showUrl} onClose={handleClose} />
|
||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
|
{message && <Toast message={message} onClose={() => setMessage(null)} />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user