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)}
+ >
);
}