464 lines
22 KiB
Text
464 lines
22 KiB
Text
<% if action_name == "show" %>
|
|
<% feedback_message_emails = @email_messages %>
|
|
<% feedback_message_notes = @notes %>
|
|
<% else %>
|
|
<% feedback_message_emails = @email_messages.select { |email| email.feedback_message_id == feedback_message.id } %>
|
|
<% feedback_message_notes = @notes.select { |note| note.noteable_id == feedback_message.id } %>
|
|
<% end %>
|
|
|
|
<details <%= "open" if action_name == "show" %> class="crayons-card" id="accordion-<%= feedback_message.id %>">
|
|
<summary class="p-5">
|
|
<span id="header<%= feedback_message.id %>">
|
|
<span id="collapse__header__link-<%= feedback_message.id %>">
|
|
Report #<%= feedback_message.id %> - Submitted: <%= time_ago_in_words feedback_message.created_at %> ago
|
|
</span>
|
|
<div class="float-right">
|
|
<span class="c-indicator c-indicator--warning crayons-subtitle-2"><%= feedback_message.category.titleize %></span>
|
|
✉️ Emails Sent: <%= feedback_message_emails.size %> |
|
|
<%= link_to "Link to Report #{feedback_message.id}", admin_report_path(feedback_message.id) %>
|
|
|
|
</div>
|
|
</span>
|
|
</summary>
|
|
<div aria-labelledby="header<%= feedback_message.id %>" data-parent="#accordion-<%= feedback_message.id %>">
|
|
<div class="crayons-card__body">
|
|
<%# report details %>
|
|
<div class="flex flex-wrap -mx-4">
|
|
<div class="w-75 max-w-75 px-4">
|
|
<h3 class="crayons-subtitle-3">
|
|
<% if feedback_message.offender %>
|
|
Reporter and Affected:
|
|
<% else %>
|
|
Reporter:
|
|
<% end %>
|
|
</h3>
|
|
<p>
|
|
<% if feedback_message.reporter_id? %>
|
|
<div class="flex flex-1 items-center">
|
|
<%= feedback_message.reporter.name %>
|
|
<a href="<%= feedback_message.reporter.path %>">@<%= feedback_message.reporter.username %></a>
|
|
<span class="fs-bold"><%= render partial: "admin/users/show/profile/status", locals: { user: feedback_message.reporter } %></span>
|
|
</div>
|
|
<% else %>
|
|
Anonymous
|
|
<% end %>
|
|
</p>
|
|
|
|
<% if feedback_message.offender %>
|
|
<h3 class="crayons-subtitle-3">
|
|
Offender:
|
|
</h3>
|
|
<p>
|
|
<div class="flex flex-1 items-center">
|
|
<%= feedback_message.offender.name %>
|
|
<a href="<%= feedback_message.offender.path %>">@<%= feedback_message.offender.username %></a>
|
|
<%= render partial: "admin/users/show/profile/status", locals: { user: feedback_message.offender } %>
|
|
</div>
|
|
</p>
|
|
<% else %>
|
|
<h3 class="crayons-subtitle-3">
|
|
Reported URL (new tab):
|
|
</h3>
|
|
<p>
|
|
<a href="<%= feedback_message.reported_url %>" target="_blank" rel="noopener"><%= feedback_message.reported_url %></a>
|
|
</p>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="w-100 max-w-100 px-4">
|
|
<% if feedback_message.offender %>
|
|
<h3 class="crayons-subtitle-3">
|
|
Message from Offender:
|
|
</h3>
|
|
<div class="reported__message">
|
|
<%= raw(feedback_message.message) %>
|
|
</div>
|
|
<% else %>
|
|
<h3 class="crayons-subtitle-3">
|
|
Message:
|
|
</h3>
|
|
<p>
|
|
<% if feedback_message.message.blank? %>
|
|
<span class="fs-italic">No message was left.</span>
|
|
<% else %>
|
|
<%= feedback_message.message %>
|
|
<% end %>
|
|
</p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<%# status %>
|
|
|
|
<div class="flex flex-wrap -mx-4 my-3">
|
|
<div class="w-100 max-w-100 px-4">
|
|
<h3 class="crayons-subtitle-2">Set Status:</h3>
|
|
|
|
<% case feedback_message.status %>
|
|
<% when 'Open' %>
|
|
<div class="flex">
|
|
<%= button_tag "✅ Resolved", type: "button", data: { status: "Resolved", id: feedback_message.id }, class: "c-btn c-btn--primary block mt-3 mr-2 status-button" %>
|
|
<%= button_tag "❌ Invalid", type: "button", data: { status: "Invalid", id: feedback_message.id }, class: "c-btn c-btn--primary block mt-3 status-button" %>
|
|
</div>
|
|
<% when 'Invalid' %>
|
|
<div class="flex">
|
|
<%= button_tag "❔ Open", type: "button", data: { status: "Open", id: feedback_message.id }, class: "c-btn c-btn--primary block mt-3 mr-2 status-button" %>
|
|
<%= button_tag "✅ Resolved", type: "button", data: { status: "Resolved", id: feedback_message.id }, class: "c-btn c-btn--primary block mt-3 status-button" %>
|
|
</div>
|
|
<% when 'Resolved' %>
|
|
<div class="flex">
|
|
<%= button_tag "❔Open", type: "button", data: { status: "Open", id: feedback_message.id }, class: "c-btn c-btn--primary block mt-3 mr-2 status-button" %>
|
|
<%= button_tag "❌ Invalid", type: "button", data: { status: "Invalid", id: feedback_message.id }, class: "c-btn c-btn--primary block mt-3 status-button" %>
|
|
</div>
|
|
<% end %>
|
|
<div class="mt-2 fs-italic hidden" id="update_message__<%= feedback_message.id %>">You have marked this as Resolved</div>
|
|
|
|
</div>
|
|
</div>
|
|
<%# emails %>
|
|
<details class="flex flex-wrap">
|
|
<summary class="py-2">
|
|
<span class="crayons-subtitle-2">
|
|
✉️ Emails Sent: <%= feedback_message_emails.size %>
|
|
</span>
|
|
</summary>
|
|
<%# previous emails %>
|
|
<div class="flex flex-wrap -mx-4">
|
|
<div class="w-100 max-w-100 px-4">
|
|
<h3 class="crayons-subtitle-2">Previous Emails:</h3>
|
|
<div class="previous__emails__container">
|
|
<% if feedback_message_emails.any? %>
|
|
<% feedback_message_emails.each do |email| %>
|
|
<div class="email__container">
|
|
<p class="to__subject">Type: <%= email.utm_campaign&.capitalize %></p>
|
|
<p class="to__subject">To: <%= email.to %></p>
|
|
<p class="to__subject">Subject: <%= email.subject %></p>
|
|
<%= email.html_content.html_safe %>
|
|
</div>
|
|
<% end %>
|
|
<% else %>
|
|
<h3 class="crayons-subtitle-2 fw-normal">No Email Records</h3>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<%# email form %>
|
|
<div class="flex flex-wrap -mx-4">
|
|
<div class="w-100 max-w-100 px-4">
|
|
<h3 class="crayons-subtitle-2">Email Form:</h3>
|
|
<ul class="crayons-navigation crayons-navigation--horizontal" role="tablist">
|
|
<li role="presentation">
|
|
<a id="tab-reporter-<%= feedback_message.id %>" class="crayons-navigation__item crayons-navigation__item--current" href="#reporter-<%= feedback_message.id %>" aria-controls="reporter-<%= feedback_message.id %>" role="tab">Reporter</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a id="tab-offender-<%= feedback_message.id %>" class="crayons-navigation__item" href="#offender-<%= feedback_message.id %>" aria-controls="offender-<%= feedback_message.id %>" role="tab">Offender</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a id="tab-affected-<%= feedback_message.id %>" class="crayons-navigation__item" href="#affected-<%= feedback_message.id %>" aria-controls="affected-<%= feedback_message.id %>" role="tab">Affected</a>
|
|
</li>
|
|
</ul>
|
|
<div class="my-3">
|
|
<div role="tabcard" class="tab-pane" data-id="<%= feedback_message.id %>" data-userType="reporter" id="reporter-<%= feedback_message.id %>">
|
|
<div class="crayons-notice crayons-notice--info" aria-live="polite">Please note that all users who report abuse receive an automatic confirmation email. You can send an additional, follow-up email to this user by using the form below.</div>
|
|
<br>
|
|
<h3 class="crayons-subtitle-2">Send To:</h3>
|
|
<%= email_field_tag :reporter_email_to, feedback_message.reporter&.email, class: "crayons-textfield my-1", id: "reporter__emailto__#{feedback_message.id}", required: true, autocomplete: "off" %>
|
|
<h3 class="crayons-subtitle-2">Subject:</h3>
|
|
<%= text_field_tag :reporter_email_subject, reporter_email_details[:subject], class: "crayons-textfield my-1", id: "reporter__subject__#{feedback_message.id}", autocomplete: "off" %>
|
|
<h3 class="crayons-subtitle-2">Body:</h3>
|
|
<%= text_area_tag :reporter_email_body, reporter_email_details[:body], class: "crayons-textfield my-1", style: "height: 300px;", id: "reporter__body__#{feedback_message.id}" %>
|
|
</div>
|
|
<div role="tabcard" class="hidden" data-id="<%= feedback_message.id %>" data-userType="offender" id="offender-<%= feedback_message.id %>">
|
|
<h3 class="crayons-subtitle-2">Send To:</h3>
|
|
<%= email_field_tag :offender_email_to, feedback_message.offender&.email, class: "crayons-textfield my-1", id: "offender__emailto__#{feedback_message.id}", required: true, autocomplete: "off" %>
|
|
<h3 class="crayons-subtitle-2">Subject:</h3>
|
|
<%= text_field_tag :offender_email_subject, offender_email_details[:subject], class: "crayons-textfield my-1", id: "offender__subject__#{feedback_message.id}", autocomplete: "off" %>
|
|
<h3 class="crayons-subtitle-2">Body:</h3>
|
|
<%= text_area_tag :offender_email_body, offender_email_details[:body], class: "crayons-textfield my-1", style: "height: 300px;", id: "offender__body__#{feedback_message.id}" %>
|
|
</div>
|
|
<div role="tabcard" class="hidden" data-id="<%= feedback_message.id %>" data-userType="affected" id="affected-<%= feedback_message.id %>">
|
|
<h3 class="crayons-subtitle-2">Send To:</h3>
|
|
<%= email_field_tag :affected_email_to, feedback_message.affected&.email, class: "crayons-textfield my-1", id: "affected__emailto__#{feedback_message.id}", required: true, autocomplete: "off" %>
|
|
<h3 class="crayons-subtitle-2">Subject:</h3>
|
|
<%= text_field_tag :affected_email_subject, affected_email_details[:subject], class: "crayons-textfield my-1", id: "affected__subject__#{feedback_message.id}", autocomplete: "off" %>
|
|
<h3 class="crayons-subtitle-2">Body:</h3>
|
|
<%= text_area_tag :affected_email_body, affected_email_details[:body], class: "crayons-textfield my-1", style: "height: 300px;", id: "affected__body__#{feedback_message.id}" %>
|
|
</div>
|
|
</div>
|
|
<button class="c-btn c-btn--primary" type="button" id="send__email__btn__<%= feedback_message.id %>">Send Email ✉️</button>
|
|
</div>
|
|
</div>
|
|
<div class="email__alert crayons-notice w-100 mt-2 hidden" id="email__alert__<%= feedback_message.id %>">
|
|
</div>
|
|
</details>
|
|
<%# notes %>
|
|
<details class="flex flex-wrap">
|
|
<summary class="py-2">
|
|
<span class="crayons-subtitle-2">
|
|
📝 Notes: <%= feedback_message_notes.size %>
|
|
</span>
|
|
</summary>
|
|
<div class="w-100 max-w-100 px-4">
|
|
<div id="notes__<%= feedback_message.id %>">
|
|
<% feedback_message_notes.each do |note| %>
|
|
<div class="notes__border my-2 p-2">
|
|
<span class="c-indicator c-indicator--info float-right">
|
|
<%= time_ago_in_words note.created_at %> ago
|
|
</span>
|
|
<h3 class="crayons-subtitle-2">
|
|
<%= note.author.name %>:
|
|
</h3>
|
|
<p>
|
|
<%= note.content %>
|
|
</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<div>
|
|
<input type="hidden" name="reason" value="<%= feedback_message.feedback_type %>" id="note__reason__<%= feedback_message.id %>">
|
|
<input type="hidden" name="noteable_id" value="<%= feedback_message.id %>" id="note__noteable-id__<%= feedback_message.id %>">
|
|
<input type="hidden" name="noteable_type" value="FeedbackMessage" id="note__noteable-type__<%= feedback_message.id %>">
|
|
<input type="hidden" name="author_id" value="<%= current_user.id %>" id="note__author-id__<%= feedback_message.id %>">
|
|
<input
|
|
type="textarea"
|
|
name="content"
|
|
placeholder="Leave some notes for the admin team about the status and context of this report."
|
|
class="notefield"
|
|
id="note__content__<%= feedback_message.id %>"
|
|
required>
|
|
<button class="c-btn c-btn--primary" type="button" id="note__submit__<%= feedback_message.id %>">Submit Note 📝</button>
|
|
<span class="fs-italic">Notes are only viewable by other admins</span>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
<div class="flex flex-wrap -mx-4">
|
|
<div class="w-100 max-w-100 px-4 flex justify-end">
|
|
<button class="c-btn c-btn--primary" type="button" id="minimize__report__button__<%= feedback_message.id %>">
|
|
Minimize Report
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
|
|
<script>
|
|
|
|
document.getElementById('tab-reporter-' + <%= feedback_message.id %>).addEventListener('click', function (event) {
|
|
event.preventDefault();
|
|
var reportId = <%= feedback_message.id %>;
|
|
showTabContent("reporter", reportId);
|
|
});
|
|
|
|
document.getElementById('tab-offender-' + <%= feedback_message.id %>).addEventListener('click', function (event) {
|
|
event.preventDefault();
|
|
var reportId = <%= feedback_message.id %>;
|
|
showTabContent("offender", reportId);
|
|
});
|
|
|
|
document.getElementById('tab-affected-' + <%= feedback_message.id %>).addEventListener('click', function (event) {
|
|
event.preventDefault();
|
|
var reportId = <%= feedback_message.id %>;
|
|
showTabContent("affected", reportId);
|
|
});
|
|
|
|
function showTabContent(tabName, reportId) {
|
|
// Make all tabs inactive
|
|
document.getElementById(`tab-reporter-${reportId}`).classList.remove("crayons-navigation__item--current");
|
|
document.getElementById(`tab-offender-${reportId}`).classList.remove("crayons-navigation__item--current");
|
|
document.getElementById(`tab-affected-${reportId}`).classList.remove("crayons-navigation__item--current");
|
|
|
|
// Hide all tab related contents
|
|
document.getElementById(`reporter-${reportId}`).classList.add("hidden");
|
|
document.getElementById(`offender-${reportId}`).classList.add("hidden");
|
|
document.getElementById(`affected-${reportId}`).classList.add("hidden");
|
|
|
|
// Remove tab-pane class from all tab contents
|
|
document.getElementById(`reporter-${reportId}`).classList.remove("tab-pane");
|
|
document.getElementById(`offender-${reportId}`).classList.remove("tab-pane");
|
|
document.getElementById(`affected-${reportId}`).classList.remove("tab-pane");
|
|
|
|
// Finally, make the tab active and its related content visible
|
|
document.getElementById(`${tabName}-${reportId}`).classList.remove("hidden");
|
|
document.getElementById(`${tabName}-${reportId}`).classList.add("tab-pane");
|
|
document.getElementById(`tab-${tabName}-${reportId}`).classList.add("crayons-navigation__item--current");
|
|
}
|
|
|
|
document.getElementById('accordion-<%= feedback_message.id %>').addEventListener('click', function(event) {
|
|
if (event.target.classList.contains('status-button')) {
|
|
var status = event.target.dataset.status;
|
|
var id = event.target.dataset.id;
|
|
saveStatus(id, status);
|
|
}
|
|
});
|
|
|
|
function saveStatus(id, status) {
|
|
var formData = new FormData();
|
|
formData.append('id', id);
|
|
formData.append('status', status); // 'Open', 'Invalid', or 'Resolved'
|
|
|
|
fetch("<%= save_status_admin_reports_path %>", {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-Token': document.querySelector("meta[name='csrf-token']").content,
|
|
},
|
|
body: formData,
|
|
credentials: 'same-origin'
|
|
})
|
|
.then(response => response.json())
|
|
.then(json => {
|
|
if (json.outcome === 'Success') {
|
|
document.getElementById('collapse__header__link-' + id).click();
|
|
document.getElementById('update_message__' + id).innerHTML = `You have marked this as ${status}`
|
|
document.getElementById('update_message__' + id).classList.remove('hidden')
|
|
} else {
|
|
console.log(json);
|
|
}
|
|
})
|
|
.catch(error => console.error('Error:', error));
|
|
}
|
|
|
|
function successfulEmail(alert) {
|
|
alert.classList.remove("hidden");
|
|
alert.classList.add('crayons-notice--success');
|
|
alert.innerHTML = "Email sent successfully! Refresh to see";
|
|
}
|
|
|
|
function failedEmail(alert) {
|
|
alert.classList.remove("hidden");
|
|
alert.classList.add('crayons-notice--danger');
|
|
alert.innerHTML = "Email failed to send, see console or Honeybadger for errors";
|
|
}
|
|
|
|
function sendEmail(id) {
|
|
// tab-pane class helps to identify the active tab.
|
|
var activeTab = document.querySelector(".tab-pane[data-id='" + id + "']");
|
|
var alert = document.getElementById('email__alert__' + id);
|
|
var sendEmailBtn = document.getElementById('send__email__btn__' + id);
|
|
var userType = activeTab.dataset.usertype;
|
|
var emailToAddress = document.getElementById(userType + "__emailto__" + id).value;
|
|
var subjectLine = document.getElementById(userType + "__subject__" + id).value;
|
|
var emailBody = document.getElementById(userType + "__body__" + id).value;
|
|
|
|
alert.classList.add("hidden");
|
|
alert.classList.remove("crayons-notice--warning");
|
|
alert.classList.remove("crayons-notice--success");
|
|
alert.classList.remove("crayons-notice--danger");
|
|
|
|
if (emailToAddress === "") {
|
|
alert.classList.remove("hidden");
|
|
alert.classList.add("crayons-notice--warning");
|
|
alert.innerHTML = "Email can't be blank!"
|
|
return
|
|
}
|
|
|
|
var formData = new FormData();
|
|
formData.append('feedback_message_id', id);
|
|
formData.append('email_to', emailToAddress);
|
|
formData.append('email_body', emailBody);
|
|
formData.append('email_subject', subjectLine);
|
|
formData.append('email_type', userType);
|
|
|
|
fetch("<%= send_email_admin_reports_path %>", {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-Token': document.querySelector("meta[name='csrf-token']").content,
|
|
},
|
|
body: formData,
|
|
credentials: 'same-origin'
|
|
})
|
|
.then(response => response.json()
|
|
.then(json => {
|
|
if (json.outcome === "Success") {
|
|
successfulEmail(alert);
|
|
} else {
|
|
console.log('email failed')
|
|
failedEmail(alert);
|
|
}
|
|
}))
|
|
.catch(error => {
|
|
failedEmail(alert);
|
|
console.log(error);
|
|
})
|
|
}
|
|
|
|
document.getElementById('send__email__btn__' + <%= feedback_message.id %>).addEventListener('click', function (event) {
|
|
event.preventDefault();
|
|
var reportId = <%= feedback_message.id %>;
|
|
sendEmail(reportId);
|
|
});
|
|
|
|
function addNoteToPage(noteParams, id) {
|
|
var notesDiv = document.getElementById('notes__' + id);
|
|
|
|
var singleNoteDiv = document.createElement('div');
|
|
singleNoteDiv.setAttribute('class', 'notes__border my-2 p-2');
|
|
|
|
var timeBadge = document.createElement('span');
|
|
timeBadge.setAttribute('class', 'c-indicator c-indicator--info float-right');
|
|
timeBadge.innerText = "just now";
|
|
singleNoteDiv.append(timeBadge);
|
|
|
|
var noteAuthor = document.createElement('H3');
|
|
noteAuthor.setAttribute('class', 'crayons-subtitle-2');
|
|
var newNote = document.createElement('p');
|
|
|
|
var authorContent = document.createTextNode(noteParams.author_name + ': ');
|
|
var noteContent = document.createTextNode(noteParams.content);
|
|
|
|
noteAuthor.appendChild(authorContent);
|
|
newNote.appendChild(noteContent);
|
|
|
|
singleNoteDiv.append(noteAuthor);
|
|
singleNoteDiv.append(newNote);
|
|
|
|
notesDiv.append(singleNoteDiv);
|
|
}
|
|
|
|
function clearNote(id) {
|
|
document.getElementById('note__content__' + id).value = '';
|
|
}
|
|
|
|
function submitNote(id) {
|
|
var submitNoteBtn = document.getElementById('note__submit__<%= feedback_message.id %>');
|
|
|
|
var formData = new FormData();
|
|
formData.append('content', document.getElementById('note__content__' + id).value)
|
|
formData.append('reason', document.getElementById('note__reason__' + id).value)
|
|
formData.append('noteable_id', document.getElementById('note__noteable-id__' + id).value)
|
|
formData.append('noteable_type', document.getElementById('note__noteable-type__' + id).value)
|
|
formData.append('author_id', document.getElementById('note__author-id__' + id).value)
|
|
|
|
fetch("<%= create_note_admin_reports_path %>", {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-Token': document.querySelector("meta[name='csrf-token']").content,
|
|
},
|
|
body: formData,
|
|
credentials: 'same-origin'
|
|
})
|
|
.then(response => response.json()
|
|
.then(json => {
|
|
if (json.outcome === 'Success') {
|
|
addNoteToPage(json, id);
|
|
clearNote(id);
|
|
} else {
|
|
// failedNote();
|
|
}
|
|
})
|
|
.catch(error => {
|
|
// failedNote();
|
|
console.log(error);
|
|
}))
|
|
}
|
|
|
|
document.getElementById('note__submit__<%= feedback_message.id %>').addEventListener('click', function () {
|
|
var reportId = <%= feedback_message.id %>;
|
|
submitNote(reportId);
|
|
});
|
|
|
|
document.getElementById('minimize__report__button__<%= feedback_message.id %>').addEventListener('click', function () {
|
|
document.getElementById('collapse__header__link-<%= feedback_message.id %>').click();
|
|
});
|
|
</script>
|