瀏覽代碼

Update Admin Curated Onboarding, add select-all/mass action operations

Daniel Supernault 1 年之前
父節點
當前提交
b22cac944b
共有 1 個文件被更改,包括 225 次插入0 次删除
  1. 225 0
      resources/views/admin/curated-register/index.blade.php

+ 225 - 0
resources/views/admin/curated-register/index.blade.php

@@ -20,10 +20,32 @@
         @include('admin.curated-register.partials.nav')
 
         @if($records && $records->count())
+        <div class="select-all-menu" style="display: none;">
+            <form class="form-inline" id="select-form">
+                <p class="mb-2 align-middle text-sm mr-2 font-weight-bold text-muted">Select an action:</p>
+                <label class="sr-only" for="actionInput">Action</label>
+                <select class="custom-select mb-2 mr-sm-2" id="actionInput">
+                    <option selected disabled>Select action</option>
+                    <option value="silently-reject-all" data-action="silently reject">Silently reject all</option>
+                    <option value="email-reject-all" data-action="reject all w/ email">Reject all w/ email</option>
+                    <option disabled value="">-------------------</option>
+                    <option value="request-info" data-action="request more info">Request more info</option>
+                    <option disabled value="">-------------------</option>
+                    <option value="approve-all" data-action="approve all">Approve all</option>
+                </select>
+                <button type="submit" class="btn btn-primary mb-2" id="actionInputButton" disabled>Submit</button>
+            </form>
+        </div>
         <div class="table-responsive rounded">
             <table class="table table-dark">
                 <thead class="thead-dark">
                     <tr>
+                        <th scope="col">
+                            <div class="custom-control custom-checkbox">
+                                <input type="checkbox" class="custom-control-input" id="selectall">
+                                <label class="custom-control-label" for="selectall"></label>
+                            </div>
+                        </th>
                         <th scope="col">ID</th>
                         <th scope="col">Username</th>
                         @if(in_array($filter, ['all', 'open', 'awaiting', 'responses']))
@@ -37,6 +59,12 @@
                 <tbody>
                     @foreach($records as $record)
                     <tr>
+                        <td>
+                            <div class="custom-control custom-checkbox">
+                                <input type="checkbox" class="custom-control-input account-select-check" id="r{{$record->id}}" data-id="{{$record->id}}">
+                                <label class="custom-control-label" for="r{{$record->id}}"></label>
+                            </div>
+                        </td>
                         <td class="align-middle">
                             <a href="/i/admin/curated-onboarding/show/{{$record->id}}" class="font-weight-bold">
                                 #{{ $record->id }}
@@ -84,3 +112,200 @@
 @include('admin.curated-register.partials.not-enabled')
 @endif
 @endsection
