memberships: modal for confirmation (#130)

* unpolished version of working modal

* separated JS script

* minor change in JS

* minor changes JS file
diff --git a/core/auth/memberships/group.html b/core/auth/memberships/group.html
index 3995fb7..42a2e38 100644
--- a/core/auth/memberships/group.html
+++ b/core/auth/memberships/group.html
@@ -27,7 +27,7 @@
     <hr class="divider">
     <form action="/group/{{ .GroupName }}/add-child-group" method="post">
         <label for="child-group">Select Child Group:</label>
-        <select id="child-group" name="child-group" required>
+        <select id="child-group" aria-label="Select" name="child-group" required>
             {{- range .AvailableGroups }}
             <option value="{{ . }}">{{ . }}</option>
             {{- end }}
@@ -44,8 +44,8 @@
         <tr>
             <td><a href="/user/{{ . }}">{{ . }}</a></td>
             <td>
-                <form action="/group/{{ $parentGroupName }}/remove-owner/{{ . }}" method="post" onsubmit="return confirm('Are you sure you want to revoke user {{ . }} ownership of the {{ $parentGroupName }} group?')">
-                    <button type="submit" class="button">Remove</button>
+                <form action="/group/{{ $parentGroupName }}/remove-owner/{{ . }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to revoke user <strong>{{ . }}</strong>'s ownership of the  <strong>{{ $parentGroupName }}</strong> group?">
+                    <button type="submit">Remove</button>
                 </form>
             </td>
         </tr>
@@ -61,7 +61,7 @@
         <tr>
             <td><a href="/user/{{ . }}">{{ . }}</a></td>
             <td>
-                <form action="/group/{{ $parentGroupName }}/remove-member/{{ . }}" method="post" onsubmit="return confirm('Are you sure you want to remove user {{ . }} user from {{ $parentGroupName }} group?')">
+                <form action="/group/{{ $parentGroupName }}/remove-member/{{ . }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove user  <strong>{{ . }}</strong> user from  <strong>{{ $parentGroupName }}</strong> group?">
                     <button type="submit" class="button">Remove</button>
                 </form>
             </td>
@@ -93,12 +93,23 @@
             <td><a href="/group/{{ .Name }}">{{ .Name }}</a></td>
             <td>{{ .Description }}</td>
             <td>
-                <form action="/group/{{ $parentGroupName }}/remove-child-group/{{ .Name }}" method="post" onsubmit="return confirm('Are you sure you want to remove group {{ .Name }} as a child of the group {{ $parentGroupName }}?')">
+                <form action="/group/{{ $parentGroupName }}/remove-child-group/{{ .Name }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove group  <strong>{{ .Name }}</strong> as a child of the group  <strong>{{ $parentGroupName }}</strong>?">
                     <button type="submit" class="button">Remove</button>
                 </form>
             </td>
         </tr>
         {{- end }}
     </table>
+    <dialog id="confirmation" close>
+        <article>
+            <h2>Confirm Your Action</h2>
+            <p id="confirmation-message">Are you sure?</p>
+            <footer>
+                <button id="cancel-button" class="secondary cancel-button">Cancel</button>
+                <button id="confirm-button">Confirm</button>
+            </footer>
+        </article>
+    </dialog>
+    <script src="/static/main.js"></script>
 </body>
 </html>
diff --git a/core/auth/memberships/static/main.js b/core/auth/memberships/static/main.js
new file mode 100644
index 0000000..e4ea2ca
--- /dev/null
+++ b/core/auth/memberships/static/main.js
@@ -0,0 +1,47 @@
+const confirmationDialog = document.getElementById("confirmation");
+const cancelButton = document.getElementById("cancel-button");
+const confirmButton = document.getElementById("confirm-button");
+
+function showConfirmationDialog(form) {
+    const message = form.dataset.confirmationMessage;
+    document.getElementById("confirmation-message").innerHTML = message;
+    confirmationDialog.showModal();
+    let confirmed;
+    let p = new Promise((resolve) => {
+        confirmed = resolve;
+    });
+    confirmButton.onclick = () => {
+        confirmed(true);
+    };
+    cancelButton.onclick = () => {
+        hideConfirmationDialog();
+        confirmed(false);
+    };
+    return p;
+}
+
+function hideConfirmationDialog() {
+    confirmationDialog.close();
+}
+
+async function handleRemoveOwnerSubmit(form) {
+    event.preventDefault();
+    return await showConfirmationDialog(form);
+}
+
+document.addEventListener("DOMContentLoaded", function () {
+    const removeOwnerForms = document.querySelectorAll(".remove-form");
+    removeOwnerForms.forEach((form) => {
+        form.addEventListener("submit", async function (event) {
+            event.preventDefault();
+            try {
+                isConfirmed = await handleRemoveOwnerSubmit(form);
+                if (isConfirmed) {
+                    form.submit();
+                }
+            } catch (error) {
+                console.error(error);
+            }
+        });
+    });
+});