Skip to content

Commit f0fd31a

Browse files
authored
Merge pull request #1870 from codidact/art/complaints
2 parents 9a59784 + 9f348b1 commit f0fd31a

64 files changed

Lines changed: 2331 additions & 59 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
window.addEventListener('DOMContentLoaded', () => {
2+
QPixel.DOM.addSelectorListener('change', 'input[name="report_type"]', ev => {
3+
const value = /** @type HTMLInputElement */(document.querySelector('input[name="report_type"]:checked')).value;
4+
document.querySelectorAll(`[data-report-type="${value}"]`).forEach(el => {
5+
el.classList.remove('hidden');
6+
el.removeAttribute('disabled');
7+
});
8+
document.querySelectorAll(`[data-report-type]:not([data-report-type="${value}"])`).forEach(el => {
9+
el.classList.add('hidden');
10+
el.setAttribute('disabled', 'disabled');
11+
});
12+
});
13+
14+
QPixel.DOM.addSelectorListener('click', '.js-reply-button', ev => {
15+
const tgt = /** @type HTMLElement */(ev.currentTarget);
16+
const internal = tgt.dataset.internal;
17+
18+
const widget = /** @type HTMLElement */(document.querySelector('.js-reply-widget'));
19+
const label = /** @type HTMLElement */(document.querySelector('.js-reply-label'));
20+
const form = /** @type HTMLFormElement */(document.querySelector('.js-reply-form'));
21+
22+
widget.classList.add('hidden');
23+
24+
if (internal === 'true') {
25+
widget.classList.add('is-yellow');
26+
label.innerText = 'Add your internal notes';
27+
}
28+
else {
29+
widget.classList.remove('is-yellow');
30+
label.innerText = 'Add your reply';
31+
}
32+
/** @type HTMLInputElement */(form.querySelector('input[name="internal"]')).value = internal;
33+
34+
widget.classList.remove('hidden');
35+
});
36+
37+
QPixel.DOM.addSelectorListener('submit', '.js-reply-form', async ev => {
38+
ev.preventDefault();
39+
40+
const tgt = /** @type HTMLFormElement */(ev.currentTarget);
41+
42+
const data = Object.fromEntries(new FormData(tgt).entries());
43+
const resp = await QPixel.fetchJSON(tgt.action, data);
44+
const json = await resp.json();
45+
QPixel.handleJSONResponse(json, () => {
46+
document.querySelector('.js-comments').insertAdjacentHTML('beforeend', json.comment);
47+
tgt.reset();
48+
tgt.querySelector('input[type="submit"]').removeAttribute('disabled');
49+
document.querySelector('.js-reply-widget').classList.add('hidden');
50+
51+
if (!json.can_add_more) {
52+
document.querySelector('.js-reply-container').remove();
53+
}
54+
});
55+
});
56+
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
@import 'variables';
2+
3+
.complaint-form, .complaints-container {
4+
label {
5+
display: block;
6+
margin-bottom: 1rem;
7+
font-weight: bold;
8+
font-size: 1.2rem;
9+
color: #222;
10+
11+
&.inline {
12+
display: inline-block;
13+
font-weight: normal;
14+
font-size: 1rem;
15+
}
16+
}
17+
18+
.form-radio-group {
19+
display: flex;
20+
margin: 0.75rem 0;
21+
justify-content: flex-start;
22+
align-items: center;
23+
24+
:first-child {
25+
margin-right: 0.5rem;
26+
}
27+
28+
label {
29+
display: block;
30+
margin: 0;
31+
font-weight: normal;
32+
font-size: 1rem;
33+
}
34+
35+
.form-caption {
36+
margin: 0;
37+
}
38+
}
39+
40+
.form-group {
41+
margin-bottom: 2rem;
42+
}
43+
44+
.hidden {
45+
display: none;
46+
}
47+
48+
[disabled] {
49+
border: 1px solid $muted-text;
50+
background: $muted-graphic;
51+
}
52+
}
53+
54+
.complaint-status-badge {
55+
display: inline-block;
56+
padding: 0.3rem;
57+
border-radius: 0.2rem;
58+
}
59+
60+
.is-lead + h1.complaint-title {
61+
margin-top: -1rem;
62+
}

app/assets/stylesheets/flags.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import 'variables';
2+
13
.flags-list-header {
24
display: flex;
35
justify-content: space-between;
@@ -9,6 +11,11 @@
911
.header--alert {
1012
min-width: 2em;
1113
padding: 0 0.5em;
14+
height: unset;
15+
16+
&.is-red {
17+
background: $danger;
18+
}
1219
}
1320
}
1421
}

app/controllers/active_storage/base_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class ActiveStorage::BaseController < ActionController::Base
22
before_action :enforce_signed_in
33
include ActiveStorage::SetCurrent
4+
45
protect_from_forgery with: :exception
56

67
self.etag_with_template_digest = false

app/controllers/application_controller.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ def verify_developer
108108
true
109109
end
110110

111+
def verify_staff
112+
if !user_signed_in? || !current_user.staff?
113+
render 'errors/not_found', layout: 'without_sidebar', status: :not_found
114+
return false
115+
end
116+
true
117+
end
118+
111119
def check_your_privilege(name, post = nil, render_error = true)
112120
unless current_user&.privilege?(name) || (current_user&.post_privilege?(name, post) if post)
113121
@privilege = Ability.find_by(name: name)
@@ -199,6 +207,10 @@ def set_globals
199207
if current_user&.admin?
200208
Rack::MiniProfiler.authorize_request
201209
end
210+
211+
if current_user&.staff?
212+
@complaints_count = Complaint.where(status: 'new').count
213+
end
202214
end
203215

204216
def setup_request_context

0 commit comments

Comments
 (0)