+
+@push('scripts')
+<script type="text/javascript">
+    const menu = document.querySelector(".select-all-menu");
+    const selectAll = document.getElementById("selectall");
+    const checkboxes = document.querySelectorAll(".account-select-check");
+    const form = document.getElementById('select-form');
+    const action = document.getElementById('actionInput');
+    const actionBtn = document.getElementById('actionInputButton');
+
+    action.addEventListener("change", function() {
+        if([
+            'silently-reject-all',
+            'email-reject-all',
+            'request-info',
+            'approve-all'
+        ].includes(action.value)) {
+            actionBtn.removeAttribute('disabled')
+        } else {
+            actionBtn.setAttribute('disabled', 'disabled')
+        }
+    })
+
+    selectAll.addEventListener("change", function() {
+        checkboxes.forEach(function(checkbox) {
+            checkbox.checked = selectAll.checked;
+        });
+
+        if(selectAll.checked) {
+            menu.style.display = 'block';
+        } else {
+            menu.style.display = 'none';
+        }
+    });
+
+    checkboxes.forEach(function(checkbox) {
+        checkbox.addEventListener("change", function() {
+            let count = Array.from(checkboxes).filter(cb => cb.checked).length;
+
+            if(count > 1) {
+                menu.style.display = 'block';
+            } else {
+                menu.style.display = 'none';
+            }
+        })
+    })
+
+    form.addEventListener("submit", async function(event) {
+        event.preventDefault();
+        event.currentTarget?.blur();
+
+        const messages = await axios.get('/i/admin/api/curated-onboarding/templates/get')
+        .then(res => res.data);
+
+        let action = form.actionInput.value;
+        if(action === 'Select action') {
+            return;
+        }
+
+        let actionMap = {
+            'silently-reject-all': 'silently reject all these applications?',
+            'email-reject-all': 'reject and notify applicants via email?',
+            'request-info': 'request more info from these applicants?',
+            'approve-all': 'approve all these applicants?',
+        }
+
+        let wrapper = document.createElement('div');
+        let warning = document.createElement('p');
+        warning.classList.add('text-left');
+        warning.innerHTML = 'Are you sure you want to ' + actionMap[action];
+        wrapper.appendChild(warning)
+
+        swal({
+            title: "Confirm",
+            content: wrapper,
+            icon: "warning",
+            dangerMode: true,
+            buttons: {
+                cancel: "Cancel",
+                confirm: {
+                  text: "Proceed",
+                  value: "proceed",
+                }
+            },
+        })
+        .then(res => {
+            if(res === 'proceed') {
+                const ids = Array.from(checkboxes).filter(cb => cb.checked).map(el => el.getAttribute('data-id'));
+
+                if(action === 'request-info') {
+                    let wrapper = document.createElement('div');
+                    let warning = document.createElement('p');
+                    wrapper.classList.add('list-group')
+                    warning.classList.add('text-left');
+                    warning.innerHTML = 'Select a message to send:';
+                    wrapper.appendChild(warning);
+
+                    messages.forEach(m => {
+                        let mr = document.createElement('button');
+                        mr.classList.add('list-group-item');
+                        mr.innerHTML = m.name;
+                        mr.onclick = () => {
+                            swal.close();
+                            handleRequestType(m, ids)
+                        }
+                        wrapper.appendChild(mr);
+                    })
+
+                    swal({
+                        title: "Select Message Template",
+                        content: wrapper,
+                        icon: "warning",
+                        dangerMode: true,
+                        buttons: false,
+                    })
+                    return;
+                } else {
+                    ids.reduce((promiseChain, id) => {
+                        return promiseChain
+                        .then((result) => {
+                            return handleAction(id, action);
+                        })
+                        .catch((error) => {
+                            throw error;
+                        });
+                    }, Promise.resolve())
+                    .then(() => {
+                        console.log('All requests completed successfully');
+                        window.location.reload()
+                    })
+                    .catch((error) => {
+                        swal('Error', 'An error occured, please try again later!', 'error');
+                        console.error('Promise chain failed:', error);
+                    });
+                }
+            }
+        })
+    });
+
+    function handleRequestType(type, ids) {
+        swal({
+            title: 'Confirm Message Request',
+            text: type.content,
+            icon: "warning",
+            dangerMode: true,
+            buttons: {
+                cancel: "Cancel",
+                confirm: {
+                  text: "Proceed",
+                  value: "proceed",
+                }
+            }
+        }).then(res => {
+            if(res === 'proceed') {
+                ids.reduce((promiseChain, id) => {
+                    return promiseChain
+                    .then((result) => {
+                        return handleAction(id, 'request-info', type.content);
+                    })
+                    .catch((error) => {
+                        console.error(`Error fetching data for ID ${id}:`, error);
+                        throw error;
+                    });
+                }, Promise.resolve())
+                .then(() => {
+                    console.log('All requests completed successfully');
+                    window.location.reload()
+                })
+                .catch((error) => {
+                    swal('Error', 'An error occured, please try again later!', 'error');
+                    console.error('Promise chain failed:', error);
+                });
+            } else {
+                console.log(res)
+            }
+        })
+    }
+
+    function handleAction(id, type, msg = false) {
+        if(type === 'silently-reject-all') {
+            return axios.post(`/i/admin/api/curated-onboarding/show/${id}/reject`, {
+                action: 'reject-silent'
+            })
+        } else if(type === 'email-reject-all') {
+            return axios.post(`/i/admin/api/curated-onboarding/show/${id}/reject`, {
+                action: 'reject-email'
+            })
+        } else if(type === 'approve-all') {
+            return axios.post(`/i/admin/api/curated-onboarding/show/${id}/approve`)
+        } else if(type === 'request-info') {
+            axios.post(`/i/admin/api/curated-onboarding/show/${id}/message/send`, {
+                message: msg
+            })
+        }
+    }
+</script>
+@endpush