diff --git a/src/components/Popup/Popup.module.scss b/src/components/Popup/Popup.module.scss new file mode 100644 index 0000000..3994081 --- /dev/null +++ b/src/components/Popup/Popup.module.scss @@ -0,0 +1,47 @@ +@use '@htv/ui-kit/styles/mixins'; +@use '@htv/ui-kit/styles/units'; + +.animated { +} + +.backdrop { + @include mixins.transition(backdrop-filter opacity, slow); + display: flex; + justify-content: center; + align-items: center; + + position: fixed; + + opacity: 0; + z-index: 100; + inset: 0; + margin: 0; + + &.animated { + backdrop-filter: blur(0.75rem); + opacity: 1; + } +} + +.box { + position: relative; + background-color: #272433; + + max-width: 85%; + max-height: 85%; + + padding: 2.5rem; + border-radius: 0.375rem; + + .header { + display: flex; + justify-content: space-between; + margin-bottom: 1rem; + } +} + +.button { + padding: 0.6rem 1.5rem; + text-decoration: none; + font-size: 0.9rem; +} diff --git a/src/components/Popup/index.jsx b/src/components/Popup/index.jsx new file mode 100644 index 0000000..8ab4317 --- /dev/null +++ b/src/components/Popup/index.jsx @@ -0,0 +1,75 @@ +import { FaTimes } from '@react-icons/all-files/fa/FaTimes'; +import classNames from 'classnames'; +import { useState, useEffect, useRef } from 'react'; + +import Button from '@htv/ui-kit/components/Button'; +import Text from '@htv/ui-kit/components/Text'; + +import { backdrop, box, button, header, animated } from './Popup.module.scss'; + +export default function Popup({ + description, + label, + show = false, + onClose = () => {}, +}) { + const { mounted, shown } = useMountedTransitions(show, 350); + + return ( + mounted && ( +
+
+
+ + {label} + + +
+ + {description} + +
+
+ ) + ); +} + +// TODO: Abstract this hook to be part of HTV UI-Kit +function useMountedTransitions(initState, delay) { + const [pre, setPre] = useTwoWayState(initState); + const [post, setPost] = useState(initState); + const _delay = useRef(delay); + + useEffect(() => setPre(initState), [initState]); + useEffect(() => { + const timer = window.setTimeout( + () => setPost(pre), + pre ? 0 : _delay.current, + ); + return () => window.clearTimeout(timer); + }, [pre]); + + return { + setState: setPre, + shown: pre && post, + mounted: pre || post, + }; +} + +function useTwoWayState(initState) { + const [state, setState] = useState(initState); + useEffect(() => { + if (state === initState) return; + setState(initState); + }, [state, initState]); + + return [state, setState]; +} diff --git a/src/sections/Register/index.jsx b/src/sections/Register/index.jsx index 5f8a8bd..0f4e55a 100644 --- a/src/sections/Register/index.jsx +++ b/src/sections/Register/index.jsx @@ -1,7 +1,7 @@ import { IoChevronBack } from '@react-icons/all-files/io5/IoChevronBack'; import classNames from 'classnames'; import { Link } from 'gatsby'; -import { useReducer, useEffect } from 'react'; +import { useReducer, useEffect, useState } from 'react'; import { toast } from 'react-hot-toast'; import { useMutate } from 'restful-react'; @@ -10,6 +10,7 @@ import Section from '@htv/ui-kit/components/Section'; import Text from '@htv/ui-kit/components/Text'; import Input from '../../components/Input'; +import Popup from '../../components/Popup'; import { container, section, @@ -58,6 +59,7 @@ export default function Register() { loading: 'Registering user...', success: () => { dispatch(null); + setShowPopup(true); return `Success! An email confirmation has been sent to ${input.email}`; }, error: ({ data }) => { @@ -106,6 +108,8 @@ export default function Register() { store.rePassword, ].every(Boolean); + const [showPopup, setShowPopup] = useState(false); + return (
@@ -196,6 +200,12 @@ export default function Register() {
+ setShowPopup(false)} + > ); }