Refactor/internal ui update (#5339) [deploy]
* Move internal styles out of layout * Upgrade to Bootstrap 4.4 and redo nav * Redesign /internal/users/index * Refactor /internal/tags/show * Refactor /internal/broadcasts/index * Refactor /internal/broadcasts/index * Refactor /internal/pages/index * Refactor /internal/mods/index * Fix internal nav highlighting * Refactor internal/organizations/index * Refactor internal/growth * Refactor internal/badges * Refactor /internal/podcasts/ * Refactor internal listings filter * Refactor /internal/endpoints/ * Refactor /internal/tools/ * Refactor /internal/chat_channels/ * Refactor /internal/config/ * Refactor /internal/feedback_messages This is the one that worries me the most. I made a strong effort not to touch any IDs and the JavaScript appears to be working after manual testing. This view probably needs some systems specs covering it. * Remove unused CSS * Refactor feedback_messages/show * Refactor internal/comments * Refactor internal/podcasts/edit * Refactor internal/users/show * Refactor internal/users/edit * Refactor internal/organizations/show * Refactor internal/permissions * Refactor internal/tags/show * Refactor internal/pages/form * Add events to navbar * Refactor internal/events * Refactor internal/brodcasts * Refactor internal/articles * Refactor internal/listings * Remove unused CSS * Load jquery earlier
This commit is contained in:
parent
97d188264f
commit
9652ecc456
49 changed files with 2190 additions and 1949 deletions
59
app/assets/stylesheets/internal/layout.scss
Normal file
59
app/assets/stylesheets/internal/layout.scss
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
.pagination {
|
||||
justify-content: right;
|
||||
|
||||
.page, .next, .last,
|
||||
.first, .prev {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 25% 15% 15% 15% 15% 15%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.single-internal-listing {
|
||||
border-bottom: 1px solid grey;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.buffering-area-for-single-listing {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.featured-bg {
|
||||
background: #bbffd2
|
||||
}
|
||||
|
||||
.approved-bg {
|
||||
background: #92e8ae;
|
||||
border: 12px solid #ff9900;
|
||||
}
|
||||
|
||||
.highlighted-bg {
|
||||
background: #2effa8 !important;
|
||||
border: 20px solid black;
|
||||
}
|
||||
|
||||
.submitting-no-border {
|
||||
background: #96f2cc !important;
|
||||
}
|
||||
|
||||
.highlighted-no-border {
|
||||
background: #2effa8 !important;
|
||||
}
|
||||
|
||||
.highlighted-no-border input[type="submit"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.highlighted-border {
|
||||
border: 20px solid black;
|
||||
}
|
||||
|
|
@ -2,6 +2,6 @@ class Internal::PermissionsController < Internal::ApplicationController
|
|||
layout "internal"
|
||||
|
||||
def index
|
||||
@users = User.with_role(:admin).union(User.with_role(:super_admin)).union(User.with_role(:single_resource_admin, :any))
|
||||
@users = User.with_role(:admin).union(User.with_role(:super_admin)).union(User.with_role(:single_resource_admin, :any)).page(params[:page]).per(50)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,103 +1,94 @@
|
|||
<script>
|
||||
console.log('its rendering!')
|
||||
function timeNow(objectID) {
|
||||
var seconds = new Date().getTime() / 1000;
|
||||
document.getElementById("featured_number_" + objectID).value = Math.round(seconds);
|
||||
}
|
||||
function timeNow(objectID) {
|
||||
var seconds = new Date().getTime() / 1000;
|
||||
document.getElementById("featured_number_" + objectID).value = Math.round(seconds);
|
||||
}
|
||||
|
||||
function sink(objectID) {
|
||||
var seconds = new Date().getTime() / 1080;
|
||||
document.getElementById("featured_number_" + objectID).value = Math.round(seconds);
|
||||
}
|
||||
function sink(objectID) {
|
||||
var seconds = new Date().getTime() / 1080;
|
||||
document.getElementById("featured_number_" + objectID).value = Math.round(seconds);
|
||||
}
|
||||
|
||||
function submitForms() {
|
||||
var form = $(this);
|
||||
var valuesToSubmit = $(this).serialize();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: $(this).attr('action'), //sumbits it to the given url of the form
|
||||
data: valuesToSubmit,
|
||||
// dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
|
||||
}).success(function (json) {
|
||||
console.log("success")
|
||||
form.parents(".row, .single-internal-listing").addClass("highlighted-bg")
|
||||
form.parents(".row, .single-internal-listing").addClass("highlighted-border")
|
||||
setTimeout(function () {
|
||||
form.parents(".row, .single-internal-listing").removeClass("highlighted-bg")
|
||||
}, 350)
|
||||
});
|
||||
return false; // prevents normal behaviour
|
||||
}
|
||||
window.addEventListener('load', function() {
|
||||
function submitForms() {
|
||||
var form = $(this);
|
||||
var valuesToSubmit = $(this).serialize();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: $(this).attr('action'), //sumbits it to the given url of the form
|
||||
data: valuesToSubmit,
|
||||
}).success(function (json) {
|
||||
console.log("success")
|
||||
form.parents(".card").addClass("highlighted-bg")
|
||||
form.parents(".card").addClass("highlighted-border")
|
||||
setTimeout(function () {
|
||||
form.parents(".card").removeClass("highlighted-bg")
|
||||
}, 350)
|
||||
});
|
||||
return false; // prevents normal behaviour
|
||||
}
|
||||
|
||||
$('.row').on("submit", "form", submitForms)
|
||||
$('.buffering-area-for-single-listing').on("submit", "form", submitForms)
|
||||
$('.card').on("submit", "form", submitForms)
|
||||
$('.buffer-area').on("submit", "form", submitForms)
|
||||
|
||||
$(".toggle-buffering-butt").click(function (e) {
|
||||
e.preventDefault()
|
||||
console.log($(this).closest(".single-internal-article, .buffer-area").find(".buffering-area-for-single-article, .buffering-area-for-single-listing").toggle());
|
||||
})
|
||||
imageUploadButt = document.getElementById('image-upload-button')
|
||||
imageUpload = document.getElementById('image-upload')
|
||||
imageUploadSubmit = document.getElementById('image-upload-submit')
|
||||
|
||||
imageUploadButt = document.getElementById('image-upload-button')
|
||||
imageUpload = document.getElementById('image-upload')
|
||||
imageUploadSubmit = document.getElementById('image-upload-submit')
|
||||
if (imageUploadButt && imageUpload && imageUploadSubmit) {
|
||||
imageUploadButt.onclick = function (e) {
|
||||
e.preventDefault();
|
||||
document.getElementById('image-upload').click();
|
||||
}
|
||||
imageUpload.onchange = function (e) {
|
||||
var image = document.getElementById('image-upload').files;
|
||||
if (image.length > 0) {
|
||||
document.getElementById('uploaded-image').style = 'display:none';
|
||||
document.getElementById('image-upload-submit').value = "uploading";
|
||||
setTimeout(function () {
|
||||
document.getElementById('image-upload-submit').click(function () {
|
||||
});
|
||||
}, 50)
|
||||
}
|
||||
}
|
||||
imageUploadSubmit.onclick = function (e) {
|
||||
e.preventDefault();
|
||||
var image = document.getElementById('image-upload').files;
|
||||
if (image.length > 0) {
|
||||
var ajaxReq = createAjaxReq();
|
||||
ajaxReq.onreadystatechange = uploadImageCb.bind(this, ajaxReq);
|
||||
ajaxReq.open('POST', '/image_uploads', true);
|
||||
ajaxReq.send(generateUploadFormdata(image));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imageUploadButt && imageUpload && imageUploadSubmit) {
|
||||
imageUploadButt.onclick = function (e) {
|
||||
e.preventDefault();
|
||||
document.getElementById('image-upload').click();
|
||||
}
|
||||
imageUpload.onchange = function (e) {
|
||||
var image = document.getElementById('image-upload').files;
|
||||
if (image.length > 0) {
|
||||
document.getElementById('image-upload-file-label').style = 'color:#888888';
|
||||
document.getElementById('image-upload-file-label').innerHTML = "Uploading...";
|
||||
document.getElementById('uploaded-image').style = 'display:none';
|
||||
document.getElementById('image-upload-submit').value = "uploading";
|
||||
setTimeout(function () {
|
||||
document.getElementById('image-upload-submit').click(function () {
|
||||
});
|
||||
}, 50)
|
||||
}
|
||||
}
|
||||
imageUploadSubmit.onclick = function (e) {
|
||||
e.preventDefault();
|
||||
var image = document.getElementById('image-upload').files;
|
||||
if (image.length > 0) {
|
||||
var ajaxReq = createAjaxReq();
|
||||
ajaxReq.onreadystatechange = uploadImageCb.bind(this, ajaxReq);
|
||||
ajaxReq.open('POST', '/image_uploads', true);
|
||||
ajaxReq.send(generateUploadFormdata(image));
|
||||
}
|
||||
}
|
||||
}
|
||||
function generateUploadFormdata(image) {
|
||||
var token = document.getElementsByName('authenticity_token')[0].value;
|
||||
var formData = new FormData();
|
||||
formData.append('authenticity_token', token);
|
||||
formData.append('image', image[0]);
|
||||
return formData;
|
||||
}
|
||||
|
||||
function generateUploadFormdata(image) {
|
||||
var token = document.getElementsByName('authenticity_token')[0].value;
|
||||
var formData = new FormData();
|
||||
formData.append('authenticity_token', token);
|
||||
formData.append('image', image[0]);
|
||||
return formData;
|
||||
}
|
||||
function uploadImageCb(ajaxReq) {
|
||||
if (ajaxReq.status === 200 && ajaxReq.readyState === XMLHttpRequest.DONE) {
|
||||
var address = document.getElementById('uploaded-image');
|
||||
address.value = JSON.parse(ajaxReq.response).link;
|
||||
address.style.display = "inline-block";
|
||||
address.style.width = "90%";
|
||||
address.select();
|
||||
var uploadedMessage = '';
|
||||
document.getElementById('image-upload-submit').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function uploadImageCb(ajaxReq) {
|
||||
if (ajaxReq.status === 200 && ajaxReq.readyState === XMLHttpRequest.DONE) {
|
||||
var address = document.getElementById('uploaded-image');
|
||||
address.value = JSON.parse(ajaxReq.response).link;
|
||||
address.style.display = "inline-block";
|
||||
address.style.width = "90%";
|
||||
address.select();
|
||||
var uploadedMessage = '';
|
||||
document.getElementById('image-upload-file-label').innerHTML = uploadedMessage;
|
||||
document.getElementById('image-upload-file-label').style.color = '#00c673';
|
||||
document.getElementById('image-upload-submit').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function createAjaxReq() {
|
||||
if (window.XMLHttpRequest) {
|
||||
return new XMLHttpRequest();
|
||||
} else {
|
||||
return new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
}
|
||||
function createAjaxReq() {
|
||||
if (window.XMLHttpRequest) {
|
||||
return new XMLHttpRequest();
|
||||
} else {
|
||||
return new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,24 @@
|
|||
<div class="single-internal-article">
|
||||
<% featured = article.featured ? "featured-bg" : "" %>
|
||||
<% featured = article.approved ? "approved-bg" : featured %>
|
||||
<% if article.video %>
|
||||
<h1> Contains VIDEO </h1>
|
||||
<% end %>
|
||||
<div class="row main-group <%= featured %>" style="<%= "background:red" if !article.published? && article.published_from_feed? && !article.user&.feed_admin_publish_permission? %>">
|
||||
<div class="card my-3">
|
||||
<div class="card-header">
|
||||
<a href="<%= article.path %>" target="_blank"><%= article.title %></a>
|
||||
<a class="ml-2" href="<%= article.path %>/edit" target="_blank"><span class="badge badge-success">EDIT</span></a>
|
||||
</div>
|
||||
<div class="card-body <%= "bg-danger" if !article.published? && article.published_from_feed? && !article.user&.feed_admin_publish_permission? %>">
|
||||
<% featured = article.featured ? "featured-bg" : "" %>
|
||||
<% featured = article.approved ? "approved-bg" : featured %>
|
||||
|
||||
<button class="btn btn-primary float-right" href="/internal/users/<%= article.user_id %>">Manage User</button>
|
||||
|
||||
<% if article.video %>
|
||||
<h2>Contains Video</h2>
|
||||
<% end %>
|
||||
|
||||
<% cache "internal-user-info-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %>
|
||||
|
||||
<% if article.user&.warned %>
|
||||
<h1 style="margin:0;background:orange;"> USER WARNED </h1>
|
||||
<h2><span class="badge badge-warning">USER WARNED</span></h2>
|
||||
<% end %>
|
||||
|
||||
<% if article.user&.notes&.any? %>
|
||||
<h2>User Notes (<%= article.user&.notes&.size %> total)</h2>
|
||||
<% article.user&.notes&.last(3)&.each do |note| %>
|
||||
|
|
@ -19,12 +29,12 @@
|
|||
<p><a href="/internal/users/<%= article.user_id %>">View All</a></p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<p><a href="/internal/users/<%= article.user_id %>">Manage User </a></p>
|
||||
|
||||
<% if article.published_from_feed? && !article.published? %>
|
||||
<p style="padding:5px;background:#f7ff1e;color:black;display:inline;font-weight:bold">
|
||||
<p>
|
||||
RSS Import <%= article.created_at.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<p style="font-size:0.8em;padding:5px;">
|
||||
<p>
|
||||
Originally Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
||||
</p>
|
||||
<% elsif article.crossposted_at? %>
|
||||
|
|
@ -41,121 +51,171 @@
|
|||
<img src="<%= cloud_cover_url(article.main_image) %>" style="width:100%;" alt="cover image" /><br />
|
||||
</div>
|
||||
<% end %>
|
||||
<b><a href="<%= article.path %>" target="_blank"><%= article.title %></a></b>
|
||||
<a href="<%= article.path %>/edit" target="_blank" style="background:#00da8b;color:white;padding:1px 6px">EDIT</a>
|
||||
<% article.decorate.cached_tag_list_array.each do |tag| %>
|
||||
<a href='/t/<%= tag %>'>#<%= tag %></a>
|
||||
<% end %>
|
||||
<a href="/internal/users/<%= article.user_id %>">@<%= article.user&.username %></a> ❤️ <%= article.positive_reactions_count %> | 💬 <%= article.comments_count %>
|
||||
<br /><br />
|
||||
<div class="inner-row">
|
||||
<form action="/internal/articles/<%= article.id %>" accept-charset="UTF-8" method="post">
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<h3>
|
||||
<a href="/internal/users/<%= article.user_id %>">@<%= article.user&.username %></a>
|
||||
</h3>
|
||||
<h3>
|
||||
❤️ <%= article.positive_reactions_count %> | 💬 <%= article.comments_count %>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<ul class="nav">
|
||||
<% article.decorate.cached_tag_list_array.each do |tag| %>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href='/t/<%= tag %>'>#<%= tag %></a>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<button class="btn btn-success" onclick="timeNow(<%= article.id %>);return false;">☝️ Boost!</button>
|
||||
<button class="btn btn-danger" onclick="sink(<%= article.id %>);return false;">👇 SPAM!</button>
|
||||
|
||||
<form action="/internal/articles/<%= article.id %>" accept-charset="UTF-8" method="post">
|
||||
<div class="form-group">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
||||
<input type="hidden" name="_method" value="patch" />
|
||||
Featured Number:
|
||||
<input name="article[featured_number]" value="<%= article.featured_number %>" id="featured_number_<%= article.id %>" style="max-width:140px">
|
||||
<button onclick="timeNow(<%= article.id %>);return false;">☝️</button>
|
||||
<button onclick="sink(<%= article.id %>);return false;">👇 SPAM!</button>
|
||||
Change author: <input size="6" name="article[user_id]" value="<%= article.user_id %>" />
|
||||
  Featured: <input name="article[featured]" type="checkbox" <%= "checked" if article.featured %>>
|
||||
  Approved: <input name="article[approved]" type="checkbox" <%= "checked" if article.approved %>>
|
||||
  Live Now: <input name="article[live_now]" type="checkbox" <%= "checked" if article.live_now %>>
|
||||
  Email Digest Eligible:
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="featured_number_<%= article.id %>">Featured Number:</label>
|
||||
<input id="featured_number_<%= article.id %>" class="form-control" name="article[featured_number]" value="<%= article.featured_number %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="author_id_<%= article.id %>">Author ID:</label>
|
||||
<input id="author_id_<%= article.id %>" class="form-control" size="6" name="article[user_id]" value="<%= article.user_id %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="image_bg_color_<%= article.id %>">Image BG color:</label>
|
||||
<input name="article[main_image_background_hex_color]" class="form-control" value="<%= article.main_image_background_hex_color %>" id="image_bg_color_<%= article.id %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="social_image_<%= article.id %>">Social Image:</label>
|
||||
<input name="article[social_image]" class="form-control" value="<%= article.social_image %>" id="social_image_<%= article.id %>">
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input name="article[featured]" type="checkbox" <%= "checked" if article.featured %>>
|
||||
<label>Featured</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input name="article[approved]" type="checkbox" <%= "checked" if article.approved %>>
|
||||
<label>Approved</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input name="article[live_now]" type="checkbox" <%= "checked" if article.live_now %>>
|
||||
<label>Live Now</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input name="article[email_digest_eligible]" type="checkbox" <%= "checked" if article.email_digest_eligible %>>
|
||||
  Image BG color:
|
||||
<input name="article[main_image_background_hex_color]" value="<%= article.main_image_background_hex_color %>" id="featured_number_<%= article.id %>">
|
||||
Social Image:
|
||||
<input name="article[social_image]" value="<%= article.social_image %>" id="featured_number_<%= article.id %>">
|
||||
<br /><br />
|
||||
Boosted (Additional articles):
|
||||
<label>Email Digest Eligible</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input name="article[boosted_additional_articles]" type="checkbox" <%= "checked" if article.boosted_additional_articles %>>
|
||||
  Boosted (DEV Digest):
|
||||
<label>Boosted (Additional articles)</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input name="article[boosted_dev_digest_email]" type="checkbox" <%= "checked" if article.boosted_dev_digest_email %>>
|
||||
|
||||
<% if params[:state]&.include?("classic") %>
|
||||
<br /><br />
|
||||
<textarea cols="70" rows="6" wrap="hard" name="article[body_markdown]"><%= article.body_markdown %></textarea>
|
||||
<% end %>
|
||||
 
|
||||
<% if article.last_buffered %>
|
||||
<em>Last Buffered <%= article.last_buffered %></em>
|
||||
<% else %>
|
||||
Buffered: <input name="article[last_buffered]" value="<%= Time.current %>" type="checkbox">
|
||||
<% end %>
|
||||
   
|
||||
<button class="btn btn-primary">SUBMIT</button>
|
||||
</form>
|
||||
<div>
|
||||
<% article.buffer_updates.order("created_at ASC").each do |buffer_update| %>
|
||||
<div class="row bg-warning">
|
||||
<b>
|
||||
<a href="https://buffer.com/app/profile/<%= buffer_update.buffer_profile_id_code %>/buffer/queue/list">
|
||||
<%= buffer_update.social_service_name %>
|
||||
<%= " MAIN" if buffer_update.buffer_profile_id_code == ApplicationConfig["BUFFER_TWITTER_ID"] %>
|
||||
</a>
|
||||
</b>
|
||||
<%= buffer_update.body_text %>
|
||||
<br />
|
||||
<em style="font-size:0.8em"><%= time_ago_in_words(buffer_update.created_at) %> ago</em>
|
||||
</div>
|
||||
<% end %>
|
||||
<label>Boosted (DEV Digest)</label>
|
||||
</div>
|
||||
|
||||
<% if article.boosted_dev_digest_email %>
|
||||
<br /><br />
|
||||
<% phrase = "#{article.path}?booster_org=#{article.organization&.slug || 'generic'}" %>
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).size %> EMAILS</b>
|
||||
<br />
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).where("sent_at > ?", 1.week.ago).size %> EMAILS IN THE PAST WEEK</b>
|
||||
<br /><br />
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).where.not(opened_at: nil).size %> OPENED EMAILS</b>
|
||||
<br />
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).where.not(opened_at: nil).where("sent_at > ?", 1.week.ago).size %> OPENED EMAILS IN THE PAST WEEK</b>
|
||||
<% unless article.last_buffered %>
|
||||
<div class="form-check">
|
||||
<input name="article[last_buffered]" value="<%= Time.current %>" type="checkbox">
|
||||
<label>Buffered</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if params[:state]&.include?("classic") %>
|
||||
<textarea cols="70" rows="6" wrap="hard" name="article[body_markdown]"><%= article.body_markdown %></textarea>
|
||||
<% end %>
|
||||
|
||||
<button class="btn btn-primary float-right">Submit</button>
|
||||
</form>
|
||||
|
||||
<% if article.last_buffered %>
|
||||
<div class="mt-5">
|
||||
<em>Last Buffered <%= article.last_buffered %></em>
|
||||
<% article.buffer_updates.order("created_at ASC").each do |buffer_update| %>
|
||||
<h5>
|
||||
<a href="https://buffer.com/app/profile/<%= buffer_update.buffer_profile_id_code %>/buffer/queue/list">
|
||||
<%= buffer_update.social_service_name %>
|
||||
<%= " MAIN" if buffer_update.buffer_profile_id_code == ApplicationConfig["BUFFER_TWITTER_ID"] %>
|
||||
</a>
|
||||
</h5>
|
||||
<%= time_ago_in_words(buffer_update.created_at) %> ago
|
||||
<p class="bg-warning">
|
||||
<%= buffer_update.body_text %>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if article.boosted_dev_digest_email %>
|
||||
<br /><br />
|
||||
<% phrase = "#{article.path}?booster_org=#{article.organization&.slug || 'generic'}" %>
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).size %> EMAILS</b>
|
||||
<br />
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).where("sent_at > ?", 1.week.ago).size %> EMAILS IN THE PAST WEEK</b>
|
||||
<br /><br />
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).where.not(opened_at: nil).size %> OPENED EMAILS</b>
|
||||
<br />
|
||||
<b>BOOSTED IN <%= EmailMessage.where("subject LIKE ?", "%#{phrase}%").where.not(opened_at: nil).where.not(opened_at: nil).where("sent_at > ?", 1.week.ago).size %> OPENED EMAILS IN THE PAST WEEK</b>
|
||||
<% end %>
|
||||
|
||||
<div>
|
||||
<button class="btn toggle-buffering-butt" style="margin:10px 0px;padding:10px 30px;border: 2px solid black;font-size:1.1em">
|
||||
<button class="btn btn-secondary" data-toggle="collapse" data-target="#article-<%= article.id %>-buffer-area" area-expanded="false" area-controls="article-<%= article.id %>-buffer-area">
|
||||
Share to Buffer
|
||||
</button>
|
||||
<% if (article.decorate.cached_tag_list_array & Tag.bufferized_tags).any? %>
|
||||
(Satellites Available)
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="buffering-area-for-single-article" style="display: none">
|
||||
|
||||
<div id="article-<%= article.id %>-buffer-area" class="buffering-area-for-single-article collapse">
|
||||
<% unless params[:state]&.include?("classic") %>
|
||||
<div class="row" style="font-size:15px;">
|
||||
<div class="blockquote my-2">
|
||||
<%= article.processed_html&.html_safe %>
|
||||
</div>
|
||||
<div class="flex-column" style="padding:10px;margin-top:20px;font-weight:800;">
|
||||
<div>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="main_twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Twitter MAIN</p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="255"><%= article.title %>
|
||||
<% if article.user.twitter_username? %>
{ author: @<%= article.user.twitter_username %> } #DEVCommunity<% end %></textarea>
|
||||
<button class="btn btn-info" style="font-size:1em;">🦅 Tweet to @<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %></button>
|
||||
<% end %>
|
||||
<% if (article.decorate.cached_tag_list_array & Tag.bufferized_tags).any? %>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="satellite_twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Twitter Satellite</p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="255"><%= article.title %>
|
||||
<% if article.user.twitter_username? %>
{ author: @<%= article.user.twitter_username %> }<% end %></textarea>
|
||||
<button class="btn btn-info" style="font-size:1em;">🐦 Tweet to satellites</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="facebook" />
|
||||
<input type="hidden" name="social_channel" value="main_twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Facebook & LinkedIn </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="fb_post" required></textarea>
|
||||
<button class="btn btn-info" style="font-size:1em;">📘 Post to Facebook</button>
|
||||
<h5>Twitter MAIN</h5>
|
||||
<div class="form-group">
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="255"><%= article.title %>
|
||||
<% if article.user.twitter_username? %>
{ author: @<%= article.user.twitter_username %> } #DEVCommunity<% end %>
|
||||
</textarea>
|
||||
</div>
|
||||
<button class="btn btn-primary mb-2">🦅 Tweet to @<%= ApplicationConfig["SITE_TWITTER_HANDLE"] %></button>
|
||||
<% end %>
|
||||
|
||||
<% if (article.decorate.cached_tag_list_array & Tag.bufferized_tags).any? %>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="satellite_twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<h5>Twitter Satellite</h5>
|
||||
<div class="form-group">
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="255"><%= article.title %>
|
||||
<% if article.user.twitter_username? %>
{ author: @<%= article.user.twitter_username %> }<% end %>
|
||||
</textarea>
|
||||
</div>
|
||||
<button class="btn btn-primary mb-2">🐦 Tweet to satellites</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="facebook" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<h5>Facebook & LinkedIn</h5>
|
||||
<div class="form-group">
|
||||
<textarea cols="37" rows="6" wrap="hard" name="fb_post" required>
|
||||
</textarea>
|
||||
</div>
|
||||
<button class="btn btn-primary mb-2">📘 Post to Facebook</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,98 +1,97 @@
|
|||
<style>
|
||||
.top-nav {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.top-nav a {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="editor-image-upload" style="position:fixed;top:100px;z-index:10000;padding:10px;background:white;left:0;right:0;text-align:center;border-bottom:2px solid gray">
|
||||
<input type="file" id="image-upload" name="file" accept="image/*" style="display:none">
|
||||
<button id="image-upload-button">Upload Image</button>
|
||||
<span style="width:500px;display:inline-block">
|
||||
<label id="image-upload-file-label">(or paste URL directly into Social Image input)</label>
|
||||
<div class="row">
|
||||
<div class="col-12 py-2 sticky-top bg-white d-flex justify-content-center editor-image-upload">
|
||||
<input type="file" id="image-upload" name="file" accept="image/*" style="display:none">
|
||||
<input type="submit" id='image-upload-submit' value="Upload" style="display:none">
|
||||
<input id="uploaded-image" style="display:none;width:100%;" />
|
||||
</span>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<style>.top-nav a {
|
||||
border: 1px solid #d8d8d8;
|
||||
font-weight: bold;
|
||||
margin-right: 3px;
|
||||
font-size: 0.66em
|
||||
}</style>
|
||||
<h3 class="top-nav">
|
||||
<a href="/internal/articles" class="btn <%= "btn-success" if params[:state].blank? %>">Hot</a>
|
||||
<a href="/internal/articles?state=chronological" class="btn <%= "btn-success" if params[:state] == "chronological" %>">Chronological</a>
|
||||
Not Buffered:
|
||||
<a href="/internal/articles?state=not-buffered-0.25" class="btn <%= "btn-success" if params[:state] == "not-buffered-0.25" %>">6hr</a>
|
||||
<a href="/internal/articles?state=not-buffered-1" class="btn <%= "btn-success" if params[:state] == "not-buffered-1" %>">1d</a>
|
||||
<a href="/internal/articles?state=not-buffered-7" class="btn <%= "btn-success" if params[:state] == "not-buffered-7" %>">7d</a>
|
||||
<a href="/internal/articles?state=satellite" class="btn <%= "btn-success" if params[:state] == "satellite" %>">🛰</a>
|
||||
Top:
|
||||
<a href="/internal/articles?state=top-3" class="btn <%= "btn-success" if params[:state] == "top-3" %>">3mo</a>
|
||||
<a href="/internal/articles?state=boosted-additional-articles" class="btn <%= "btn-success" if params[:state] == "boosted-additional-articles" %>">Boosted</a>
|
||||
</h3>
|
||||
<br />
|
||||
<% if params[:state] && params[:state].include?("top-") && params[:state] != "top-3" && params[:state] != "top-6" %>
|
||||
<h1 style="color:red">
|
||||
<%= params[:state] %>-months
|
||||
</h1>
|
||||
<% end %>
|
||||
<button class="btn btn-primary mr-2" id="image-upload-button">Upload Image</button>
|
||||
<input id="uploaded-image" class="form-control w-50" style="" placeholder="(or paste URL directly into Social Image input)" type="text" readonly>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<hr>
|
||||
<ul class="nav nav-pills nav-fill">
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles" class="nav-link <%= "active" if params[:state].blank? %>">Hot</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles?state=chronological" class="nav-link <%= "active" if params[:state] == "chronological" %>">Chronological</a>
|
||||
</li>
|
||||
<h3 class="mx-2">Not Buffered:</h3>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles?state=not-buffered-0.25" class="nav-link <%= "active" if params[:state] == "not-buffered-0.25" %>">6hr</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles?state=not-buffered-1" class="nav-link <%= "active" if params[:state] == "not-buffered-1" %>">1d</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles?state=not-buffered-7" class="nav-link <%= "active" if params[:state] == "not-buffered-7" %>">7d</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles?state=satellite" class="nav-link <%= "active" if params[:state] == "satellite" %>">🛰</a>
|
||||
</li>
|
||||
<h3 class="mx-2">Top:</h3>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles?state=top-3" class="nav-link <%= "active" if params[:state] == "top-3" %>">3mo</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/articles?state=boosted-additional-articles" class="nav-link <%= "active" if params[:state] == "boosted-additional-articles" %>">Boosted</a>
|
||||
</li>
|
||||
</ul>
|
||||
<% if params[:state] && params[:state].include?("top-") && params[:state] != "top-3" && params[:state] != "top-6" %>
|
||||
<h1 style="color:red">
|
||||
<%= params[:state] %>-months
|
||||
</h1>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-12 mb-2">
|
||||
<details>
|
||||
<summary style="font-size: 1.3em; cursor: pointer;">Suggested tweets (<%= @pending_buffer_updates.size %>)</summary>
|
||||
<% @pending_buffer_updates.each do |buffer_update| %>
|
||||
<% next unless buffer_update.article %>
|
||||
<div class="row">
|
||||
<h2><%= buffer_update.article.title %></h2>
|
||||
<h4>Score: <%= buffer_update.article.score %></h4>
|
||||
<hr />
|
||||
<%= HTML_Truncator.truncate(buffer_update.article.processed_html, 50, ellipsis: '<a class="comment-read-more" href="' + buffer_update.article.path + '">... Read Entire Post</a>').html_safe %>
|
||||
<hr />
|
||||
<code><b><%= Tag.find_by(id: buffer_update.tag_id)&.name || buffer_update.social_service_name %>:</b></code>
|
||||
<form action="/internal/buffer_updates/<%= buffer_update.id %>" accept-charset="UTF-8" method="post">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
||||
<input type="hidden" name="_method" value="patch" />
|
||||
<input type="hidden" name="status" value="confirmed" />
|
||||
<textarea name="body_text" style="height: 100px"><%= buffer_update.body_text %></textarea>
|
||||
<br />
|
||||
<button value="confirmed" name="status" class="btn btn-success">confirm</button>
|
||||
</form>
|
||||
<form action="/internal/buffer_updates/<%= buffer_update.id %>" accept-charset="UTF-8" method="post">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
||||
<input type="hidden" name="_method" value="patch" />
|
||||
<input type="hidden" name="status" value="dismissed" />
|
||||
<button value="dismissed" name="status" class="btn btn-danger">dismiss</button>
|
||||
</form>
|
||||
</div>
|
||||
<% end %>
|
||||
</details>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<% if @featured_articles && @featured_articles.any? %>
|
||||
<h2>Manually Featured Articles</h2>
|
||||
<% @featured_articles.each do |article| %>
|
||||
<%= render "individual_article", article: article %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h1>All Articles</h1>
|
||||
<%= paginate @articles %>
|
||||
|
||||
<details>
|
||||
<summary style="font-size: 1.3em; cursor: pointer;">Suggested tweets (<%= @pending_buffer_updates.size %>)</summary>
|
||||
<% @pending_buffer_updates.each do |buffer_update| %>
|
||||
<% next unless buffer_update.article %>
|
||||
<div class="row">
|
||||
<h2><%= buffer_update.article.title %></h2>
|
||||
<h4>Score: <%= buffer_update.article.score %></h4>
|
||||
<hr />
|
||||
<%= HTML_Truncator.truncate(buffer_update.article.processed_html, 50, ellipsis: '<a class="comment-read-more" href="' + buffer_update.article.path + '">... Read Entire Post</a>').html_safe %>
|
||||
<hr />
|
||||
<code><b><%= Tag.find_by(id: buffer_update.tag_id)&.name || buffer_update.social_service_name %>:</b></code>
|
||||
<form action="/internal/buffer_updates/<%= buffer_update.id %>" accept-charset="UTF-8" method="post">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
||||
<input type="hidden" name="_method" value="patch" />
|
||||
<input type="hidden" name="status" value="confirmed" />
|
||||
<textarea name="body_text" style="height: 100px"><%= buffer_update.body_text %></textarea>
|
||||
<br />
|
||||
<button value="confirmed" name="status" class="btn btn-success">confirm</button>
|
||||
</form>
|
||||
<form action="/internal/buffer_updates/<%= buffer_update.id %>" accept-charset="UTF-8" method="post">
|
||||
<input name="utf8" type="hidden" value="✓">
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
||||
<input type="hidden" name="_method" value="patch" />
|
||||
<input type="hidden" name="status" value="dismissed" />
|
||||
<button value="dismissed" name="status" class="btn btn-danger">dismiss</button>
|
||||
</form>
|
||||
</div>
|
||||
<% end %>
|
||||
</details>
|
||||
<% @articles.each do |article| %>
|
||||
<%= render "individual_article", article: article %>
|
||||
<% end %>
|
||||
|
||||
<% if @featured_articles && @featured_articles.any? %>
|
||||
<h1>Manually Featured Articles</h1>
|
||||
<% @featured_articles.each do |article| %>
|
||||
<%= render "individual_article", article: article %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="row" style="font-size:1.5em;border:0px">
|
||||
<h1>All Articles</h1>
|
||||
<%= paginate @articles %>
|
||||
</div>
|
||||
|
||||
<% @articles.each do |article| %>
|
||||
<%= render "individual_article", article: article %>
|
||||
<% end %>
|
||||
|
||||
<div class="row" style="font-size:1.5em;border:0px">
|
||||
<%= paginate @articles %>
|
||||
<%= paginate @articles %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "article_script" %>
|
||||
|
|
|
|||
|
|
@ -1,36 +1,18 @@
|
|||
<h1>Badges</h1>
|
||||
|
||||
<style>
|
||||
.panel-body div, .panel-body input[type=submit] {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Award Badges</div>
|
||||
<div class="panel-body">
|
||||
<%= form_with(url: internal_badges_award_badges_path, local: true) do |f| %>
|
||||
<div>
|
||||
<%= f.label :badge, "Badge" %>
|
||||
<br>
|
||||
<%= f.select("badge", @badges.map { |b| [b.title, b.slug] }) %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :usernames, "Usernames (Comma Delimited)*" %>
|
||||
<br>
|
||||
<%= f.text_area :usernames, required: true, size: "40x10" %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :message_markdown, "Override Default Message (Supports Markdown)" %>
|
||||
<br>
|
||||
<%= f.text_area :message_markdown, size: "40x10" %>
|
||||
</div>
|
||||
<%= f.submit "Award Badges" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="panel-footer"><strong>Warning: This task will fail silently when supplied with incorrect usernames!<strong></div>
|
||||
<h3>Award Badges</h3>
|
||||
<div class="alert alert-warning"><strong>Warning: This task will fail silently when supplied with incorrect usernames!<strong></div>
|
||||
<%= form_with(url: internal_badges_award_badges_path, local: true) do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label :badge, "Badge" %>
|
||||
<%= f.select("badge", @badges.map { |b| [b.title, b.slug] }, class: "form-control") %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :usernames, "Usernames (Comma Delimited)*" %>
|
||||
<%= f.text_area :usernames, required: true, size: "40x10", class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :message_markdown, "Override Default Message (Supports Markdown)" %>
|
||||
<%= f.text_area :message_markdown, size: "40x10", class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Award Badges", class: "btn btn-primary mb-4" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
<h3>Title - this for our reference only:</h3>
|
||||
<%= text_field_tag :title, @broadcast.title %>
|
||||
<hr>
|
||||
<%= label_tag :processed_html, "HTML" %>
|
||||
<br>
|
||||
<%= text_area_tag :processed_html, @broadcast.processed_html, size: "100x10" %>
|
||||
<br>
|
||||
Type: <%= select_tag "type_of", options_for_select(["Onboarding", "Announcement"]) %>
|
||||
<br>
|
||||
<%= label_tag :sent %>
|
||||
<%= select_tag :sent, options_for_select([true, false]) %>
|
||||
<div class="form-group">
|
||||
<%= label_tag :processed_html, "HTML" %>
|
||||
<%= text_area_tag :processed_html, @broadcast.processed_html, size: "100x10", class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= label_tag :type, "Type:" %>
|
||||
<%= select_tag "type_of", options_for_select(%w["Onboarding Announcement"]) %>
|
||||
</div>
|
||||
<div class="form-gorup">
|
||||
<%= label_tag :sent, "Sent:" %>
|
||||
<%= select_tag :sent, options_for_select([true, false]) %>
|
||||
</div>
|
||||
<br>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
<h1>Edit broadcast:</h1>
|
||||
<%= form_for([:internal, @broadcast], method: :patch) do %>
|
||||
<%= render "form" %>
|
||||
<%= submit_tag "Update Broadcast" %>
|
||||
<% end %>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>Edit broadcast:</h2>
|
||||
<%= form_for([:internal, @broadcast], method: :patch) do %>
|
||||
<%= render "form" %>
|
||||
<%= submit_tag "Update Broadcast", class: "btn btn-primary float-right" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,30 @@
|
|||
<a href="/internal/broadcasts/new">Make A New Broadcast</a>
|
||||
<h1>Current Broadcasts</h1>
|
||||
<div class="row justify-content-end">
|
||||
<%= link_to "Make A New Broadcast", "/internal/broadcasts/new", class: "btn btn-primary" %>
|
||||
</div>
|
||||
|
||||
<h2>Current Broadcasts</h2>
|
||||
<hr>
|
||||
<% @broadcasts.each do |broadcast| %>
|
||||
<a href="/internal/broadcasts/<%= broadcast.id %>/edit">Edit this broadcast</a>
|
||||
<br>
|
||||
<h3>Title: <%= broadcast.title %></h3>
|
||||
<h4>Broadcast Type: <%= broadcast.type_of %></h4>
|
||||
<br>
|
||||
Content:
|
||||
<br><%= broadcast.processed_html %>
|
||||
<br>
|
||||
<br>
|
||||
Sent?: <%= broadcast.sent ? "Yes" : "No" %>
|
||||
<hr>
|
||||
<% end %>
|
||||
|
||||
<div class="row">
|
||||
<div class="list-group-flush w-100">
|
||||
<% @broadcasts.each do |broadcast| %>
|
||||
<a class="list-group-item list-group-item-action flex-column align-items-start" href="/internal/broadcasts/<%= broadcast.id %>/edit">
|
||||
<h3 class="mb-2">Title: <%= broadcast.title %></h3>
|
||||
<h3>Broadcast Type: <%= broadcast.type_of %></h3>
|
||||
<h3>Content:</h3>
|
||||
<p>
|
||||
<%= broadcast.processed_html %>
|
||||
</p>
|
||||
<h3>Status:</h3>
|
||||
<h3>
|
||||
<span class="badge badge-<%= broadcast.sent ? "success" : "warning" %>">
|
||||
<%= broadcast.sent ? "Sent" : "Not Sent" %>
|
||||
</span>
|
||||
<span class="sr-only">Broadcast Status</span>
|
||||
</h3>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= csrf_meta_tags %>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
<h1>Make a new broadcast:</h1>
|
||||
<%= form_for([:internal, @broadcast], method: :post) do %>
|
||||
<%= render "form" %>
|
||||
<%= submit_tag "Create Broadcast" %>
|
||||
<% end %>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>Make a new broadcast:</h2>
|
||||
<%= form_for([:internal, @broadcast], method: :post) do %>
|
||||
<%= render "form" %>
|
||||
<%= submit_tag "Create Broadcast", class: "btn btn-primary float-right" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,44 @@
|
|||
<h1>Group Connect Channels</h1>
|
||||
<%= paginate @group_chat_channels %>
|
||||
<% @group_chat_channels.each do |channel| %>
|
||||
<div class="wrapper-3" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div><a href="/connect/<%= channel.slug %>" target="_blank"><%= channel.channel_name %></a></div>
|
||||
<div style="font-size: 0.8em;"><%= channel.users.pluck(:username).join(", ") %></div>
|
||||
<div>
|
||||
<%= form_for [:internal, channel] do |f| %>
|
||||
<%= f.text_field :usernames_string, placeholder: "Usernames to add" %>
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
</div>
|
||||
<h2>Create New Connect Channel</h2>
|
||||
<div class="row m-3">
|
||||
<div class="col">
|
||||
<%= form_for [:internal, ChatChannel.new], html: { class: "inline-form" } do |f| %>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<%= f.text_field :channel_name, placeholder: "Channel Name" %>
|
||||
<%= f.text_field :usernames_string, placeholder: "Usernames to add" %>
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h2>Group Connect Channels</h2>
|
||||
|
||||
<%= paginate @group_chat_channels %>
|
||||
|
||||
<h1>Create New Connect Channel</h1>
|
||||
<br />
|
||||
<%= form_for [:internal, ChatChannel.new] do |f| %>
|
||||
<%= f.text_field :channel_name, placeholder: "Channel Name" %>
|
||||
<%= f.text_field :usernames_string, placeholder: "Usernames to add" %>
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Users</th>
|
||||
<th scope="col">Add Users</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @group_chat_channels.each do |channel| %>
|
||||
<tr>
|
||||
<td><a href="/connect/<%= channel.slug %>" target="_blank"><%= channel.channel_name %></td>
|
||||
<td><%= channel.users.pluck(:username).join(", ") %></td>
|
||||
<td>
|
||||
<%= form_for [:internal, channel] do |f| %>
|
||||
<%= f.text_field :usernames_string, placeholder: "Usernames to add" %>
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @group_chat_channels %>
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
<a href="/internal/listings">Back to All Listings</a>
|
||||
<a class="btn btn-primary float-right" href="/internal/listings">Back to All Listings</a>
|
||||
|
||||
<h1>Edit <a href="/listings/<%= @classified_listing.category %>/<%= @classified_listing.slug %>" target="_blank">"<%= @classified_listing.title %>"</a></h1>
|
||||
<h2>Edit <a href="/listings/<%= @classified_listing.category %>/<%= @classified_listing.slug %>" target="_blank">"<%= @classified_listing.title %>"</a></h2>
|
||||
|
||||
<%= form_for [:internal, @classified_listing] do |form| %>
|
||||
<%= form.label :title %>
|
||||
<br>
|
||||
<%= form.text_field :title, size: 100, maxlength: 128 %>
|
||||
<hr>
|
||||
<%= form.label :body_markdown %>
|
||||
<br>
|
||||
<%= form.text_area :body_markdown, cols: 40, rows: 15, maxlength: 400 %>
|
||||
<hr>
|
||||
<%= form.label :tag_list %>
|
||||
<br>
|
||||
<i style="font-size: 15px;">Comma separated, one space, 8 tags max</i>
|
||||
<br>
|
||||
<%= form.text_field :tag_list, value: @classified_listing.cached_tag_list, size: 100 %>
|
||||
<hr>
|
||||
<%= form.label :category %>
|
||||
<br>
|
||||
<%= form.select :category, options_for_select(ClassifiedListing.select_options_for_categories.map(&:last), @classified_listing.category) %>
|
||||
<hr>
|
||||
<%= form.label :published %>
|
||||
<%= form.check_box :published, checked: @classified_listing.published? %>
|
||||
<hr>
|
||||
<%= form.submit "Update Listing", class: "btn btn-lg btn-primary" %>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<%= form.label :title %>
|
||||
<%= form.text_field :title, size: 100, maxlength: 128, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :body_markdown %>
|
||||
<%= form.text_area :body_markdown, cols: 40, rows: 15, maxlength: 400, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :tag_list %>
|
||||
<i style="font-size: 15px;">Comma separated, one space, 8 tags max</i>
|
||||
<%= form.text_field :tag_list, value: @classified_listing.cached_tag_list, size: 100, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :category %>
|
||||
<%= form.select :category, options_for_select(ClassifiedListing.select_options_for_categories.map(&:last), @classified_listing.category) %>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<%= form.check_box :published, checked: @classified_listing.published? %>
|
||||
<%= form.label :published %>
|
||||
</div>
|
||||
<%= form.submit "Update Listing", class: "btn btn-primary float-right" %>
|
||||
<% end %>
|
||||
<%= form_for [:internal, @classified_listing] do |f| %>
|
||||
<input type="hidden" name="classified_listing[action]" value="bump" />
|
||||
<%= f.submit "Bump Listing ⏫", class: "btn btn-lg btn-primary" %>
|
||||
<% end %>
|
||||
<hr>
|
||||
<%= link_to "Destroy Listing", url_for(action: :destroy, id: @classified_listing.id), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-danger" %>
|
||||
<br><br><br>
|
||||
<hr class="mt-5">
|
||||
<div class="d-flex justify-content-start">
|
||||
<%= form_for [:internal, @classified_listing] do |f| %>
|
||||
<input type="hidden" name="classified_listing[action]" value="bump" />
|
||||
<%= f.submit "Bump Listing ⏫", class: "btn btn-secondary" %>
|
||||
<% end %>
|
||||
<%= link_to "Destroy Listing", url_for(action: :destroy, id: @classified_listing.id), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-danger ml-2" %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,24 @@
|
|||
<h1>Classified Listings</h1>
|
||||
<%= form_tag("/internal/listings", method: "get") do %>
|
||||
<%= label_tag(:search, "Find by listing title or username:") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
<%= label_tag(:search, "Filter listings by category") %>
|
||||
<%= select_tag(:filter, options_for_select( [""] + ClassifiedListing.categories_available.keys, params[:filter])) %>
|
||||
<%= submit_tag("Search & Filter") %>
|
||||
<% end %>
|
||||
<div class="row m-3 justify-content-end">
|
||||
<div>
|
||||
<%= form_tag("/internal/listings", method: "get") do %>
|
||||
<div class="form-group">
|
||||
<%= label_tag(:search, "Keyword") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= label_tag(:filter, "Category") %>
|
||||
<%= select_tag(:filter, options_for_select([""] + ClassifiedListing.categories_available.keys, params[:filter])) %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= submit_tag("Filter") %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= paginate @classified_listings %>
|
||||
<div class="wrapper" style="border-bottom: 1px solid black">
|
||||
<div class="grid-item">Title Link</div>
|
||||
|
|
@ -32,12 +42,19 @@
|
|||
<div class="grid-item"><%= listing.published ? "Yes" : "No" %></div>
|
||||
<div class="grid-item"><%= listing.bumped_at ? time_ago_in_words(listing.bumped_at) + " ago" : "Draft" %></div>
|
||||
</div>
|
||||
|
||||
<div class="buffer-area" style="text-align: left">
|
||||
<br>
|
||||
<button class="btn toggle-buffering-butt" style="border: 1px solid grey; margin-top: 2px">Share to Buffer</button><% if listing.last_buffered.present? %> <em> Last shared: <%= listing.last_buffered.strftime("%d %B %Y") %></em><% end %>
|
||||
<br>
|
||||
<br>
|
||||
<div class="buffering-area-for-single-listing" style="display: none;">
|
||||
<button class="btn btn-secondary" data-toggle="collapse" data-target="#buffering-area-for-listing-<%= listing.id %>" aria-expanded="false" aria-controls="buffering-area-for-listing-<%= listing.id %>">
|
||||
Share to Buffer
|
||||
</button>
|
||||
|
||||
<% if listing.last_buffered.present? %>
|
||||
<em>
|
||||
Last shared: <%= listing.last_buffered.strftime("%d %B %Y") %>
|
||||
</em>
|
||||
<% end %>
|
||||
|
||||
<div id="buffering-area-for-listing-<%= listing.id %>" class="collapse buffer-area">
|
||||
<div class="grid-item">
|
||||
<p class="listing-title"><strong><%= listing.title %></strong></p>
|
||||
<p class="listing-body"><%= listing.processed_html&.html_safe %></p>
|
||||
|
|
@ -48,12 +65,14 @@
|
|||
<input type="hidden" name="listing_id" value="<%= listing.id %>" />
|
||||
<textarea cols="37" rows="8" wrap="hard" name="tweet" maxlength="255">📋 New DEV Listing!

Category: <%= listing.category %>

<%= listing.title %>

<% if listing.user.twitter_username? %>Posted by @<%= listing.user.twitter_username %><% end %></textarea>
|
||||
<br>
|
||||
<button class="btn-info tweet-listing">🐦 Tweet 🐦</button>
|
||||
<button class="btn btn-primary">🐦 Tweet 🐦</button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= paginate @classified_listings %>
|
||||
|
||||
<%= render "internal/articles/article_script" %>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,25 @@
|
|||
<div class="container-fluid">
|
||||
<h2>Comments</h2>
|
||||
<% @comments.each do |comment| %>
|
||||
<div class="row comment-row">
|
||||
<div class="inner-row col-md-8 col-md-offset-2">
|
||||
<% if comment.commentable %>
|
||||
<p class="lead">
|
||||
<strong><a href="<%= comment.commentable.path %>">re: <%= comment.commentable.title %></a> (<%= comment.positive_reactions_count %> ❤️)</strong>
|
||||
<%= paginate @comments %>
|
||||
|
||||
<% @comments.each do |comment| %>
|
||||
<div class="row my-3">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<% if comment.commentable %>
|
||||
<a href="<%= comment.commentable.path %>">re: <%= comment.commentable.title %></a> (<%= comment.positive_reactions_count %> ❤️)
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
<%= sanitize comment.processed_html.html_safe,
|
||||
tags: %w[strong em p h1 h2 h3 h4 h5 h6 i u b code pre br ul ol li small sup img a span hr blockquote],
|
||||
attributes: %w[href strong em ref rel src title alt class] %>
|
||||
|
||||
</p>
|
||||
<% end %>
|
||||
<%= sanitize comment.processed_html.html_safe,
|
||||
tags: %w(strong em p h1 h2 h3 h4 h5 h6 i u b code pre br ul ol li small sup img a span hr blockquote),
|
||||
attributes: %w(href strong em ref rel src title alt class) %>
|
||||
<div class="row">
|
||||
<div class="inner-row col-xs-8">
|
||||
<h5 class="card-title text-center">
|
||||
<% if comment.user %>
|
||||
<a href="<%= comment.user.path %>" style="color:black;" target="_blank">
|
||||
<img style="height:30px;border-radius:3px;vertical-align:-8px;" src="<%= ProfileImage.new(comment.user).get(50) %>" alt="<%= comment.user.username %> profile" /> <%= comment.user.username %>
|
||||
<a href="<%= comment.user.path %>" target="_blank">
|
||||
<img class="rounded" height="30" src="<%= ProfileImage.new(comment.user).get(50) %>" alt="<%= comment.user.username %> profile" /> <%= comment.user.username %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% if comment.user && comment.user.twitter_username.present? %>
|
||||
|
|
@ -24,28 +28,30 @@
|
|||
<i class="fa fa-twitter" aria-hidden="true"></i> @<%= comment.user.twitter_username %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="inner-row col-xs-2 col-xs-offset-0">
|
||||
<a class="btn btn-primary" href="<%= comment.path %>" target="_blank">View</a>
|
||||
</div>
|
||||
<% if comment.reactions.where(user_id: current_user.id).empty? %>
|
||||
<div class="inner-row col-xs-2 col-xs-offset-0">
|
||||
<%= form_tag("/reactions", remote: true) do %>
|
||||
<%= hidden_field_tag(:reactable_type, "Comment") %>
|
||||
<%= hidden_field_tag(:reactable_id, comment.id) %>
|
||||
<button class="btn btn-danger">❤️ Like</button>
|
||||
</h5>
|
||||
<div class="mt-3 d-flex justify-content-end">
|
||||
<a class="btn btn-primary" href="<%= comment.path %>" target="_blank">View</a>
|
||||
<% if comment.reactions.where(user_id: current_user.id).empty? %>
|
||||
<%= form_tag("/reactions", remote: true, class: "d-inline ml-2") do %>
|
||||
<%= hidden_field_tag(:reactable_type, "Comment") %>
|
||||
<%= hidden_field_tag(:reactable_id, comment.id) %>
|
||||
<button class="btn btn-danger">❤️ Like</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= paginate @comments %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= paginate @comments %>
|
||||
|
||||
<script>
|
||||
$("form").submit(function (e) {
|
||||
$(this).fadeOut();
|
||||
})
|
||||
window.addEventListener('load', function() {
|
||||
$("form").submit(function (e) {
|
||||
$(this).toggleClass("d-none");
|
||||
$(this).toggleClass("d-inline");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,9 @@
|
|||
<h1>Site configuration</h1>
|
||||
|
||||
<style>
|
||||
.panel {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.preview {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.help-block {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
</style>
|
||||
<h2>Site Configuration</h2>
|
||||
|
||||
<%= form_for(SiteConfig.new, url: internal_config_path) do |f| %>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Staff</div>
|
||||
<div class="panel-body">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">Staff</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<%= f.label :staff_user_id %>
|
||||
<%= f.number_field :staff_user_id,
|
||||
|
|
@ -25,7 +11,7 @@
|
|||
value: SiteConfig.staff_user_id,
|
||||
min: 1,
|
||||
placeholder: "1" %>
|
||||
<span class="help-block">User ID of the staff account</span>
|
||||
<div class="alert alert-info">User ID of the staff account</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -34,7 +20,7 @@
|
|||
class: "form-control",
|
||||
value: SiteConfig.default_site_email,
|
||||
placeholder: "email@staff.com" %>
|
||||
<span class="help-block">Email of the staff account</span>
|
||||
<div class="alert alert-info">Email of the staff account</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -43,50 +29,56 @@
|
|||
class: "form-control",
|
||||
value: SiteConfig.social_networks_handle,
|
||||
placeholder: "thepracticaldev" %>
|
||||
<span class="help-block">Social networks handle (eg. Twitter, GitHub)</span>
|
||||
<div class="alert alert-info">Social networks handle (eg. Twitter, GitHub)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Images</div>
|
||||
<div class="panel-body">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">Images</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<%= f.label :main_social_image %>
|
||||
<%= f.text_field :main_social_image,
|
||||
class: "form-control",
|
||||
value: SiteConfig.main_social_image,
|
||||
placeholder: "https://image.url" %>
|
||||
<span class="help-block">Used as the main image in social networks and OpenGraph</span>
|
||||
<img alt="main social image" class="preview" src="<%= SiteConfig.main_social_image %>" width="50%" />
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-12">
|
||||
<img alt="main social image" class="img-fluid" src="<%= SiteConfig.main_social_image %>" />
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="alert alert-info"><h5>Used as the main image in social networks and OpenGraph</h5></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :favicon_url %>
|
||||
<%= f.text_field :favicon_url,
|
||||
class: "form-control",
|
||||
value: SiteConfig.favicon_url,
|
||||
placeholder: "https://image.url" %>
|
||||
<span class="help-block">Used as the site favicon</span>
|
||||
<img alt="favicon" class="preview" src="<%= SiteConfig.favicon_url %>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :favicon_url %>
|
||||
<%= f.text_field :favicon_url,
|
||||
class: "form-control",
|
||||
value: SiteConfig.favicon_url,
|
||||
placeholder: "https://image.url" %>
|
||||
<div class="alert alert-info">Used as the site favicon</div>
|
||||
<img alt="favicon" class="preview" src="<%= SiteConfig.favicon_url %>" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :logo_svg %>
|
||||
<%= f.text_area :logo_svg,
|
||||
class: "form-control",
|
||||
value: SiteConfig.logo_svg,
|
||||
rows: 6,
|
||||
placeholder: "<svg ...></svg>" %>
|
||||
<span class="help-block">Used as the SVG logo of the community</span>
|
||||
<%= @logo_svg %>
|
||||
<div class="form-group">
|
||||
<%= f.label :logo_svg %>
|
||||
<%= f.text_area :logo_svg,
|
||||
class: "form-control",
|
||||
value: SiteConfig.logo_svg,
|
||||
rows: 6,
|
||||
placeholder: "<svg ...></svg>" %>
|
||||
<div class="alert alert-info">Used as the SVG logo of the community</div>
|
||||
<%= @logo_svg %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Rate limits</div>
|
||||
<div class="panel-body">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">Rate limits</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<%= f.label :rate_limit_follow_count_daily %>
|
||||
<%= f.number_field :rate_limit_follow_count_daily,
|
||||
|
|
@ -94,20 +86,20 @@
|
|||
value: SiteConfig.rate_limit_follow_count_daily,
|
||||
min: 0,
|
||||
placeholder: 500 %>
|
||||
<span class="help-block">Used to limit the amount of users a person can follow daily</span>
|
||||
<div class="alert alert-info">Used to limit the amount of users a person can follow daily</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Google Analytics Reporting API v4</div>
|
||||
<div class="panel-body">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">Google Analytics Reporting API v4</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<%= f.label :ga_view_id, "View ID" %>
|
||||
<%= f.text_field :ga_view_id,
|
||||
class: "form-control",
|
||||
value: SiteConfig.ga_view_id %>
|
||||
<span class="help-block">Google Analytics Reporting API v4 - View ID</span>
|
||||
<div class="alert alert-info">Google Analytics Reporting API v4 - View ID</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -117,20 +109,20 @@
|
|||
value: SiteConfig.ga_fetch_rate,
|
||||
min: 1,
|
||||
placeholder: 1 %>
|
||||
<span class="help-block">Determines how often the site updates its Google Analytics stats</span>
|
||||
<div class="alert alert-info">Determines how often the site updates its Google Analytics stats</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Mailchimp Lists IDs</div>
|
||||
<div class="panel-body">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">Mailchimp Lists IDs</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<%= f.label :mailchimp_newsletter_id, "Main Newsletter" %>
|
||||
<%= f.text_field :mailchimp_newsletter_id,
|
||||
class: "form-control",
|
||||
value: SiteConfig.mailchimp_newsletter_id %>
|
||||
<span class="help-block">Main Newsletter ID</span>
|
||||
<div class="alert alert-info">Main Newsletter ID</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -138,7 +130,7 @@
|
|||
<%= f.text_field :mailchimp_sustaining_members_id,
|
||||
class: "form-control",
|
||||
value: SiteConfig.mailchimp_sustaining_members_id %>
|
||||
<span class="help-block">Sustaining Members Newsletter ID</span>
|
||||
<div class="alert alert-info">Sustaining Members Newsletter ID</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -146,7 +138,7 @@
|
|||
<%= f.text_field :mailchimp_tag_moderators_id,
|
||||
class: "form-control",
|
||||
value: SiteConfig.mailchimp_tag_moderators_id %>
|
||||
<span class="help-block">Tag Moderators Newsletter ID</span>
|
||||
<div class="alert alert-info">Tag Moderators Newsletter ID</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -154,21 +146,21 @@
|
|||
<%= f.text_field :mailchimp_community_moderators_id,
|
||||
class: "form-control",
|
||||
value: SiteConfig.mailchimp_community_moderators_id %>
|
||||
<span class="help-block">Community Moderators Newsletter ID</span>
|
||||
<div class="alert alert-info">Community Moderators Newsletter ID</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Email digest frequency</div>
|
||||
<div class="panel-body">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">Email digest frequency</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<%= f.label :periodic_email_digest_max %>
|
||||
<%= f.number_field :periodic_email_digest_max,
|
||||
class: "form-control",
|
||||
value: SiteConfig.periodic_email_digest_max,
|
||||
placeholder: 0 %>
|
||||
<span class="help-block">Determines the maximum for the periodic email digest</span>
|
||||
<div class="alert alert-info">Determines the maximum for the periodic email digest</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
|
@ -177,12 +169,12 @@
|
|||
class: "form-control",
|
||||
value: SiteConfig.periodic_email_digest_min,
|
||||
placeholder: 2 %>
|
||||
<span class="help-block">Determines the mininum for the periodic email digest</span>
|
||||
<div class="alert alert-info">Determines the mininum for the periodic email digest</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.submit "Update site configuration", class: "btn btn-primary" %>
|
||||
<div class="form-group mt-3">
|
||||
<%= f.submit "Update Site Configuration", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,41 +1,51 @@
|
|||
<%= f.label :cover_image %>:
|
||||
<%= f.file_field :cover_image %>
|
||||
<br>
|
||||
<img src="<%= event.profile_image_url %>" style="width: 25%;" alt="event profile image">
|
||||
<br>
|
||||
<%= f.label :profile_image %> (for live notification):
|
||||
<%= f.file_field :profile_image %>
|
||||
<br>
|
||||
<%= f.label :title %>
|
||||
<%= f.text_field :title, maxlength: 90, size: 40, required: true %>
|
||||
<br>
|
||||
<%= f.label :host_name %>
|
||||
<%= f.text_field :host_name, size: 40, required: true %>
|
||||
<br>
|
||||
<%= f.label :category %>
|
||||
<%= f.select :category, ["AMA", "Workshop", "Talk", "Town Hall"], required: true %>
|
||||
<br>
|
||||
<%= f.label :starts_at %>
|
||||
<%= f.datetime_select :starts_at, required: true, include_blank: true, start_year: Time.current.year, end_year: Time.current.year + 2 %> UTC Time Only (4 hours ahead of eastern time)
|
||||
<br>
|
||||
<%= f.label :ends_at %>
|
||||
<%= f.datetime_select :ends_at, required: true, include_blank: true, start_year: Time.current.year, end_year: Time.current.year + 2 %> UTC Time Only (4 hours ahead of eastern time)
|
||||
<br>
|
||||
<%= f.label :location_name %>
|
||||
<%= f.text_field :location_name, required: true %>
|
||||
<br>
|
||||
<%= f.label :location_url %>
|
||||
<%= f.text_field :location_url, required: true %>
|
||||
<br>
|
||||
<%= f.label :description_markdown %>
|
||||
<br>
|
||||
<%= f.text_area :description_markdown, size: "45x10", required: true %>
|
||||
<br>
|
||||
<%= f.label :publish %>
|
||||
<%= f.check_box :published %>
|
||||
<br>
|
||||
<%= f.label :live_now %>
|
||||
<%= f.check_box :live_now %>
|
||||
<br>
|
||||
<%= f.submit %>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<%= f.label :cover_image %>:
|
||||
<%= f.file_field :cover_image, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :profile_image %> (for live notification):
|
||||
<%= f.file_field :profile_image, class: "form-control" %>
|
||||
<img src="<%= event.profile_image_url %>" style="width: 25%;" alt="event profile image">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :title %>
|
||||
<%= f.text_field :title, maxlength: 90, size: 40, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :host_name %>
|
||||
<%= f.text_field :host_name, size: 40, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :category %>
|
||||
<%= f.select :category, ["AMA", "Workshop", "Talk", "Town Hall"], required: true %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :starts_at %>
|
||||
<%= f.datetime_select :starts_at, required: true, include_blank: true, start_year: Time.current.year, end_year: Time.current.year + 2, class: "form-control" %> UTC Time Only (4 hours ahead of eastern time)
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :ends_at %>
|
||||
<%= f.datetime_select :ends_at, required: true, include_blank: true, start_year: Time.current.year, end_year: Time.current.year + 2, class: "form-control" %> UTC Time Only (4 hours ahead of eastern time)
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :location_name %>
|
||||
<%= f.text_field :location_name, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :location_url %>
|
||||
<%= f.text_field :location_url, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :description_markdown %>
|
||||
<%= f.text_area :description_markdown, size: "45x10", required: true, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :publish %>
|
||||
<%= f.check_box :published %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :live_now %>
|
||||
<%= f.check_box :live_now %>
|
||||
</div>
|
||||
<%= f.submit class: "btn btn-primary float-right my-3" %>
|
||||
|
|
|
|||
|
|
@ -1,41 +1,32 @@
|
|||
<style>
|
||||
.event-list img {
|
||||
max-width: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Create New Event</h1>
|
||||
<hr>
|
||||
|
||||
<div class="event-form">
|
||||
<%= form_for @event, url: { controller: "events", action: "create" } do |f| %>
|
||||
<%= render "event_form", f: f, event: @event %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="event-list">
|
||||
<h1> Upcoming Events </h1>
|
||||
<% @events.each do |event| %>
|
||||
<% if event.starts_at.future? %>
|
||||
<img src="<%= event.cover_image_url %>" alt="event cover image">
|
||||
<div class="event-form">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>Create New Event</h2>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<%= form_for @event, url: { controller: "events", action: "create" } do |f| %>
|
||||
<%= render "event_form", f: f, event: @event %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h2> Upcoming Events </h2>
|
||||
<% @events.each do |event| %>
|
||||
<% if event.starts_at.future? %>
|
||||
<img src="<%= event.cover_image_url %>" alt="event cover image">
|
||||
<%= form_for [:internal, event] do |f| %>
|
||||
<%= render "event_form", f: f, event: event %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<br>
|
||||
<h1> Past Events </h1>
|
||||
<% @events.each do |event| %>
|
||||
<% if !event.starts_at.future? %>
|
||||
<img src="<%= event.cover_image_url %>" alt="event cover image">
|
||||
<div class="event-form">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h2> Past Events </h2>
|
||||
<% @events.each do |event| %>
|
||||
<% if !event.starts_at.future? %>
|
||||
<img src="<%= event.cover_image_url %>" alt="event cover image">
|
||||
<%= form_for [:internal, event] do |f| %>
|
||||
<%= render "event_form", f: f, event: event %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<br>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,316 +3,349 @@
|
|||
<% else %>
|
||||
<% feedback_message_emails = @email_messages.select { |email| email.feedback_message_id == feedback_message.id } %>
|
||||
<% end %>
|
||||
<div class="panel-group" id="accordion-<%= feedback_message.id %>" role="tablist" aria-multiselectable="true">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="heading<%= feedback_message.id %>">
|
||||
<h2 class="panel-title">
|
||||
<a id="collapse__header__link-<%= feedback_message.id %>" href="#collapse<%= feedback_message.id %>" role="button" data-toggle="collapse" data-parent="#accordion" aria-expanded="true" aria-controls="collapse<%= feedback_message.id %>">
|
||||
Report #<%= feedback_message.id %> - Submitted: <%= time_ago_in_words feedback_message.created_at %> ago
|
||||
</a>
|
||||
<div class="panel-right-elements">
|
||||
✉️ Emails Sent: <%= feedback_message_emails.size %> |
|
||||
<a href="/internal/reports/<%= feedback_message.id %>">Link to Report #<%= feedback_message.id %></a>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<div class="row my-3" id="accordion-<%= feedback_message.id %>">
|
||||
<div class="card w-100">
|
||||
<div class="card-header" id="header<%= feedback_message.id %>">
|
||||
<a href="#" id="collapse__header__link-<%= feedback_message.id %>" data-toggle="collapse" data-target="#collapse<%= feedback_message.id %>" aria-expanded="true" aria-controls="collapse<%= feedback_message.id %>">
|
||||
Report #<%= feedback_message.id %> - Submitted: <%= time_ago_in_words feedback_message.created_at %> ago
|
||||
</a>
|
||||
<div class="float-right">
|
||||
✉️ Emails Sent: <%= feedback_message_emails.size %> |
|
||||
<a href="/internal/reports/<%= feedback_message.id %>">Link to Report #<%= feedback_message.id %></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-collapse collapse in" id="collapse<%= feedback_message.id %>" role="tabpanel" aria-labelledby="heading">
|
||||
<div class="panel-body">
|
||||
<h2>
|
||||
Reporter:
|
||||
<% if feedback_message.reporter_id? %>
|
||||
<%= feedback_message.reporter.name %>
|
||||
<a href="<%= feedback_message.reporter.path %>">@<%= feedback_message.reporter.username %></a>
|
||||
<% else %>
|
||||
Anonymous
|
||||
<% end %>
|
||||
</h2>
|
||||
<h3>
|
||||
Reported URL (new tab):
|
||||
<br>
|
||||
<a href="<%= feedback_message.reported_url %>" target="_blank"><%= feedback_message.reported_url %></a>
|
||||
</h3>
|
||||
<h3>Category: <%= feedback_message.category %></h3>
|
||||
<h3>
|
||||
Message:
|
||||
</h3>
|
||||
<p>
|
||||
<% if feedback_message.message.blank? %>
|
||||
<span class="blankmessage">No message was left.</span>
|
||||
<% else %>
|
||||
<%= feedback_message.message %>
|
||||
<% end %>
|
||||
</p>
|
||||
<div id="collapse<%= feedback_message.id %>" class="collapse show" aria-labelledby="header<%= feedback_message.id %>" data-parent="#accordion-<%= feedback_message.id %>">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<h2>
|
||||
Reporter:
|
||||
</h2>
|
||||
<h5>
|
||||
<% if feedback_message.reporter_id? %>
|
||||
<%= feedback_message.reporter.name %>
|
||||
<a href="<%= feedback_message.reporter.path %>">@<%= feedback_message.reporter.username %></a>
|
||||
<% else %>
|
||||
Anonymous
|
||||
<% end %>
|
||||
</h5>
|
||||
<h2>
|
||||
Reported URL (new tab):
|
||||
</h2>
|
||||
<h5>
|
||||
<a href="<%= feedback_message.reported_url %>" target="_blank"><%= feedback_message.reported_url %></a>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<h3>
|
||||
<span class="badge badge-warning float-right"><%= feedback_message.category.titleize %></span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h2>
|
||||
Message:
|
||||
</h2>
|
||||
<p>
|
||||
<% if feedback_message.message.blank? %>
|
||||
<span class="font-italic">No message was left.</span>
|
||||
<% else %>
|
||||
<%= feedback_message.message %>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<h3>Previous Emails:</h3>
|
||||
<div class="previous__emails__container">
|
||||
<% 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.body_html_content.html_safe %>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>Previous Emails:</h2>
|
||||
<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.body_html_content.html_safe %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<h5>No Email Records</h5>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<h3>Email Form:</h3>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#reporter-<%= feedback_message.id %>" aria-controls="reporter-<%= feedback_message.id %>" role="tab" data-toggle="tab">Reporter</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#offender-<%= feedback_message.id %>" aria-controls="offender-<%= feedback_message.id %>" role="tab" data-toggle="tab">Offender</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#affected-<%= feedback_message.id %>" aria-controls="affected-<%= feedback_message.id %>" role="tab" data-toggle="tab">Affected</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane fade in active" data-id="<%= feedback_message.id %>" data-userType="reporter" id="reporter-<%= feedback_message.id %>">
|
||||
<h3>
|
||||
Send to:
|
||||
<br>
|
||||
<%= email_field_tag :reporter_email_to, feedback_message.reporter&.email, class: "form-control", id: "reporter__emailto__#{feedback_message.id}", required: true %>
|
||||
</h3>
|
||||
<h3>Subject:</h3>
|
||||
<%= text_field_tag :reporter_email_subject, reporter_email_details[:subject], class: "form-control", id: "reporter__subject__#{feedback_message.id}" %>
|
||||
<h3>Body:</h3>
|
||||
<%= text_area_tag :reporter_email_body, reporter_email_details[:body], class: "form-control", style: "height: 300px;", id: "reporter__body__#{feedback_message.id}" %>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" data-id="<%= feedback_message.id %>" data-userType="offender" id="offender-<%= feedback_message.id %>">
|
||||
<h3>
|
||||
Send to:
|
||||
<br>
|
||||
<%= email_field_tag :offender_email_to, feedback_message.offender&.email, class: "form-control", id: "offender__emailto__#{feedback_message.id}", required: true %>
|
||||
</h3>
|
||||
<h3>Subject:</h3>
|
||||
<%= text_field_tag :offender_email_subject, offender_email_details[:subject], class: "form-control", id: "offender__subject__#{feedback_message.id}" %>
|
||||
<h3>Body:</h3>
|
||||
<%= text_area_tag :offender_email_body, offender_email_details[:body], class: "form-control", style: "height: 300px;", id: "offender__body__#{feedback_message.id}" %>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" data-id="<%= feedback_message.id %>" data-userType="affected" id="affected-<%= feedback_message.id %>">
|
||||
<h3>
|
||||
Send to:
|
||||
<br>
|
||||
<%= email_field_tag :affected_email_to, feedback_message.affected&.email, class: "form-control", id: "affected__emailto__#{feedback_message.id}", required: true %>
|
||||
</h3>
|
||||
<h3>Subject:</h3>
|
||||
<%= text_field_tag :affected_email_subject, affected_email_details[:subject], class: "form-control", id: "affected__subject__#{feedback_message.id}" %>
|
||||
<h3>Body:</h3>
|
||||
<%= text_area_tag :affected_email_body, affected_email_details[:body], class: "form-control", style: "height: 300px;", id: "affected__body__#{feedback_message.id}" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<button class="btn btn-primary" type="button" id="send__email__btn__<%= feedback_message.id %>">SEND EMAIL ✉️</button>
|
||||
<div class="email__alert alert fade in" id="email__alert__<%= feedback_message.id %>">
|
||||
</div>
|
||||
<h3>
|
||||
Status: <%= f.select :status, %w[Open Invalid Resolved], {}, id: "status__#{feedback_message.id}" %>
|
||||
<button class="btn btn-primary" type="button" id="save__status__<%= feedback_message.id %>">SAVE STATUS</button>
|
||||
</h3>
|
||||
<h3>Notes:</h3>
|
||||
<div class="notes__container" id="notes__<%= feedback_message.id %>">
|
||||
<% feedback_message.notes&.order("created_at")&.each do |note| %>
|
||||
<div class="single__note">
|
||||
<span class="badge time__badge">
|
||||
<%= time_ago_in_words note.created_at %> ago
|
||||
</span>
|
||||
<p class="note-content">
|
||||
<%= note.author.name %>: <%= note.content %>
|
||||
</p>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>Email Form:</h2>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="nav-item">
|
||||
<a class="nav-link active" href="#reporter-<%= feedback_message.id %>" aria-controls="reporter-<%= feedback_message.id %>" role="tab" data-toggle="tab">Reporter</a>
|
||||
</li>
|
||||
<li role="presentation" class="nav-item">
|
||||
<a class="nav-link" href="#offender-<%= feedback_message.id %>" aria-controls="offender-<%= feedback_message.id %>" role="tab" data-toggle="tab">Offender</a>
|
||||
</li>
|
||||
<li role="presentation" class="nav-item">
|
||||
<a class="nav-link" href="#affected-<%= feedback_message.id %>" aria-controls="affected-<%= feedback_message.id %>" role="tab" data-toggle="tab">Affected</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content my-3">
|
||||
<div role="tabcard" class="tab-pane fade in active show" data-id="<%= feedback_message.id %>" data-userType="reporter" id="reporter-<%= feedback_message.id %>">
|
||||
<h3>Send to:</h3>
|
||||
<%= email_field_tag :reporter_email_to, feedback_message.reporter&.email, class: "form-control my-1", id: "reporter__emailto__#{feedback_message.id}", required: true %>
|
||||
<h3>Subject:</h3>
|
||||
<%= text_field_tag :reporter_email_subject, reporter_email_details[:subject], class: "form-control my-1", id: "reporter__subject__#{feedback_message.id}" %>
|
||||
<h3>Body:</h3>
|
||||
<%= text_area_tag :reporter_email_body, reporter_email_details[:body], class: "form-control my-1", style: "height: 300px;", id: "reporter__body__#{feedback_message.id}" %>
|
||||
</div>
|
||||
<div role="tabcard" class="tab-pane fade" data-id="<%= feedback_message.id %>" data-userType="offender" id="offender-<%= feedback_message.id %>">
|
||||
<h3>Send to:</h3>
|
||||
<%= email_field_tag :offender_email_to, feedback_message.offender&.email, class: "form-control my-1", id: "offender__emailto__#{feedback_message.id}", required: true %>
|
||||
<h3>Subject:</h3>
|
||||
<%= text_field_tag :offender_email_subject, offender_email_details[:subject], class: "form-control my-1", id: "offender__subject__#{feedback_message.id}" %>
|
||||
<h3>Body:</h3>
|
||||
<%= text_area_tag :offender_email_body, offender_email_details[:body], class: "form-control my-1", style: "height: 300px;", id: "offender__body__#{feedback_message.id}" %>
|
||||
</div>
|
||||
<div role="tabcard" class="tab-pane fade" data-id="<%= feedback_message.id %>" data-userType="affected" id="affected-<%= feedback_message.id %>">
|
||||
<h3>Send to:</h3>
|
||||
<%= email_field_tag :affected_email_to, feedback_message.affected&.email, class: "form-control my-1", id: "affected__emailto__#{feedback_message.id}", required: true %>
|
||||
<h3>Subject:</h3>
|
||||
<%= text_field_tag :affected_email_subject, affected_email_details[:subject], class: "form-control my-1", id: "affected__subject__#{feedback_message.id}" %>
|
||||
<h3>Body:</h3>
|
||||
<%= text_area_tag :affected_email_body, affected_email_details[:body], class: "form-control my-1", style: "height: 300px;", id: "affected__body__#{feedback_message.id}" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<button class="btn btn-primary" type="button" id="send__email__btn__<%= feedback_message.id %>">Send Email ✉️</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="email__alert alert w-100 mt-2 d-none" id="email__alert__<%= feedback_message.id %>">
|
||||
</div>
|
||||
<div class="row my-3">
|
||||
<div class="col-12">
|
||||
<h3>Status:</h3>
|
||||
<%= f.select :status, %w[Open Invalid Resolved], {}, id: "status__#{feedback_message.id}" %>
|
||||
<button class="btn btn-primary d-block mt-3" type="button" id="save__status__<%= feedback_message.id %>">Save Status</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-3">
|
||||
<div class="col-12">
|
||||
<h3>Notes:</h3>
|
||||
<div class="notes__container" id="notes__<%= feedback_message.id %>">
|
||||
<% feedback_message.notes&.order("created_at")&.each do |note| %>
|
||||
<div class="border border-info bg-light rounded my-2 p-2">
|
||||
<span class="badge badge-info float-right">
|
||||
<%= time_ago_in_words note.created_at %> ago
|
||||
</span>
|
||||
<h5 class="font-weight-bold">
|
||||
<%= note.author.name %>:
|
||||
</h5>
|
||||
<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 about the status and context of this report."
|
||||
class="notefield"
|
||||
id="note__content__<%= feedback_message.id %>"
|
||||
required>
|
||||
<button class="btn btn-primary" type="button" id="note__submit__<%= feedback_message.id %>">Submit Note 📝</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 d-flex justify-content-end">
|
||||
<button class="btn btn-primary" type="button" id="minimize__report__button__<%= feedback_message.id %>">
|
||||
Minimize Report
|
||||
</button>
|
||||
</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 about the status and context of this report."
|
||||
class="notefield"
|
||||
id="note__content__<%= feedback_message.id %>"
|
||||
required>
|
||||
<br>
|
||||
<button class="btn btn-primary" type="button" id="note__submit__<%= feedback_message.id %>">SUBMIT NOTE 📝</button>
|
||||
<br>
|
||||
<br>
|
||||
<button class="btn btn-primary" type="button" id="minimize__report__button__<%= feedback_message.id %>">
|
||||
Minimize Report
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function saveStatus(id) {
|
||||
var formData = new FormData();
|
||||
var statusSelectTag = document.getElementById('status__' + id);
|
||||
var statusBtn = document.getElementById('save__status__' + id);
|
||||
formData.append('id', id);
|
||||
formData.append('status', statusSelectTag.options[statusSelectTag.selectedIndex].value);
|
||||
function saveStatus(id) {
|
||||
var formData = new FormData();
|
||||
var statusSelectTag = document.getElementById('status__' + id);
|
||||
var statusBtn = document.getElementById('save__status__' + id);
|
||||
formData.append('id', id);
|
||||
formData.append('status', statusSelectTag.options[statusSelectTag.selectedIndex].value);
|
||||
|
||||
fetch('/internal/reports/save_status', {
|
||||
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') {
|
||||
console.log(json.outcome)
|
||||
statusBtn.innerText = "Saved!";
|
||||
setTimeout(function () {
|
||||
statusBtn.innerText = "SAVE STATUS"
|
||||
}, 1000);
|
||||
} else {
|
||||
}
|
||||
}))
|
||||
}
|
||||
fetch('/internal/reports/save_status', {
|
||||
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') {
|
||||
console.log(json.outcome)
|
||||
statusBtn.innerText = "Saved!";
|
||||
setTimeout(function () {
|
||||
statusBtn.innerText = "Save Status"
|
||||
}, 1000);
|
||||
} else {
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
document.getElementById('save__status__' + <%= feedback_message.id %>).addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
var reportId = <%= feedback_message.id %>
|
||||
saveStatus(reportId);
|
||||
});
|
||||
document.getElementById('save__status__' + <%= feedback_message.id %>).addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
var reportId = <%= feedback_message.id %>
|
||||
saveStatus(reportId);
|
||||
});
|
||||
|
||||
function successfulEmail(alert) {
|
||||
alert.style.display = 'inline-block';
|
||||
alert.classList.add('alert-success');
|
||||
alert.innerHTML = "Email sent successfully! Refresh to see";
|
||||
}
|
||||
function successfulEmail(alert) {
|
||||
alert.classList.remove("d-none");
|
||||
alert.classList.add('alert-success');
|
||||
alert.innerHTML = "Email sent successfully! Refresh to see";
|
||||
}
|
||||
|
||||
function failedEmail(alert) {
|
||||
alert.style.display = 'inline-block';
|
||||
alert.classList.add('alert-danger');
|
||||
alert.innerHTML = "Email failed to send, see console or Honeybadger for errors";
|
||||
}
|
||||
function failedEmail(alert) {
|
||||
alert.classList.remove("d-none");
|
||||
alert.classList.add('alert-danger');
|
||||
alert.innerHTML = "Email failed to send, see console or Honeybadger for errors";
|
||||
}
|
||||
|
||||
function sendEmail(id) {
|
||||
var activeTab = document.querySelector(".tab-pane.fade.in.active[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 = activeTab.querySelector("#" + userType + "__emailto__" + id).value;
|
||||
var subjectLine = activeTab.querySelector("#" + userType + "__subject__" + id).value;
|
||||
var emailBody = activeTab.querySelector("#" + userType + "__body__" + id).value;
|
||||
function sendEmail(id) {
|
||||
var activeTab = document.querySelector(".tab-pane.fade.in.active[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 = activeTab.querySelector("#" + userType + "__emailto__" + id).value;
|
||||
var subjectLine = activeTab.querySelector("#" + userType + "__subject__" + id).value;
|
||||
var emailBody = activeTab.querySelector("#" + userType + "__body__" + id).value;
|
||||
|
||||
alert.style.display = "none";
|
||||
alert.classList.remove("alert-warning");
|
||||
alert.classList.remove("alert-success");
|
||||
alert.classList.remove("alert-danger");
|
||||
alert.classList.add("d-none");
|
||||
alert.classList.remove("alert-warning");
|
||||
alert.classList.remove("alert-success");
|
||||
alert.classList.remove("alert-danger");
|
||||
|
||||
if (emailToAddress === "") {
|
||||
alert.style.display = 'inline-block';
|
||||
alert.classList.add("alert-warning");
|
||||
alert.innerHTML = "Email can't be blank!"
|
||||
return
|
||||
}
|
||||
if (emailToAddress === "") {
|
||||
alert.classList.remove("d-none");
|
||||
alert.classList.add("alert-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);
|
||||
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('/internal/reports/send_email', {
|
||||
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);
|
||||
})
|
||||
}
|
||||
fetch('/internal/reports/send_email', {
|
||||
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);
|
||||
});
|
||||
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);
|
||||
function addNoteToPage(noteParams, id) {
|
||||
var notesDiv = document.getElementById('notes__' + id);
|
||||
|
||||
var singleNoteDiv = document.createElement('div');
|
||||
singleNoteDiv.setAttribute('class', 'single__note');
|
||||
var singleNoteDiv = document.createElement('div');
|
||||
singleNoteDiv.setAttribute('class', 'border border-info bg-light rounded my-2 p-2');
|
||||
|
||||
var timeBadge = document.createElement('span');
|
||||
timeBadge.setAttribute('class', 'time__badge badge');
|
||||
timeBadge.innerText = "just now";
|
||||
singleNoteDiv.append(timeBadge);
|
||||
var timeBadge = document.createElement('span');
|
||||
timeBadge.setAttribute('class', 'badge badge-info float-right');
|
||||
timeBadge.innerText = "just now";
|
||||
singleNoteDiv.append(timeBadge);
|
||||
|
||||
var newNote = document.createElement('p');
|
||||
newNote.className = 'note-content';
|
||||
var noteContent = document.createTextNode(noteParams.author_name + ': ' + noteParams.content);
|
||||
newNote.appendChild(noteContent);
|
||||
singleNoteDiv.append(newNote);
|
||||
var noteAuthor = document.createElement('H5');
|
||||
noteAuthor.setAttribute('class', 'font-weight-bold');
|
||||
var newNote = document.createElement('p');
|
||||
|
||||
notesDiv.append(singleNoteDiv);
|
||||
}
|
||||
var authorContent = document.createTextNode(noteParams.author_name + ': ');
|
||||
var noteContent = document.createTextNode(noteParams.content);
|
||||
|
||||
function clearNote(id) {
|
||||
document.getElementById('note__content__' + id).value = '';
|
||||
}
|
||||
noteAuthor.appendChild(authorContent);
|
||||
newNote.appendChild(noteContent);
|
||||
|
||||
function submitNote(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)
|
||||
singleNoteDiv.append(noteAuthor);
|
||||
singleNoteDiv.append(newNote);
|
||||
|
||||
fetch('/internal/reports/create_note', {
|
||||
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);
|
||||
}))
|
||||
}
|
||||
notesDiv.append(singleNoteDiv);
|
||||
}
|
||||
|
||||
document.getElementById('note__submit__<%= feedback_message.id %>').addEventListener('click', function () {
|
||||
var reportId = <%= feedback_message.id %>;
|
||||
submitNote(reportId);
|
||||
});
|
||||
function clearNote(id) {
|
||||
document.getElementById('note__content__' + id).value = '';
|
||||
}
|
||||
|
||||
document.getElementById('minimize__report__button__<%= feedback_message.id %>').addEventListener('click', function () {
|
||||
document.getElementById('collapse__header__link-<%= feedback_message.id %>').click();
|
||||
});
|
||||
function submitNote(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('/internal/reports/create_note', {
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,4 @@
|
|||
<style>
|
||||
.top-nav {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) and (min-width: 768px) {
|
||||
.top-nav {
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
margin-top: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.top-nav a {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.active-state {
|
||||
background-color: #89ffba;
|
||||
}
|
||||
|
||||
.notefield {
|
||||
width: 100%;
|
||||
resize: none;
|
||||
|
|
@ -32,28 +9,6 @@
|
|||
margin: 10px 0px;
|
||||
}
|
||||
|
||||
.blankmessage {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.note-content {
|
||||
border: 1px dashed black;
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
padding-top: 25px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.email__alert {
|
||||
display: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.panel-right-elements {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.email__container {
|
||||
border: 1px solid gray;
|
||||
margin: 10px;
|
||||
|
|
@ -67,14 +22,4 @@
|
|||
color: black;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.time__badge {
|
||||
float: right;
|
||||
margin-top: 7px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.single__note {
|
||||
width: 60%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,81 +1,119 @@
|
|||
<%= render "style" %>
|
||||
<style>
|
||||
.single-article-actions a {
|
||||
color: black;
|
||||
font-size: 0.77em;
|
||||
}
|
||||
</style>
|
||||
<h1>Latest Articles</h1>
|
||||
<div style="height: 400px; overflow: scroll;">
|
||||
<% @new_articles.each do |article| %>
|
||||
<% next if article.user.badge_achievements_count > 2 %>
|
||||
<div style="border-bottom: 1px solid black; padding: 3px 0px 2px;">
|
||||
<a href="<%= article.path %>"><%= article.title %></a>
|
||||
<div class="single-article-actions">
|
||||
<a href="<%= article.path %>/mod">Mod</a> |
|
||||
<a href="<%= article.path %>/moderate">Internal</a> |
|
||||
<a href="<%= article.user.path %>">@<%= article.user.username %></a> |
|
||||
<a href="/internal/users/<%= article.user_id %>">Internal User</a> |
|
||||
<a href="/internal/users/<%= article.user_id %>/edit">Destructive Actions</a>
|
||||
|
||||
<h2>Suspicious Activity</h2>
|
||||
|
||||
<div class="row my-3" id="latestArticles">
|
||||
<div class="card w-100">
|
||||
<div class="card-header" id="articlesHeader">
|
||||
<h2 class="d-inline">Latest Articles</h2>
|
||||
<button class="btn btn-secondary float-right" type="button" data-toggle="collapse" data-target="#articlesBodyContainer" aria-expanded="false" aria-controls="articlesBodyContainer">
|
||||
Toggle
|
||||
</button>
|
||||
</div>
|
||||
<div id="articlesBodyContainer" class="collapse hide" aria-labelledby="articleHeader" data-parent="#latestArticles">
|
||||
<div class="card-body" style="overflow: scroll; max-height: 500px;">
|
||||
<% @new_articles.each do |article| %>
|
||||
<% next if article.user.badge_achievements_count > 2 %>
|
||||
<a href="<%= article.path %>"><%= article.title %></a>
|
||||
<span class="float-right">
|
||||
<a href="<%= article.path %>/mod" class="btn btn-secondary btn-sm">Mod</a>
|
||||
<a href="<%= article.path %>/moderate" class="btn btn-secondary btn-sm">Internal</a>
|
||||
<a href="<%= article.user.path %>" class="btn btn-secondary btn-sm">Profile</a>
|
||||
<a href="/internal/users/<%= article.user_id %>" class="btn btn-secondary btn-sm">Internal User</a>
|
||||
<a href="/internal/users/<%= article.user_id %>/edit" class="btn btn-danger btn-sm">Destructive Actions</a>
|
||||
</span>
|
||||
<hr>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Possible spam/abuse users</h1>
|
||||
<div style="height: 400px; overflow: scroll;">
|
||||
<% @possible_spam_users.each do |user| %>
|
||||
<div style="border-bottom: 1px solid black; padding: 5px 0px 2px;">
|
||||
<a href="<%= user.path %>">@<%= user.username %></a> - <%= user.name %>
|
||||
<div class="single-article-actions">
|
||||
<a href="/internal/users/<%= user.id %>">Internal User</a> |
|
||||
<a href="/internal/users/<%= user.id %>/edit">Destructive Actions</a>
|
||||
<div class="row my-3" id="possibleSpamUsers">
|
||||
<div class="card w-100">
|
||||
<div class="card-header" id="possibleSpamUsersHeader">
|
||||
<h2 class="d-inline">Possible Spam/Abuse Users</h2>
|
||||
<button class="btn btn-secondary float-right" type="button" data-toggle="collapse" data-target="#possibleSpamUsersBodyContainer" aria-expanded="false" aria-controls="possibleSpamUsersBodyContainer">
|
||||
Toggle
|
||||
</button>
|
||||
</div>
|
||||
<div id="possibleSpamUsersBodyContainer" class="collapse hide" aria-labelledby="possibleSpamUsersHeader" data-parent="#possibleSpamUsers">
|
||||
<div class="card-body" style="overflow: scroll; max-height: 500px;">
|
||||
<% @possible_spam_users.each do |user| %>
|
||||
<a href="<%= user.path %>">@<%= user.username %></a> - <%= user.name %>
|
||||
<span class="float-right">
|
||||
<a href="/internal/users/<%= user.id %>" class="btn btn-secondary btn-sm">Internal User</a>
|
||||
<a href="/internal/users/<%= user.id %>/edit" class="btn btn-danger btn-sm">Destructive Actions</a>
|
||||
</span>
|
||||
<hr>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 class="top-nav">
|
||||
Abuse Reports -
|
||||
<a href="/internal/reports?state=<%= @feedback_type %>&status=Open" class="<%= "active-state" if @status == "Open" %>">Open/Unresolved</a> |
|
||||
<a href="/internal/reports?state=<%= @feedback_type %>&status=Resolved" class="<%= "active-state" if @status == "Resolved" %>">Resolved</a> |
|
||||
<a href="/internal/reports?state=<%= @feedback_type %>&status=Invalid" class="<%= "active-state" if @status == "Invalid" %>">Invalid</a>
|
||||
</h1>
|
||||
<hr>
|
||||
<h2>Abuse Reports</h2>
|
||||
|
||||
<div class="row my-3">
|
||||
<div class="col">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item">
|
||||
<a href="/internal/reports?state=<%= @feedback_type %>&status=Open" class="nav-link <%= "active" if @status == "Open" %>">Open/Unresolved</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/reports?state=<%= @feedback_type %>&status=Resolved" class="nav-link <%= "active" if @status == "Resolved" %>">Resolved</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/reports?state=<%= @feedback_type %>&status=Invalid" class="nav-link <%= "active" if @status == "Invalid" %>">Invalid</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row my-3" id="vomitReactions">
|
||||
<div class="card w-100">
|
||||
<div class="card-header" id="vomitReactionsHeader">
|
||||
<h2 class="d-inline">Vomit Reactions</h2>
|
||||
<button class="btn btn-secondary float-right" type="button" data-toggle="collapse" data-target="#vomitReactionsBodyContainer" aria-expanded="false" aria-controls="vomitReactionsBodyContainer">
|
||||
Toggle
|
||||
</button>
|
||||
</div>
|
||||
<div id="vomitReactionsBodyContainer" class="collapse hide" aria-labelledby="vomitReactionsHeader" data-parent="#vomitReactions">
|
||||
<div class="card-body" style="overflow: scroll; max-height: 500px;">
|
||||
<% @vomits.each do |reaction| %>
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>
|
||||
🤢 <a href="<%= reaction.user.path %>">@<%= reaction.user.username %></a>
|
||||
</span>
|
||||
<span>
|
||||
<strong><%= reaction.reactable_type %>:</strong>
|
||||
<a href="<%= reaction.reactable.path %>"><%= reaction.reactable.title %></a>
|
||||
</span>
|
||||
<span>
|
||||
<% if params[:status] == "Open" || params[:status].blank? %>
|
||||
<%= form_for [:internal, reaction], html: { class: "d-inline" } do |f| %>
|
||||
<%= f.hidden_field :status, value: "confirmed" %>
|
||||
<%= f.submit "CONFIRMED", class: "btn btn-success btn-sm" %>
|
||||
<% end %>
|
||||
<%= form_for [:internal, reaction], html: { class: "d-inline" } do |f| %>
|
||||
<%= f.hidden_field :status, value: "invalid" %>
|
||||
<%= f.submit "INVALID", class: "btn btn-danger btn-sm" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
<hr>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= paginate @feedback_messages %>
|
||||
|
||||
<% @vomits.each do |reaction| %>
|
||||
<% next unless reaction.user && reaction.reactable %>
|
||||
<div class="row">
|
||||
<div class="inner-row col-md-3">
|
||||
<strong>🤢 <a href="<%= reaction.user.path %>">@<%= reaction.user.username %></a></strong>
|
||||
</div>
|
||||
<div class="inner-row col-md-<%= params[:status] == "Open" || params[:status].blank? ? "5" : "9" %>">
|
||||
<strong><%= reaction.reactable_type %>:</strong>
|
||||
<a href="<%= reaction.reactable.path %>"><%= reaction.reactable.title %></a>
|
||||
</div>
|
||||
<% if params[:status] == "Open" || params[:status].blank? %>
|
||||
<div class="inner-row col-md-2">
|
||||
<%= form_for [:internal, reaction] do |f| %>
|
||||
<%= f.hidden_field :status, value: "confirmed" %>
|
||||
<%= f.submit "CONFIRMED", class: "btn btn-success btn-lg" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="inner-row col-md-2">
|
||||
<%= form_for [:internal, reaction] do |f| %>
|
||||
<%= f.hidden_field :status, value: "invalid" %>
|
||||
<%= f.submit "INVALID", class: "btn btn-danger btn-lg" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<br>
|
||||
<% @feedback_messages.each do |feedback_message| %>
|
||||
<%= form_for [:internal, feedback_message] do |f| %>
|
||||
<%= render "feedback_message", f: f, feedback_message: feedback_message %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<%= paginate @feedback_messages %>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
<%= render "style" %>
|
||||
|
||||
<div class="blank_space" style="height: 50px;">
|
||||
</div>
|
||||
<div class="blank_space">
|
||||
</div>
|
||||
<div class="blank_space">
|
||||
</div>
|
||||
|
||||
<%= form_for [:internal, @feedback_message] do |f| %>
|
||||
<%= form_for [:internal, @feedback_message], html: { class: "mt-3" } do |f| %>
|
||||
<%= render "feedback_message", f: f, feedback_message: @feedback_message %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,44 @@
|
|||
<h3>Past <%= num_days %> day new users (<%= User.where("created_at > ?", num_days.day.ago).count %>)</h3>
|
||||
<h4>Overall data:</h4>
|
||||
<ul>
|
||||
<li>
|
||||
Average comments: <%= User.where("created_at > ?", num_days.day.ago).average(:comments_count) %>
|
||||
</li>
|
||||
<li>
|
||||
Average articles: <%= User.where("created_at > ?", num_days.day.ago).average(:articles_count) %>
|
||||
</li>
|
||||
<li>
|
||||
Average reactions: <%= User.where("created_at > ?", num_days.day.ago).average(:reactions_count) %>
|
||||
</li>
|
||||
</ul>
|
||||
<% @variants.each do |var| %>
|
||||
<h4>Variant: <%= var %></h4>
|
||||
<ul>
|
||||
<li>
|
||||
Average comments: <%= User.where("created_at > ?", num_days.day.ago).where(onboarding_variant_version: var).average(:comments_count) %>
|
||||
</li>
|
||||
<li>
|
||||
Average articles: <%= User.where("created_at > ?", num_days.day.ago).where(onboarding_variant_version: var).average(:articles_count) %>
|
||||
</li>
|
||||
<li>
|
||||
Average reactions: <%= User.where("created_at > ?", num_days.day.ago).where(onboarding_variant_version: var).average(:reactions_count) %>
|
||||
</li>
|
||||
</ul>
|
||||
<% end %>
|
||||
<h3 class="m-4">Past <%= num_days %> day new users (<%= User.where("created_at > ?", num_days.day.ago).count %>)</h3>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<strong>Overall data:</strong>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">
|
||||
Average comments: <%= User.where("created_at > ?", num_days.day.ago).average(:comments_count) %>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
Average articles: <%= User.where("created_at > ?", num_days.day.ago).average(:articles_count) %>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
Average reactions: <%= User.where("created_at > ?", num_days.day.ago).average(:reactions_count) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<% @variants.each do |var| %>
|
||||
<div class="col-sm-6 mt-3">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<strong>Variant: <%= var %></strong>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">
|
||||
Average comments: <%= User.where("created_at > ?", num_days.day.ago).where(onboarding_variant_version: var).average(:comments_count) %>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
Average articles: <%= User.where("created_at > ?", num_days.day.ago).where(onboarding_variant_version: var).average(:articles_count) %>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
Average reactions: <%= User.where("created_at > ?", num_days.day.ago).where(onboarding_variant_version: var).average(:reactions_count) %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
<h1>Growth</h1>
|
||||
|
||||
<h2>Onboarding variants</h2>
|
||||
<%= render "results", num_days: 7 %>
|
||||
<%= render "results", num_days: 1 %>
|
||||
|
||||
<h2>Descriptions of current variants</h2>
|
||||
<h2 class="m-4">Descriptions of current variants</h2>
|
||||
|
||||
<%= simple_format "
|
||||
// 0) Original intro slide: three explainer paragraphs, left adjusted.
|
||||
|
|
|
|||
|
|
@ -1,69 +1,72 @@
|
|||
<style>
|
||||
textarea {
|
||||
height: 140px;
|
||||
}
|
||||
</style>
|
||||
<h1><%= params[:state] || "community" %> mods</h1>
|
||||
<%= form_tag("/internal/mods", method: "get") do %>
|
||||
<%= label_tag(:search, "Find by tag name:") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
<%= submit_tag("Search") %>
|
||||
<% end %>
|
||||
|
||||
<h3>
|
||||
<a href="/internal/mods"
|
||||
style="<%= "background: yellow" if params[:state].blank? %>">General Community</a> |
|
||||
<a href="/internal/mods?state=tag"
|
||||
style="<%= "background: yellow" if params[:state] == "tag" %>">Tag Mods</a> |
|
||||
<a href="/internal/mods?state=potential"
|
||||
style="<%= "background: yellow" if params[:state] == "potential" %>">Potential Mods</a>
|
||||
</h3>
|
||||
|
||||
<%= paginate @mods %>
|
||||
<div class="wrapper" style="font-weight: 600; border-bottom: 2px solid black; grid-template-columns: 15% 25% 13% 13% 20% 14%;">
|
||||
<div>ID</div>
|
||||
<div>Profile</div>
|
||||
<div>Comments</div>
|
||||
<div>Badges</div>
|
||||
<div>Last Comment</div>
|
||||
<% if params[:state] == "potential" %>
|
||||
<div>Action</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% @mods.each do |user| %>
|
||||
<div class="wrapper" style="border-top: 1px solid grey; padding: 10px; grid-template-columns: 15% 25% 13% 13% 20% 14%; font-size: 0.9em">
|
||||
<div><a href="/internal/users/<%= user.id %>"><%= user.id %></a></div>
|
||||
<div><a href="<%= user.path %>">@<%= user.username %></a></div>
|
||||
<div><%= user.comments_count %></div>
|
||||
<div><%= user.badge_achievements_count %></div>
|
||||
<div><%= time_ago_in_words user.last_comment_at %> ago</div>
|
||||
<% if params[:state] == "potential" && !user.trusted %>
|
||||
<div style="font-size: 0.8em;">
|
||||
<%= form_for([:internal, user], url: "/internal/mods/#{user.id}", method: :patch) do |f| %>
|
||||
<%#= f.hidden_field :id, value: user.id %>
|
||||
<%= f.submit "Make Trusted Mod" %>
|
||||
<% end %>
|
||||
<div class="row m-3">
|
||||
<div class="col">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item">
|
||||
<a href="/internal/mods" class="nav-link <%= "active" if params[:state].blank? %>">General Community</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/mods?state=tag" class="nav-link <%= "active" if params[:state] == "tag" %>">Tag Mods</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/mods?state=potential" class="nav-link <%= "active" if params[:state] == "potential" %>">Potential Mods</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col">
|
||||
<%= form_tag("/internal/mods", method: "get") do %>
|
||||
<div class="form-row justify-content-end">
|
||||
<div class="form-group">
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
<%= submit_tag("Search") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if user.notes.any? %>
|
||||
<details closed>
|
||||
<summary style="cursor: pointer; font-weight: bold; padding: 7px 12px; background: #f0f3f7"><%= pluralize user.notes.size, "Note" %></summary>
|
||||
<ul>
|
||||
<% user.notes.each do |note| %>
|
||||
<li>
|
||||
<b><%= note.reason %>:</b> <%= note.content %> <em>—<%= note.created_at.strftime("%B %e, %Y") %></em>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</details>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= paginate @mods %>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Profile</th>
|
||||
<th scope="col">Comments</th>
|
||||
<th scope="col">Badges</th>
|
||||
<th scope="col">Last Comment</th>
|
||||
<% if params[:state] == "potential" %>
|
||||
<th scope="col">Action</th>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @mods.each do |mod| %>
|
||||
<tr>
|
||||
<td><%= mod.id %></td>
|
||||
<td><%= link_to mod.username, "/internal/users/#{mod.id}/" %></td>
|
||||
<td><%= mod.comments_count %></td>
|
||||
<td><%= mod.badge_achievements_count %></td>
|
||||
<td><%= time_ago_in_words mod.last_comment_at %> ago</td>
|
||||
<% if params[:state] == "potential" %>
|
||||
<td>
|
||||
<% if !mod.trusted %>
|
||||
<%= form_for([:internal, mod], url: "/internal/mods/#{mod.id}", method: :patch) do |f| %>
|
||||
<%= f.submit "Make Trusted Mod" %>
|
||||
<% end %>
|
||||
<% elsif mod.trusted %>
|
||||
<span class="badge badge-success">Trusted</span>
|
||||
<% end %>
|
||||
</td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @mods %>
|
||||
<br /><br />
|
||||
|
||||
<script>
|
||||
function submitForms() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<div class="row">
|
||||
<h3><u>Activity</u></h3>
|
||||
<ul>
|
||||
<li><%= @organization.articles.size %> articles</li>
|
||||
<li><%= @organization.followers.size %> followers</li>
|
||||
</ul>
|
||||
<div class="col-sm-6">
|
||||
<h2>Activity</h2>
|
||||
<ul>
|
||||
<li><%= @organization.articles.size %> articles</li>
|
||||
<li><%= @organization.followers.size %> followers</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,28 +1,51 @@
|
|||
<br>
|
||||
<%= form_tag("/internal/organizations", method: "get") do %>
|
||||
<%= label_tag(:search, "Find by name:") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<%= submit_tag("Search") %>
|
||||
<% end %>
|
||||
<br>
|
||||
<div class="wrapper" style="font-weight: 600; border-bottom: 2px solid black;">
|
||||
<div>Name</div>
|
||||
<div>ID</div>
|
||||
<div>Twitter</div>
|
||||
<div>GitHub</div>
|
||||
<div>URL</div>
|
||||
<div class="row m-3">
|
||||
<div class="col justify-content-end">
|
||||
<%= form_tag("/internal/organizations", method: "get") do %>
|
||||
<div class="form-row justify-content-end">
|
||||
<div class="form-group">
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<%= submit_tag("Search") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= paginate @organizations %>
|
||||
|
||||
<% @organizations.each do |organization| %>
|
||||
<div class="wrapper" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div class="grid-item"><a href="/internal/organizations/<%= organization.id %>" target="_blank">@<%= organization.name %></a></div>
|
||||
<div class="grid-item"><%= organization.id %></div>
|
||||
<div class="grid-item"><%= organization.twitter_username || "N/A" %></div>
|
||||
<div class="grid-item"><%= organization.github_username || "N/A" %></div>
|
||||
<div class="grid-item"><%= organization.url || "N/A" %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Twitter</th>
|
||||
<th scope="col">GitHub</th>
|
||||
<th scope="col">URL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @organizations.each do |organization| %>
|
||||
<tr>
|
||||
<td><a href="/internal/organizations/<%= organization.id %>" target="_blank">@<%= organization.name %></td>
|
||||
<td><%= organization.id %></td>
|
||||
<% if organization.twitter_username %>
|
||||
<td><%= link_to organization.twitter_username, "https://twitter.com/#{organization.twitter_username}" %></td>
|
||||
<% else %>
|
||||
<td>N/A</td>
|
||||
<% end %>
|
||||
<% if organization.github_username %>
|
||||
<td><%= link_to organization.github_username, "https://github.com/#{organization.github_username}" %></td>
|
||||
<% else %>
|
||||
<td>N/A</td>
|
||||
<% end %>
|
||||
<% if organization.url %>
|
||||
<td><%= link_to organization.url, organization.url %></td>
|
||||
<% else %>
|
||||
<td>N/A</td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @organizations %>
|
||||
|
|
|
|||
|
|
@ -1,32 +1,35 @@
|
|||
<style>
|
||||
dt {
|
||||
width: calc(20% - 1rem);
|
||||
float: left;
|
||||
}
|
||||
|
||||
dd {
|
||||
width: calc(80% - 1rem)
|
||||
}
|
||||
</style>
|
||||
<div class="row">
|
||||
<h1>
|
||||
<%= @organization.name %><a href="/<%= @organization.slug %>" target="_blank"> (@<%= @organization.name %>)</a>
|
||||
</h1>
|
||||
<p><em>Created <%= @organization.created_at.strftime("%b %e '%y") %></em></p>
|
||||
<p><strong><u>General Info</u></strong></p>
|
||||
<dl>
|
||||
<dt>ID:</dt>
|
||||
<dd><%= @organization.id %></span></dd>
|
||||
<dt>name:</dt>
|
||||
<dd><%= @organization.name %></dd>
|
||||
<dt>Membership Count:</dt>
|
||||
<dd><%= @organization.organization_memberships.size %></dd>
|
||||
<dt>Email:</dt>
|
||||
<dd><%= @organization.email || "N/A" %></dd>
|
||||
<dt>Twitter:</dt>
|
||||
<dd><%= @organization.twitter_username || "N/A" %></dd>
|
||||
<dt>GitHub:</dt>
|
||||
<dd><%= @organization.github_username || "N/A" %></dd>
|
||||
</dl>
|
||||
<div class="col-12">
|
||||
<h2 class="d-inline">
|
||||
<%= @organization.name %><a href="/<%= @organization.slug %>" target="_blank"> (@<%= @organization.name %>)</a>
|
||||
</h2>
|
||||
<p class="font-italic">Created <%= @organization.created_at.strftime("%b %e '%y") %></p>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h2>General Info</h2>
|
||||
<dl>
|
||||
<dt>ID:</dt>
|
||||
<dd><%= @organization.id %></span></dd>
|
||||
<dt>name:</dt>
|
||||
<dd><%= @organization.name %></dd>
|
||||
<dt>Membership Count:</dt>
|
||||
<dd><%= @organization.organization_memberships.size %></dd>
|
||||
<dt>Email:</dt>
|
||||
<dd><%= @organization.email || "N/A" %></dd>
|
||||
<dt>Twitter:</dt>
|
||||
<% if @organization.twitter_username %>
|
||||
<dd><%= link_to @organization.twitter_username, "https://twitter.com/#{@organization.twitter_username}" %></dd>
|
||||
<% else %>
|
||||
<dd>N/A</dd>
|
||||
<% end %>
|
||||
<dt>GitHub:</dt>
|
||||
<% if @organization.github_username %>
|
||||
<dd><%= link_to @organization.github_username, "https://github.com/#{@organization.github_username}" %></dd>
|
||||
<% else %>
|
||||
<dd>N/A</dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "activity" %>
|
||||
|
|
|
|||
|
|
@ -1,29 +1,32 @@
|
|||
<%= form_for [:internal, @page] do |form| %>
|
||||
<%= form.label :title %>
|
||||
<br/>
|
||||
<%= form.text_field :title %>
|
||||
<hr/>
|
||||
<%= form.label :slug %>
|
||||
<br/>
|
||||
<%= form.text_field :slug %>
|
||||
<hr/>
|
||||
<%= form.label :body_markdown %>
|
||||
<br/>
|
||||
<%= form.text_area :body_markdown %>
|
||||
<hr/>
|
||||
<%= form.label :body_html %> (Only if not using markdown. HTML is dangerous ⚠️)
|
||||
<br/>
|
||||
<%= form.text_area :body_html %>
|
||||
<hr/>
|
||||
<%= form.label :description %>
|
||||
<br/>
|
||||
<%= form.text_field :description %>
|
||||
<hr/>
|
||||
<%= form.label :is_top_level_path %> (Determines if it is accessible by <code>/page-slug</code> vs <code>/page/page-slug</code>) Be careful! ⚠️
|
||||
<br/>
|
||||
<%= form.check_box :is_top_level_path %>
|
||||
<hr/>
|
||||
<%= form.submit %>
|
||||
|
||||
<hr/>
|
||||
<% end %>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<%= form_for [:internal, @page] do |form| %>
|
||||
<div class="form-group">
|
||||
<%= form.label :title %>
|
||||
<%= form.text_field :title, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :slug %>
|
||||
<%= form.text_field :slug, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :body_markdown %>
|
||||
<%= form.text_area :body_markdown, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :body_html %> (Only if not using markdown. HTML is dangerous ⚠️)
|
||||
<%= form.text_area :body_html, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :description %>
|
||||
<%= form.text_field :description, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :is_top_level_path %>
|
||||
<%= form.check_box :is_top_level_path %>
|
||||
<p>(Determines if it is accessible by <code>/page-slug</code> vs <code>/page/page-slug</code>) Be careful! ⚠️</p>
|
||||
</div>
|
||||
<%= form.submit class: "btn btn-primary float-right" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
<h1>Edit <%= @page.title %></h1>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>Edit <%= @page.title %></h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "form" %>
|
||||
<%= render "form" %>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
<div>
|
||||
<a class="btn btn-success" href="/internal/pages/new">New Page</a>
|
||||
<div class="notice"><%= flash[:notice] %></div>
|
||||
<%= csrf_meta_tags %>
|
||||
|
||||
<div class="row justify-content-end">
|
||||
<%= link_to "New Page", "/internal/pages/new", class: "btn btn-primary" %>
|
||||
</div>
|
||||
|
||||
<% @pages.each do |page| %>
|
||||
<div class="wrapper" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div class="grid-item"><a href="<%= page.path %>" target="_blank"><%= page.slug %></a></div>
|
||||
<div><%= page.title %></div>
|
||||
<div>
|
||||
<a class="btn" href="/internal/pages/<%= page.id %>/edit">Edit</a>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="list-group-flush w-100">
|
||||
<% @pages.each do |page| %>
|
||||
<a class="list-group-item list-group-item-action" href="/internal/pages/<%= page.id %>/edit">
|
||||
<%= page.title %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
<h1>New Page</h1>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>New Page</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "form" %>
|
||||
<%= render "form" %>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,30 @@
|
|||
<h1>Admin Roles</h1>
|
||||
<h2>Admin Roles</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
||||
<%= paginate @users %>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Profile</th>
|
||||
<th scope="col">Roles</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @users.each do |user| %>
|
||||
<tr>
|
||||
<td><%= user.id %></td>
|
||||
<td><%= link_to "@#{user.username}", user.path %></td>
|
||||
<td><%= user.roles.pluck(:name) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @users %>
|
||||
|
||||
<div class="wrapper" style="font-weight: 600; border-bottom: 2px solid black; grid-template-columns: 25% 25% 50%;">
|
||||
<div>ID</div>
|
||||
<div>Profile</div>
|
||||
<div>Roles</div>
|
||||
</div>
|
||||
<% @users.each do |user| %>
|
||||
<div class="wrapper" style="border-top: 1px solid grey; padding: 10px; grid-template-columns: 25% 25% 50%; font-size: 0.9em">
|
||||
<div><a href="/internal/users/<%= user.id %>"><%= user.id %></a></div>
|
||||
<div><a href="<%= user.path %>">@<%= user.username %></a></div>
|
||||
<div><%= user.roles.pluck(:name) %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,43 +1,48 @@
|
|||
<h1>
|
||||
<%= link_to @podcast.title, "/#{@podcast.slug}" %>
|
||||
</h1>
|
||||
<% if @podcast.admins.any? %>
|
||||
<p><strong>Admins: </strong></p>
|
||||
<ul>
|
||||
<% @podcast.admins.each do |admin| %>
|
||||
<%= form_for @podcast, url: remove_admin_internal_podcast_path(@podcast.id), html: { method: :delete } do |f| %>
|
||||
<li>
|
||||
<%= link_to "@#{admin.username}", "/#{admin.username}" %>
|
||||
<%= f.hidden_field :user_id, value: admin.id %>
|
||||
<%= f.submit "Remove" %>
|
||||
</li>
|
||||
<br>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<p>There are no admins for this podcast.</p>
|
||||
<% end %>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="m-0"><%= link_to @podcast.title, "/#{@podcast.slug}" %></h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<% if @podcast.admins.any? %>
|
||||
<h3>Admins:</h3>
|
||||
<ul class="list-group list-group-flush mb-3">
|
||||
<% @podcast.admins.each do |admin| %>
|
||||
<%= form_for @podcast, url: remove_admin_internal_podcast_path(@podcast.id), html: { method: :delete, class: "form-inline" } do |f| %>
|
||||
<li class="list-group-item w-100">
|
||||
<%= link_to "@#{admin.username}", "/#{admin.username}" %>
|
||||
<%= f.hidden_field :user_id, value: admin.id %>
|
||||
<%= f.submit "Remove", class: "btn btn-danger btn-sm float-right" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<p>There are no admins for this podcast.</p>
|
||||
<% end %>
|
||||
|
||||
<%= form_for @podcast, url: add_admin_internal_podcast_path(@podcast.id), html: { method: :post } do |f| %>
|
||||
<div>
|
||||
<%= f.label "Add Admin (by user_id) " %>
|
||||
<%= f.text_field :user_id, value: "" %>
|
||||
<%= f.submit "Add Admin" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= form_for @podcast, url: add_admin_internal_podcast_path(@podcast.id), html: { method: :post } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label "Add Admin (by user_id)", for: "podcast_user_id" %>
|
||||
<%= f.text_field :user_id, value: "", class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Add Admin", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<%= form_for [:internal, @podcast] do |f| %>
|
||||
<hr>
|
||||
<div>
|
||||
<%= f.label :title %>
|
||||
<%= f.text_field :title %>
|
||||
<%= form_for [:internal, @podcast] do |f| %>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<%= f.label :title, for: "podcast_title" %>
|
||||
<%= f.text_field :title, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :feed_url, for: "podcast_feed_url" %>
|
||||
<%= f.text_field :feed_url, class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :feed_url %>
|
||||
<%= f.text_field :feed_url %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,44 +1,49 @@
|
|||
<style>
|
||||
.alert {
|
||||
border: 2px red solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Podcasts</h1>
|
||||
|
||||
<%= form_tag("/internal/podcasts", method: "get") do %>
|
||||
<%= label_tag(:search, "Find by title:") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<%= submit_tag("Search") %>
|
||||
<% end %>
|
||||
|
||||
<%= paginate @podcasts %>
|
||||
<br>
|
||||
<div class="wrapper-8" style="font-weight: 600; border-bottom: 2px solid black;">
|
||||
<div>ID</div>
|
||||
<div>Title</div>
|
||||
<div>Feed URL</div>
|
||||
<div>Eps</div>
|
||||
<div>Reach</div>
|
||||
<div>Pub</div>
|
||||
<div>Status Notice</div>
|
||||
<div>Admins</div>
|
||||
<div class="row m-3">
|
||||
<div class="col">
|
||||
<%= form_tag("/internal/podcasts", method: "get") do %>
|
||||
<div class="form-row justify-content-end">
|
||||
<div class="form-group">
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<%= submit_tag("Search") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% @podcasts.each do |podcast| %>
|
||||
<div class="wrapper-8" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div class="grid-item"><%= podcast.id %></div>
|
||||
<div class="grid-item"><a href="<%= edit_internal_podcast_path(podcast) %>"><%= podcast.title %></a></div>
|
||||
<div class="grid-item"><a href="<%= podcast.feed_url %>"><%= podcast.feed_url %></a></div>
|
||||
<div class="grid-item"><%= podcast.podcast_episodes.count %></div>
|
||||
<div class="grid-item"><%= podcast.reachable %></div>
|
||||
<div class="grid-item"><%= podcast.published %></div>
|
||||
<div class="grid-item"><%= podcast.status_notice %></div>
|
||||
<div class="grid-item">
|
||||
<% podcast.admins.pluck(:username).each do |username| %>
|
||||
<%= link_to "@#{username}", "/#{username}" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= paginate @podcasts %>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Title</th>
|
||||
<th scope="col">Feed URL</th>
|
||||
<th scope="col">Eps</th>
|
||||
<th scope="col">Reach</th>
|
||||
<th scope="col">Pub</th>
|
||||
<th scope="col">Status Notice</th>
|
||||
<th scope="col">Admin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @podcasts.each do |podcast| %>
|
||||
<tr>
|
||||
<td><%= podcast.id %></td>
|
||||
<td><%= link_to podcast.title, edit_internal_podcast_path(podcast) %></td>
|
||||
<td><%= link_to podcast.feed_url, podcast.feed_url %></td>
|
||||
<td><%= podcast.podcast_episode.size %></td>
|
||||
<td><%= podcast.reachable %></td>
|
||||
<td><%= podcast.published %></td>
|
||||
<td><%= podcast.status_notice %></td>
|
||||
<td>
|
||||
<% podcast.admins.pluck(:username).each do |username| %>
|
||||
<%= link_to "@#{username}", "/#{username}" %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @podcasts %>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
<% menu_items = %w[comments articles users tags welcome broadcasts reports pages tools chat_channels growth mods config badges organizations].each_with_object({}) { |v, h| h[v] = v } %>
|
||||
<% menu_items = %w[comments articles users tags welcome broadcasts reports pages tools chat_channels permissions growth mods config events badges organizations].each_with_object({}) { |v, h| h[v] = v } %>
|
||||
<% menu_items[:listings] = "classified_listings" %>
|
||||
<% menu_items[:podcasts] = "podcasts" %>
|
||||
<% menu_items[:webhooks] = "webhook_endpoints" %>
|
||||
|
||||
<div id="navbar" class="collapse navbar-collapse">
|
||||
<ul class="nav navbar-nav" style="font-size: 0.97em;">
|
||||
<% menu_items.each do |name, controller| %>
|
||||
<li class="<%= "active" if controller_name == controller %>"><a href="/internal/<%= controller %>"><%= name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div class="navbar-nav justify-content-center">
|
||||
<% menu_items.each do |name, controller| %>
|
||||
<a class="nav-item nav-link <%= "active" if request.path.include?(controller) %>" href="/internal/<%= controller %>"><%= name.to_s.titleize %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,44 +1,57 @@
|
|||
<style>
|
||||
textarea {
|
||||
height: 140px;
|
||||
}
|
||||
</style>
|
||||
<h1>Tags</h1>
|
||||
<%= form_tag("/internal/tags", method: "get") do %>
|
||||
<%= label_tag(:search, "Find by tag name:") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
<%= submit_tag("Search") %>
|
||||
<% end %>
|
||||
|
||||
<h3>
|
||||
<a href="/internal/tags"
|
||||
style="<%= "background: yellow" if params[:state].blank? %>">All</a> |
|
||||
<a href="/internal/tags?state=supported"
|
||||
style="<%= "background: yellow" if params[:state] == "supported" %>">Supported</a> |
|
||||
<a href="/internal/tags?state=unsupported"
|
||||
style="<%= "background: yellow" if params[:state] == "unsupported" %>">Unsupported</a> |
|
||||
</h3>
|
||||
|
||||
<%= paginate @tags %>
|
||||
<div class="wrapper" style="font-weight: 600; border-bottom: 2px solid black;">
|
||||
<div>Tag</div>
|
||||
<div>ID</div>
|
||||
<div>Alias For</div>
|
||||
<div>Taggings Count</div>
|
||||
<div>Category</div>
|
||||
<div>Is Moderated?</div>
|
||||
</div>
|
||||
<% @tags.each do |tag| %>
|
||||
<div class="wrapper" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div class="grid-item"><a href="/internal/tags/<%= tag.id %>" target="_blank">#<%= tag.name %></a></div>
|
||||
<div><%= tag.id %></div>
|
||||
<div><%= tag.alias_for %></div>
|
||||
<div><%= tag.taggings_count %></div>
|
||||
<div><%= tag.category %></div>
|
||||
<div><%= tag.tag_moderator_ids.any? %></div>
|
||||
<div class="row m-3">
|
||||
<div class="col">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item">
|
||||
<a href="/internal/tags" class="nav-link <%= "active" if params[:state].blank? %>">All</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/tags?state=supported" class="nav-link <%= "active" if params[:state] == "supported" %>">Supported</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/tags?state=unsupported" class="nav-link <%= "active" if params[:state] == "unsupported" %>">Unsupported</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="col">
|
||||
<%= form_tag("/internal/tags", method: "get") do %>
|
||||
<div class="form-row justify-content-end">
|
||||
<div class="form-group">
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
<%= submit_tag("Search") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= paginate @tags %>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Tag</th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Alias For</th>
|
||||
<th scope="col">Taggings Count</th>
|
||||
<th scope="col">Category</th>
|
||||
<th scope="col">Is Moderated?</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @tags.each do |tag| %>
|
||||
<tr>
|
||||
<td><%= link_to tag.name, "/internal/tags/#{tag.id}/" %></td>
|
||||
<td><%= tag.id %></td>
|
||||
<td><%= tag.alias_for %></td>
|
||||
<td><%= tag.taggings_count %></td>
|
||||
<td><%= tag.category %></td>
|
||||
<td><%= tag.tag_moderator_ids.any? %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @tags %>
|
||||
|
|
|
|||
|
|
@ -1,76 +1,83 @@
|
|||
<h1>
|
||||
<a href="/t/<%= @tag.name %>" style="background:<%= @tag.bg_color_hex %>;color:<%= @tag.text_color_hex %>;">#<%= @tag.name %></a>, tagged <%= @tag.taggings_count %> times.
|
||||
</h1>
|
||||
<% if @tag.tag_moderator_ids.any? %>
|
||||
<p><strong>Moderators: </strong></p>
|
||||
<% else %>
|
||||
<p>This tag currently has no moderators.</p>
|
||||
<% end %>
|
||||
<ul>
|
||||
<% @tag.tag_moderator_ids.each do |id| %>
|
||||
<%= form_for [:internal, @tag] do |f| %>
|
||||
<li>
|
||||
<a href="/<%= User.find(id).username %>">@<%= User.find(id).username %></a>
|
||||
<%= f.hidden_field :remove_moderator_id, value: id %>
|
||||
<%= f.submit "Remove" %>
|
||||
</li>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>
|
||||
<a href="/t/<%= @tag.name %>" style="background:<%= @tag.bg_color_hex %>;color:<%= @tag.text_color_hex %>;">#<%= @tag.name %></a>, tagged <%= @tag.taggings_count %> times.
|
||||
</h2>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h3>Moderators</h3>
|
||||
<% if @tag.tag_moderator_ids.any? %>
|
||||
<ul class="list-group-flush">
|
||||
<% @tag.tag_moderator_ids.each do |id| %>
|
||||
<li class="list-group-item d-flex justify-content-between">
|
||||
<a href="/<%= User.find(id).username %>">@<%= User.find(id).username %></a>
|
||||
<%= form_for [:internal, @tag] do |f| %>
|
||||
<%= f.hidden_field :remove_moderator_id, value: id %>
|
||||
<%= f.submit "Remove", class: "btn btn-danger btn-sm" %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<p>This tag currently has no moderators.</p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<%= form_for [:internal, @tag] do |f| %>
|
||||
<div>
|
||||
<%= f.label "Add Moderator (id): " %>
|
||||
<%= f.text_field :tag_moderator_id %>
|
||||
<%= f.submit "Add Moderator" %>
|
||||
<%= form_for [:internal, @tag], html: { class: "form-inline justify-content-between" } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label "Add Moderator (id):", class: "mr-3" %>
|
||||
<%= f.text_field :tag_moderator_id, class: "form-control" %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.submit "Add Moderator", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= form_for [:internal, @tag] do |f| %>
|
||||
<hr>
|
||||
<div>
|
||||
<%= f.label :supported %>
|
||||
<%= f.check_box :supported %>
|
||||
<div class="col-12">
|
||||
<%= form_for [:internal, @tag] do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label :supported %>
|
||||
<%= f.check_box :supported %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :badge_id %>
|
||||
<% badges_array = Badge.pluck(:title, :id) %>
|
||||
<%= f.select(:badge_id, options_for_select([["None", nil]] + badges_array, @tag.badge_id)) %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :category %>
|
||||
<%= f.select(:category, options_for_select(Tag.valid_categories, @tag.category)) %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :alias_for %>
|
||||
<%= f.text_field :alias_for, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :pretty_name %>
|
||||
<%= f.text_field :pretty_name, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :short_summary %>
|
||||
<%= f.text_field :short_summary, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :rules_markdown %>
|
||||
<br>
|
||||
<%= f.text_area :rules_markdown, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :wiki_body_markdown %>
|
||||
<br>
|
||||
<%= f.text_area :wiki_body_markdown, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :bg_color_hex %>
|
||||
<%= f.text_field :bg_color_hex, class: "color-picker form-control", required: true %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :text_color_hex %>
|
||||
<%= f.text_field :text_color_hex, class: "color-picker form-control", required: true %>
|
||||
</div>
|
||||
<%= f.submit class: "btn btn-primary float-right" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :badge_id %>
|
||||
<% badges_array = Badge.pluck(:title, :id) %>
|
||||
<%= f.select(:badge_id, options_for_select([["None", nil]] + badges_array, @tag.badge_id)) %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :category %>
|
||||
<%= f.select(:category, options_for_select(Tag.valid_categories, @tag.category)) %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :alias_for %>
|
||||
<%= f.text_field :alias_for %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :pretty_name %>
|
||||
<%= f.text_field :pretty_name %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :short_summary %>
|
||||
<%= f.text_field :short_summary %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :rules_markdown %>
|
||||
<br>
|
||||
<%= f.text_area :rules_markdown %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :wiki_body_markdown %>
|
||||
<br>
|
||||
<%= f.text_area :wiki_body_markdown %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :bg_color_hex %>
|
||||
<%= f.text_field :bg_color_hex, class: "color-picker", required: true %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :text_color_hex %>
|
||||
<%= f.text_field :text_color_hex, class: "color-picker", required: true %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,41 @@
|
|||
<h1>General Purpose URL Purge</h1>
|
||||
<h2>General Purpose URL Purge</h2>
|
||||
<p>For a page that should 404. This will purge the page via Fastly.</p>
|
||||
<p>Use the full path (https://dev.to/xyz) or the relative path: (/xyz)</p>
|
||||
<%= form_tag "/internal/tools/bust_cache" do %>
|
||||
<%= label_tag("Link:") %>
|
||||
<%= text_field_tag :dead_link, nil, placeholder: "/devteam/page" %>
|
||||
<%= submit_tag("Clear Cache") %>
|
||||
<% end %>
|
||||
<hr>
|
||||
<h1>Bust Cache For Specific Content</h1>
|
||||
<p>This clears both the Rails cache & the Fastly cache.</p>
|
||||
<div class="row m-3">
|
||||
<%= form_tag "/internal/tools/bust_cache" do %>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<%= label_tag("Link:") %>
|
||||
<%= text_field_tag :dead_link, nil, placeholder: "/devteam/page" %>
|
||||
<%= submit_tag("Clear Cache") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= form_tag "/internal/tools/bust_cache" do %>
|
||||
<%= label_tag("Article ID: ") %>
|
||||
<%= text_field_tag :bust_article, nil, placeholder: "12345" %>
|
||||
<%= submit_tag("Clear Cache") %>
|
||||
<% end %>
|
||||
<br>
|
||||
<%= form_tag "/internal/tools/bust_cache" do %>
|
||||
<%= label_tag("User ID: ") %>
|
||||
<%= text_field_tag :bust_user, nil, placeholder: "12345" %>
|
||||
<%= submit_tag("Clear Cache") %>
|
||||
<% end %>
|
||||
<hr>
|
||||
|
||||
<h2>Bust Cache For Specific Content</h2>
|
||||
<p>This clears both the Rails cache & the Fastly cache.</p>
|
||||
<div class="row m-3">
|
||||
<%= form_tag "/internal/tools/bust_cache" do %>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<%= label_tag("Article ID: ") %>
|
||||
<%= text_field_tag :bust_article, nil, placeholder: "12345" %>
|
||||
<%= submit_tag("Clear Article Cache") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="row m-3">
|
||||
<%= form_tag "/internal/tools/bust_cache" do %>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<%= label_tag("User ID: ") %>
|
||||
<%= text_field_tag :bust_user, nil, placeholder: "12345" %>
|
||||
<%= submit_tag("Clear User Cache") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
<div class="row">
|
||||
<h3><u>Activity</u></h3>
|
||||
<ul>
|
||||
<li><%= @user.comments.size %> comments</li>
|
||||
<li><%= @user.articles.size %> articles</li>
|
||||
<li><%= @user.reactions.size %> reactions</li>
|
||||
<li><%= @user.followers.size %> followers</li>
|
||||
<li><%= @user.following_users_count %> users following</li>
|
||||
<li><%= @user.badge_achievements_count %> badges</li>
|
||||
</ul>
|
||||
<h3><u>Current Roles</u></h3>
|
||||
<p>(view full history in notes below)</p>
|
||||
<ul>
|
||||
<% @user.roles.each do |role| %>
|
||||
<li><%= role.name %> <em><%= "- " + Tag.find(role.resource_id).name if role.resource_id.present? %></em></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<h2>Activity</h2>
|
||||
<ul>
|
||||
<li><%= @user.comments.size %> comments</li>
|
||||
<li><%= @user.articles.size %> articles</li>
|
||||
<li><%= @user.reactions.size %> reactions</li>
|
||||
<li><%= @user.followers.size %> followers</li>
|
||||
<li><%= @user.following_users_count %> users following</li>
|
||||
<li><%= @user.badge_achievements_count %> badges</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<h2>Current Roles</h2>
|
||||
<p>(view full history in notes below)</p>
|
||||
<ul>
|
||||
<% @user.roles.each do |role| %>
|
||||
<li><%= role.name %> <em><%= "- " + Tag.find(role.resource_id).name if role.resource_id.present? %></em></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,38 +1,54 @@
|
|||
<div class="row">
|
||||
<h3><u>Credits</u></h3>
|
||||
<p>Available User Credits: <%= @user.unspent_credits_count %></p>
|
||||
<%= form_for [:internal, @user] do |f| %>
|
||||
<%= f.label "Add Credit(s): " %>
|
||||
<br>
|
||||
<%= f.text_field :add_credits, placeholder: "#", size: 5 %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you adding these credits?", size: 50, required: true %>
|
||||
<%= f.submit "Add Credits" %>
|
||||
<% end %>
|
||||
<%= form_for [:internal, @user] do |f| %>
|
||||
<%= f.label "Remove Credits(s)" %>
|
||||
<br>
|
||||
<%= f.text_field :remove_credits, placeholder: "#", size: 5 %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you removing these credits?", size: 50, required: true %>
|
||||
<%= f.submit "Remove Credits"%>
|
||||
<% end %>
|
||||
<br>
|
||||
<% @organizations.each do |org| %>
|
||||
<p>Available <%= org.name %> Credits: <%= org.unspent_credits_count %></p>
|
||||
<%= form_for [:internal, @user] do |f| %>
|
||||
<%= f.label "Add Org Credit(s): " %>
|
||||
<br>
|
||||
<%= f.hidden_field :organization_id, value: org.id %>
|
||||
<%= f.text_field :add_org_credits, placeholder: "#", size: 5 %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you adding these credits?", size: 50, required: true %>
|
||||
<%= f.submit "Add Org Credits" %>
|
||||
<div class="col-12">
|
||||
<h2>Credits</h2>
|
||||
<hr>
|
||||
<h4 class="mt-3"><%= @user.username %></h4>
|
||||
<p>Available User Credits: <%= @user.unspent_credits_count %></p>
|
||||
|
||||
<h3>Add Credits</h3>
|
||||
<%= form_for [:internal, @user], html: { class: "form-inline justify-content-between mb-2" } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.text_field :add_credits, placeholder: "#", size: 5, class: "form-control mr-3" %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you adding these credits?", size: 50, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Add Credits", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
<%= form_for [:internal, @user] do |f| %>
|
||||
<%= f.label "Remove Org Credits(s)" %>
|
||||
<br>
|
||||
<%= f.hidden_field :organization_id, value: org.id %>
|
||||
<%= f.text_field :remove_org_credits, placeholder: "#", size: 5 %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you removing these credits?", size: 50, required: true %>
|
||||
<%= f.submit "Remove Org Credits"%>
|
||||
|
||||
<h3>Remove Credits</h3>
|
||||
<%= form_for [:internal, @user], html: { class: "form-inline justify-content-between mb-2" } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.text_field :remove_credits, placeholder: "#", size: 5, class: "form-control mr-3" %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you removing these credits?", size: 50, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Remove Credits", class: "btn btn-danger" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<% @organizations.sort.each do |org| %>
|
||||
<h4 class="mt-3"><%= org.name %></h4>
|
||||
<p>Available <%= org.name %> Credits: <%= org.unspent_credits_count %></p>
|
||||
|
||||
<h3>Add Org Credits</h3>
|
||||
<%= form_for [:internal, @user], html: { class: "form-inline justify-content-between mb-2" } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.hidden_field :organization_id, value: org.id %>
|
||||
<%= f.text_field :add_org_credits, placeholder: "#", size: 5, class: "form-control mr-3" %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you adding these credits?", size: 50, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Add Org Credits", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<h3>Remove Org Credits</h3>
|
||||
<%= form_for [:internal, @user], html: { class: "form-inline justify-content-between mb-2" } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.hidden_field :organization_id, value: org.id %>
|
||||
<%= f.text_field :remove_org_credits, placeholder: "#", size: 5, class: "form-control mr-3" %>
|
||||
<%= f.text_field :new_note, placeholder: "Why are you removing these credits?", size: 50, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Remove Org Credits", class: "btn btn-danger" %>
|
||||
<% end %>
|
||||
<hr>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,21 @@
|
|||
<div class="row">
|
||||
<h3><u>Notes</u></h3>
|
||||
<% if @user.notes.count > 0 %>
|
||||
<% @user.notes.each do |note| %>
|
||||
<p><em><%= note.created_at.strftime("%d %B %Y %H:%M UTC") %> by <%= User.find(note.author_id).username if note.author_id.present? %></em> -
|
||||
<% if !note.reason.blank? %><strong><%= note.reason %>:</strong>
|
||||
<div class="col-12">
|
||||
<h2>Notes</h2>
|
||||
<% if @user.notes.count > 0 %>
|
||||
<% @user.notes.each do |note| %>
|
||||
<p><em><%= note.created_at.strftime("%d %B %Y %H:%M UTC") %> by <%= User.find(note.author_id).username if note.author_id.present? %></em> -
|
||||
<% if !note.reason.blank? %><strong><%= note.reason %>:</strong>
|
||||
<% end %><%= note.content %></p>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p><em>No notes yet!</em></p>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p><em>No notes yet!</em></p>
|
||||
<% end %>
|
||||
<%= form_for [:internal, @user] do |f| %>
|
||||
<%= f.label "Add new note: " %>
|
||||
<br>
|
||||
<%= f.text_area :new_note %>
|
||||
<br>
|
||||
<%= f.submit "Submit Note" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= form_for [:internal, @user], html: { class: "mb-2" } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label "Add new note: ", class: "d-block" %>
|
||||
<%= f.text_area :new_note, class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Submit Note", class: "btn btn-primary float-right" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,38 +1,40 @@
|
|||
<div class="row">
|
||||
<h3><u>Organization Memberships</u></h3>
|
||||
<% if @user.organization_memberships.size.positive? %>
|
||||
<ul>
|
||||
<div class="col-12">
|
||||
<h2>Organization Memberships</h2>
|
||||
<h3>Add to New Organization</h3>
|
||||
<%= form_for [:internal, OrganizationMembership.new], html: { class: "form-inline justify-content-between my-3" } do |f| %>
|
||||
<%= f.hidden_field :user_id, value: @user.id %>
|
||||
<div class="form-group">
|
||||
<%= f.label "Organization ID:", class: "mr-3" %>
|
||||
<%= f.text_field :organization_id, class: "form-control mr-3", size: 8 %>
|
||||
<%= f.label "Membership Level:", class: "mr-3" %>
|
||||
<%= f.select(:type_of_user, options_for_select(%w[member admin])) %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.submit "Add to Org", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @user.organization_memberships.size.positive? %>
|
||||
<h3>Manage Memberships</h3>
|
||||
<hr>
|
||||
<% @user.organization_memberships.includes(:organization).each do |org_membership| %>
|
||||
<li>
|
||||
<u><b><%= org_membership.type_of_user.capitalize %> of:</b></u>
|
||||
<h3>
|
||||
<a href="<%= org_membership.organization.path %>" target="_blank" rel="noopener">
|
||||
<%= org_membership.organization.name %>
|
||||
</a>
|
||||
<%= form_for [:internal, org_membership] do |f| %>
|
||||
<%= f.label "Change permission level:" %>
|
||||
</h3>
|
||||
<%= form_for [:internal, org_membership], html: { class: "form-inline justify-content-between" } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label "Permission Level:", class: "mr-3" %>
|
||||
<%= f.select("type_of_user", options_for_select(%w[member admin], selected: org_membership.type_of_user)) %>
|
||||
<%= f.submit "Submit", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
<%= form_for([:internal, org_membership], html: { method: :delete, onsubmit: "return confirm('Are you sure you want to remove them from #{org_membership.organization.name}?)" }) do |f| %>
|
||||
<%= f.submit "Remove from org", class: "btn btn-danger" %>
|
||||
<% end %>
|
||||
</li>
|
||||
</div>
|
||||
<%= f.submit "Update Permissions", class: "btn btn-primary " %>
|
||||
<% end %>
|
||||
<%= form_for([:internal, org_membership], html: { method: :delete, onsubmit: "return confirm('Are you sure you want to remove them from #{org_membership.organization.name}?)", class: "d-flex justify-content-end my-2" }) do |f| %>
|
||||
<%= f.submit "Remove From Org", class: "btn btn-danger" %>
|
||||
<% end %>
|
||||
<hr>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<h4>Add to New Organization</h4>
|
||||
<ul>
|
||||
<%= form_for [:internal, OrganizationMembership.new] do |f| %>
|
||||
<%= f.hidden_field :user_id, value: @user.id %>
|
||||
<li>
|
||||
Organization ID:
|
||||
<%= f.text_field :organization_id %>
|
||||
</li>
|
||||
<li>
|
||||
Membership Level:
|
||||
<%= f.select(:type_of_user, options_for_select(%w[member admin])) %>
|
||||
<%= f.submit "Add to Org", class: "btn btn-primary" %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,159 +1,167 @@
|
|||
<h1>
|
||||
<%= @user.name %><a href="/<%= @user.username %>" target="_blank"> (@<%= @user.username %>)</a>
|
||||
</h1>
|
||||
<p>
|
||||
<u><a style="color: green" href="/internal/users/<%= @user.id %>">click here view user details & take other actions</a></u>
|
||||
</p>
|
||||
<p><em>Member since <%= @user.created_at.strftime("%b %e '%y") %></em></p>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2 class="d-inline">
|
||||
<%= @user.name %><a href="/<%= @user.username %>" target="_blank"> (@<%= @user.username %>)</a>
|
||||
</h2>
|
||||
<a href="<%= internal_user_path(@user) %>" class="btn btn-primary float-right">Internal Profile</a>
|
||||
<p class="font-italic">Member since <%= @user.created_at.strftime("%b %e '%y") %></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "internal/users/activity" %>
|
||||
|
||||
<div class="row">
|
||||
<h2>User Status</h2>
|
||||
<% if @user.banned %>
|
||||
<p style="background-color:red;color:white">🚨 Member is suspended 🚨</p>
|
||||
<% elsif @user.warned %>
|
||||
<p style="background-color: orange;color:white">Member is warned</p>
|
||||
<% elsif @user.comment_banned %>
|
||||
<p style="background-color: orange;color:white">Member is comment banned</p>
|
||||
<% elsif @user.trusted %>
|
||||
<p style="background-color: green;color:white">Member is trusted</p>
|
||||
<% else %>
|
||||
<p style="color:green">Member is in good standing</p>
|
||||
<% end %>
|
||||
<p><strong>Current Roles</strong><em> (view full history in notes below)</em>:</p>
|
||||
<ul>
|
||||
<% if @user.roles.empty? %>
|
||||
<li>Regular Member</li>
|
||||
<% end %>
|
||||
<% @user.roles.each do |role| %>
|
||||
<li><%= role.name %> <em><%= "- " + Tag.find(role.resource_id).name if role.resource_id.present? %></em></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<%= form_for(@user, url: user_status_internal_user_path(@user)) do |f| %>
|
||||
<%= f.label "Select new user status" %>
|
||||
<%= f.select(:user_status, options_for_select(["Warn", "Comment Ban", "Ban", "Regular Member", "Trusted", "Pro"]), include_blank: true) %>
|
||||
<br>
|
||||
<%= f.label "Reason for action:" %>
|
||||
<%= f.text_area :note_for_current_role, required: true %>
|
||||
<br>
|
||||
<%= f.submit "Update User Status" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render "notes" %>
|
||||
<header class="internal-edit-header">
|
||||
<h2>Remove Identity</h2>
|
||||
<button type="button" data-toggle="collapse" data-target="#identity-row">Toggle</button>
|
||||
</header>
|
||||
<div class="row collapse" id="identity-row">
|
||||
<p>Removing a social account identity can solve certain sign in issues, for example:</p>
|
||||
<ul>
|
||||
<li>
|
||||
They created an account on dev.to, but deleted their original social account and recreated it with the same Twitter/GitHub username.
|
||||
This will be true if their Twitter/GitHub account's UID does not match their identity's UID. You can use the following third party tools to check:
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://tweeterid.com/?username=<%= @user.twitter_username %>" target="_blank" rel="noopener nofollow">Tweeter ID for Twitter (username is in URL for reference)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://caius.github.io/github_id/#<%= @user.github_username %>" target="_blank" rel="noopener nofollow">Caius's GitHub ID Lookup Tool</a>
|
||||
</li>
|
||||
</ul>
|
||||
Steps to check:
|
||||
<ol>
|
||||
<li>Click one of the links to check their social account's UID.</li>
|
||||
<li>Confirm whether or not it matches with the identity's UID.</li>
|
||||
<li>If it doesn't match, delete the respective identity.</li>
|
||||
<li>Ask the user to reauthorize their social account via https://dev.to/settings/account</li>
|
||||
</ol>
|
||||
</li>
|
||||
<% @user.identities.each do |identity| %>
|
||||
<%= form_for(@user, url: remove_identity_internal_user_path(@user), html: { method: :delete, onsubmit: "return confirm('Are you sure? This should only be done as a solution for the listed example(s).)" }) do |f| %>
|
||||
<%= f.hidden_field :identity_id, value: identity.id %>
|
||||
<p><b><%= identity.provider.capitalize %> UID: <%= identity.uid %> - Username: <%= identity.auth_data_dump["info"]["nickname"] %></b></p>
|
||||
<%= f.submit "Delete #{identity.provider.capitalize} Identity", class: "btn btn-danger" %>
|
||||
<div class="col-12">
|
||||
<h2 class="d-inline">User Status</h2>
|
||||
<h3 class="float-right">
|
||||
<% if @user.banned %>
|
||||
<span class="badge badge-danger">🚨 Member is Suspended 🚨</span>
|
||||
<% elsif @user.warned %>
|
||||
<span class="badge badge-warning">Member is @arned</span>
|
||||
<% elsif @user.comment_banned %>
|
||||
<span class="badge badge-warning">Member is Comment Banned</span>
|
||||
<% elsif @user.trusted %>
|
||||
<span class="badge badge-success">Member is Trusted</span>
|
||||
<% else %>
|
||||
<span class="badge badge-info">Member is in Good Standing</span>
|
||||
<% end %>
|
||||
</h3>
|
||||
<%= form_for(@user, url: user_status_internal_user_path(@user), html: { class: "mt-3" }) do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label "Select new user status", class: "mr-3" %>
|
||||
<%= f.select(:user_status, options_for_select(["Warn", "Comment Ban", "Ban", "Regular Member", "Trusted", "Pro"]), include_blank: true) %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label "Reason for action:" %>
|
||||
<%= f.text_area :note_for_current_role, required: true, class: "form-control" %>
|
||||
</div>
|
||||
<%= f.submit "Update User Status", class: "btn btn-primary float-right" %>
|
||||
<% end %>
|
||||
<h3>This should be done only do this if you are certain the user is having the specific problem(s) listed above.</h3>
|
||||
<% if @user.backup_data.any? %>
|
||||
<hr>
|
||||
<h2>Recover a deleted identity:</h2>
|
||||
<ul>
|
||||
<% @user.backup_data.where(instance_type: "Identity").each do |data| %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "notes" %>
|
||||
|
||||
<div class="row my-3">
|
||||
<div class="col-12">
|
||||
<h2 class="d-inline">Remove Identity</h2>
|
||||
<button type="button" data-toggle="collapse" data-target="#identity-row" class="btn btn-secondary float-right">Toggle</button>
|
||||
</div>
|
||||
<div class="col-12 collapse" id="identity-row">
|
||||
<p>Removing a social account identity can solve certain sign in issues, for example:</p>
|
||||
<ul>
|
||||
<li>
|
||||
They created an account on dev.to, but deleted their original social account and recreated it with the same Twitter/GitHub username.
|
||||
This will be true if their Twitter/GitHub account's UID does not match their identity's UID. You can use the following third party tools to check:
|
||||
<ul>
|
||||
<li>
|
||||
<%= "#{data.json_data['provider'].capitalize} #{data.instance_type} - UID: #{data.json_data['uid']}" %>
|
||||
<%= form_for(@user, url: recover_identity_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Please confirm you want to recover the #{data.json_data['provider'].capitalize} identity.')" }) do |f| %>
|
||||
<%= f.hidden_field :backup_data_id, value: data.id %>
|
||||
<%= f.submit "Recover #{data.json_data['provider'].capitalize} Identity" %>
|
||||
<% end %>
|
||||
<a href="https://tweeterid.com/?username=<%= @user.twitter_username %>" target="_blank" rel="noopener nofollow">Tweeter ID for Twitter (username is in URL for reference)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://caius.github.io/github_id/#<%= @user.github_username %>" target="_blank" rel="noopener nofollow">Caius's GitHub ID Lookup Tool</a>
|
||||
</li>
|
||||
</ul>
|
||||
Steps to check:
|
||||
<ol>
|
||||
<li>Click one of the links to check their social account's UID.</li>
|
||||
<li>Confirm whether or not it matches with the identity's UID.</li>
|
||||
<li>If it doesn't match, delete the respective identity.</li>
|
||||
<li>Ask the user to reauthorize their social account via https://dev.to/settings/account</li>
|
||||
</ol>
|
||||
</li>
|
||||
<% @user.identities.each do |identity| %>
|
||||
<%= form_for(@user, url: remove_identity_internal_user_path(@user), html: { method: :delete, onsubmit: "return confirm('Are you sure? This should only be done as a solution for the listed example(s).)" }) do |f| %>
|
||||
<%= f.hidden_field :identity_id, value: identity.id %>
|
||||
<p><b><%= identity.provider.capitalize %> UID: <%= identity.uid %> - Username: <%= identity.auth_data_dump["info"]["nickname"] %></b></p>
|
||||
<%= f.submit "Delete #{identity.provider.capitalize} Identity", class: "btn btn-danger" %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h2>Merge User</h2>
|
||||
<p>To merge a duplicate account, make sure you are currently on the page of the user you want to KEEP. Below, add the user id of the account to merge information from, and delete.</p>
|
||||
<%= form_for(@user, url: merge_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible. Merging will delete all the other users content and combine it with this user')" }) do |f| %>
|
||||
<%= f.label "User to be deleted:" %>
|
||||
<%= f.text_field :merge_user_id, placeholder: "#ID" %>
|
||||
<%= f.submit "Merge Users" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h2>Banish User</h2>
|
||||
<% if @user.comments.where("created_at < ?", 100.days.ago).empty? && @user.created_at < 100.days.ago %>
|
||||
<p>
|
||||
<em>This is extremely destructive. Banishing will delete all the user's existing content and change their username to @spam_###.</em>
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: banish_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible. Banishing will delete all articles and turn their username into @spam_###')" }) do %>
|
||||
<button class="btn btn-danger" style="font-size:2em;">🚫 Banish User for Spam 🚫</button>
|
||||
<% end %>
|
||||
<% elsif current_user.has_role?(:super_admin) %>
|
||||
<p><strong>This is not a new user.</strong> You are only allowed to take this action because you are a
|
||||
<strong>super admin.</strong></p>
|
||||
<p>
|
||||
<em>This is extremely destructive. Banishing will delete all the user's existing content and change their username to @spam_###.</em>
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: banish_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible. Banishing will delete all articles and turn their username into @spam_###')" }) do %>
|
||||
<button class="btn btn-danger" style="font-size:2em;">Banish User for Spam!</button>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p><em>This is not a new user so you'll need to contact a super admin to banish this user.</em></p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<h3>This should be done only do this if you are certain the user is having the specific problem(s) listed above.</h3>
|
||||
<% if @user.backup_data.any? %>
|
||||
<hr>
|
||||
<h2>Recover a deleted identity:</h2>
|
||||
<ul>
|
||||
<% @user.backup_data.where(instance_type: "Identity").each do |data| %>
|
||||
<li>
|
||||
<%= "#{data.json_data['provider'].capitalize} #{data.instance_type} - UID: #{data.json_data['uid']}" %>
|
||||
<%= form_for(@user, url: recover_identity_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Please confirm you want to recover the #{data.json_data['provider'].capitalize} identity.')" }) do |f| %>
|
||||
<%= f.hidden_field :backup_data_id, value: data.id %>
|
||||
<%= f.submit "Recover #{data.json_data['provider'].capitalize} Identity" %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<h2>Delete User & Turn Content Into Ghost</h2>
|
||||
<% if current_user.has_role?(:super_admin) %>
|
||||
<p>This will
|
||||
<strong>completely destroy the user</strong> and convert all of their articles & comments into a ghost author. This action is irreversible.
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: full_delete_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? 👻 This is extremely destructive and irreversible. The user will be deleted and their articles & comments will be converted to Ghost')" }) do |f| %>
|
||||
<%= f.hidden_field :ghostify, value: true %>
|
||||
<button class="btn btn-danger" style="font-size:2em;">👻 Fully Delete User & Ghostify 👻</button>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p>Only super admins can fully delete users.</p>
|
||||
<% end %>
|
||||
<div class="col-12">
|
||||
<h2 class="d-inline">Destructive Actions</h2>
|
||||
<button type="button" data-toggle="collapse" data-target="#destructive-actions" class="btn btn-secondary float-right">Toggle</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<h2>Fully Delete User</h2>
|
||||
<% if current_user.has_role?(:super_admin) %>
|
||||
<p>This will
|
||||
<strong>completely destroy the user</strong> and all of their activity from our database. This action is irreversible.
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: full_delete_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible.')" }) do |f| %>
|
||||
<%= f.hidden_field :ghostify, value: false %>
|
||||
<button class="btn btn-danger" style="font-size:2em;">☠️ Fully Delete User & All Activity ☠️</button>
|
||||
<div id="destructive-actions" class="row collapse">
|
||||
<div class="col-12">
|
||||
<h3>Merge User</h3>
|
||||
<p>To merge a duplicate account, make sure you are currently on the page of the user you want to KEEP. Below, add the user id of the account to merge information from, and delete.</p>
|
||||
<%= form_for(@user, url: merge_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible. Merging will delete all the other users content and combine it with this user')" }) do |f| %>
|
||||
<%= f.label "User to be deleted:" %>
|
||||
<%= f.text_field :merge_user_id, placeholder: "#ID" %>
|
||||
<%= f.submit "Merge Users", class: "btn btn-danger float-right" %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p>Only super admins can fully delete users.</p>
|
||||
</div>
|
||||
|
||||
<div class="col-12 my-2">
|
||||
<h3>Banish User</h3>
|
||||
<% if @user.comments.where("created_at < ?", 100.days.ago).empty? && @user.created_at < 100.days.ago %>
|
||||
<p>
|
||||
<em>This is extremely destructive. Banishing will delete all the user's existing content and change their username to @spam_###.</em>
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: banish_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible. Banishing will delete all articles and turn their username into @spam_###')" }) do %>
|
||||
<button class="btn btn-danger float-right">🚫 Banish User for Spam 🚫</button>
|
||||
<% end %>
|
||||
<% elsif current_user.has_role?(:super_admin) %>
|
||||
<p><strong>This is not a new user.</strong> You are only allowed to take this action because you are a
|
||||
<strong>super admin.</strong></p>
|
||||
<p>
|
||||
<em>This is extremely destructive. Banishing will delete all the user's existing content and change their username to @spam_###.</em>
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: banish_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible. Banishing will delete all articles and turn their username into @spam_###')" }) do %>
|
||||
<button class="btn btn-danger float-right">Banish User for Spam!</button>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p><em>This is not a new user so you'll need to contact a super admin to banish this user.</em></p>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if current_user.has_role?(:super_admin) %>
|
||||
<div class="col-12 my-2">
|
||||
<h3>Delete User & Turn Content Into Ghost</h3>
|
||||
<p>This will
|
||||
<strong>completely destroy the user</strong> and convert all of their articles & comments into a ghost author. This action is irreversible.
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: full_delete_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? 👻 This is extremely destructive and irreversible. The user will be deleted and their articles & comments will be converted to Ghost')" }) do |f| %>
|
||||
<%= f.hidden_field :ghostify, value: true %>
|
||||
<button class="btn btn-danger float-right">👻 Fully Delete User & Ghostify 👻</button>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="col-12 my-2">
|
||||
<h3>Fully Delete User</h3>
|
||||
<p>This will
|
||||
<strong>completely destroy the user</strong> and all of their activity from our database. This action is irreversible.
|
||||
</p>
|
||||
<p><strong>Do not do this lightly.</strong></p>
|
||||
<%= form_for(@user, url: full_delete_internal_user_path(@user), html: { method: :post, onsubmit: "return confirm('Are you sure? This is extremely destructive and irreversible.')" }) do |f| %>
|
||||
<%= f.hidden_field :ghostify, value: false %>
|
||||
<button class="btn btn-danger float-right">☠️ Fully Delete User & All Activity ☠️</button>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
|
|
|
|||
|
|
@ -1,43 +1,71 @@
|
|||
<style>
|
||||
.alert {
|
||||
border: 2px red solid;
|
||||
}
|
||||
</style>
|
||||
<h3 class="top-nav" style="font-weight:400;font-size:0.9em;">
|
||||
<a href="/internal/users" style="<%= "font-weight:bold" if params[:state].blank? %>">All</a> |
|
||||
<a href="/internal/users?state=role-admin" style="<%= "font-weight:bold" if params[:state] == "role-admin" %>">Admins</a> |
|
||||
<a href="/internal/users?state=role-super_admin" style="<%= "font-weight:bold" if params[:state] == "role-super_admin" %>">Super Admins</a> |
|
||||
<a href="/internal/users?state=role-trusted" style="<%= "font-weight:bold" if params[:state] == "role-trusted" %>">Trusted</a> |
|
||||
<a href="/internal/users?state=role-tag_moderator" style="<%= "font-weight:bold" if params[:state] == "role-tag_moderator" %>">Tag Mods</a>
|
||||
</h3>
|
||||
<%= form_tag("/internal/users", method: "get") do %>
|
||||
<%= label_tag(:search, "Find by:") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
<%= submit_tag("Search") %>
|
||||
<em style="font-size:0.78em;">(<b>fields:</b> name, username, twitter_username, github_username, email)</em>
|
||||
<% end %>
|
||||
<%= paginate @users %>
|
||||
<br>
|
||||
<div class="wrapper" style="font-weight: 600; border-bottom: 2px solid black;">
|
||||
<div>User</div>
|
||||
<div>ID</div>
|
||||
<div>Name</div>
|
||||
<div>Twitter</div>
|
||||
<div>GitHub</div>
|
||||
<div>Email</div>
|
||||
<div class="row m-3">
|
||||
<div class="col">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item">
|
||||
<a href="/internal/users" class="nav-link <%= "active" if params[:state].blank? %>">All</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/users?state=role-admin" class="nav-link <%= "active" if params[:state] == "role-admin" %>">Admins</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/users?state=role-super_admin" class="nav-link <%= "active" if params[:state] == "role-super_admin" %>">Super Admins</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/users?state=role-trusted" class="nav-link <%= "active" if params[:state] == "role-trusted" %>">Trusted</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/internal/users?state=role-tag_moderator" class="nav-link <%= "active" if params[:state] == "role-tag_moderator" %>">Tag Mods</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col">
|
||||
<%= form_tag("/internal/users", method: "get") do %>
|
||||
<div class="form-row justify-content-end">
|
||||
<div class="form-group">
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<% if params[:state].present? %>
|
||||
<%= hidden_field_tag(:state, params[:state]) %>
|
||||
<% end %>
|
||||
<%= submit_tag("Search") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% @users.each do |user| %>
|
||||
<div class="wrapper" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div class="grid-item"><a href="/internal/users/<%= user.id %>" target="_blank">@<%= user.username %></a></div>
|
||||
<div class="grid-item"><%= user.id %></div>
|
||||
<div class="grid-item"><%= user.name %></div>
|
||||
<div class="grid-item"><%= user.twitter_username %></div>
|
||||
<div class="grid-item"><%= user.github_username %></div>
|
||||
<div class="grid-item"><%= user.email %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= paginate @users %>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">User</th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Twitter</th>
|
||||
<th scope="col">GitHub</th>
|
||||
<th scope="col">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @users.each do |user| %>
|
||||
<tr>
|
||||
<td><%= link_to user.username, "/internal/users/#{user.id}/" %></td>
|
||||
<td><%= user.id %></td>
|
||||
<td><%= user.name %></td>
|
||||
<% if user.twitter_username %>
|
||||
<td><%= link_to user.twitter_username, "https://twitter.com/#{user.twitter_username}" %></td>
|
||||
<% else %>
|
||||
<td>N/A</td>
|
||||
<% end %>
|
||||
<% if user.github_username %>
|
||||
<td><%= link_to user.github_username, "https://github.com/#{user.github_username}" %></td>
|
||||
<% else %>
|
||||
<td>N/A</td>
|
||||
<% end %>
|
||||
<td><%= user.email %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @users %>
|
||||
|
|
|
|||
|
|
@ -1,58 +1,64 @@
|
|||
<style>
|
||||
dt {
|
||||
width: calc(20% - 1rem);
|
||||
float: left;
|
||||
}
|
||||
|
||||
dd {
|
||||
width: calc(80% - 1rem)
|
||||
}
|
||||
</style>
|
||||
<div class="row">
|
||||
<h1>
|
||||
<%= @user.name %><a href="/<%= @user.username %>" target="_blank"> (@<%= @user.username %>)</a>
|
||||
</h1>
|
||||
<p><u><a style="color: red" href="/internal/users/<%= @user.id %>/edit">click here to merge, banish, or delete user.</a></u>
|
||||
<div class="col-12">
|
||||
<h2 class="d-inline">
|
||||
<%= @user.name %><a href="/<%= @user.username %>" target="_blank"> (@<%= @user.username %>)</a>
|
||||
</h2>
|
||||
<a href="<%= edit_internal_user_path(@user) %>" class="btn btn-primary float-right">Manage User</a>
|
||||
<p class="font-italic">Member since <%= @user.created_at.strftime("%b %e '%y") %></p>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h2>General Info</h2>
|
||||
<dl>
|
||||
<dt>ID:</dt>
|
||||
<dd><%= @user.id %></span></dd>
|
||||
<dt>Username:</dt>
|
||||
<dd><%= @user.username %></dd>
|
||||
<dt>Name:</dt>
|
||||
<dd><%= @user.name %></dd>
|
||||
<dt>Email:</dt>
|
||||
<dd><%= @user.email %></dd>
|
||||
<dt>Twitter:</dt>
|
||||
<% if @user.twitter_username %>
|
||||
<dd><%= link_to @user.twitter_username, "https://twitter.com/#{@user.twitter_username}" %></dd>
|
||||
<% else %>
|
||||
<dd>N/A</dd>
|
||||
<% end %>
|
||||
<dt>GitHub:</dt>
|
||||
<% if @user.github_username %>
|
||||
<dd><%= link_to @user.github_username, "https://github.com/#{@user.github_username}" %></dd>
|
||||
<% else %>
|
||||
<dd>N/A</dd>
|
||||
<% end %>
|
||||
<dt>Sustaining Member:</dt>
|
||||
<dd><%= @user.a_sustaining_member? %></dd>
|
||||
<% if @user.a_sustaining_member? %>
|
||||
<dt>Monthly Dues:</dt>
|
||||
<dd><%= @user.monthly_dues %></dd>
|
||||
<dt>25% Off Coupon:</dt>
|
||||
<dd><%= CouponGenerator.new(current_user.id, "member_discount").generate %> || "N/A" </dd>
|
||||
<dt>1x Gift:</dt>
|
||||
<dd><%= CouponGenerator.new(current_user.id, "tee_pack").generate %> || "N/A" </dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
</p>
|
||||
<p><em>Member since <%= @user.created_at.strftime("%b %e '%y") %></em></p>
|
||||
<p><strong><u>General Info</u></strong></p>
|
||||
<dl>
|
||||
<dt>ID:</dt>
|
||||
<dd><%= @user.id %></span></dd>
|
||||
<dt>Username:</dt>
|
||||
<dd><%= @user.username %></dd>
|
||||
<dt>Name:</dt>
|
||||
<dd><%= @user.name %></dd>
|
||||
<dt>Email:</dt>
|
||||
<dd><%= @user.email %></dd>
|
||||
<dt>Twitter:</dt>
|
||||
<dd><%= @user.twitter_username || "N/A" %></dd>
|
||||
<dt>GitHub:</dt>
|
||||
<dd><%= @user.github_username || "N/A" %></dd>
|
||||
<dt>Sustaining Member:</dt>
|
||||
<dd><%= @user.a_sustaining_member? %></dd>
|
||||
<% if @user.a_sustaining_member? %>
|
||||
<dt>Monthly Dues:</dt>
|
||||
<dd><%= @user.monthly_dues %></dd>
|
||||
<dt>25% Off Coupon:</dt>
|
||||
<dd><%= CouponGenerator.new(current_user.id, "member_discount").generate %> || "N/A" </dd>
|
||||
<dt>1x Gift:</dt>
|
||||
<dd><%= CouponGenerator.new(current_user.id, "tee_pack").generate %> || "N/A" </dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<%= render "activity" %>
|
||||
<%= render "credits" %>
|
||||
<%= render "notes" %>
|
||||
<%= render "user_organizations" %>
|
||||
<div class="row">
|
||||
<h2><u>Recent Emails</u></h2>
|
||||
<ul>
|
||||
<% @user.email_messages.order("sent_at DESC").limit(50).each do |email| %>
|
||||
<li><a href="/admin/email_messages/<%= email.id %>"><%= email.subject %></a>
|
||||
<em><%= email.sent_at&.strftime("%b %e '%y") %></em></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
<h2>Recent Emails</h2>
|
||||
<div class="list-group-flush">
|
||||
<% @user.email_messages.order("sent_at DESC").limit(50).each do |email| %>
|
||||
<a href="/admin/email_messages/<%= email.id %>" class="list-group-item list-group-item-action">
|
||||
<%= email.subject %>
|
||||
<em> - <%= email.sent_at&.strftime("%b %e '%y") %></em>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
|
|
|
|||
|
|
@ -1,24 +1,28 @@
|
|||
<h1>Webhook Endpoints</h1>
|
||||
<%= paginate @endpoints %>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Target URL</th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Events</th>
|
||||
<th scope="col">Source</th>
|
||||
<th scope="col">User</th>
|
||||
<th scope="col">Created at</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @endpoints.each do |endpoint| %>
|
||||
<tr>
|
||||
<td><%= link_to endpoint.target_url, endpoint.target_url %></td>
|
||||
<td><%= endpoint.id %></td>
|
||||
<td><%= endpoint.events.join(", ") %></td>
|
||||
<td><%= endpoint.source %></td>
|
||||
<td><%= link_to endpoint.user.username, endpoint.user.path %></td>
|
||||
<td><%= endpoint.created_at.strftime("%H:%M %d %b %Y") %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @endpoints %>
|
||||
<br>
|
||||
<div class="wrapper" style="font-weight: 600; border-bottom: 2px solid black;">
|
||||
<div>Target URL</div>
|
||||
<div>ID</div>
|
||||
<div>Events</div>
|
||||
<div>Source</div>
|
||||
<div>User</div>
|
||||
<div>Created at</div>
|
||||
</div>
|
||||
|
||||
<% @endpoints.each do |endpoint| %>
|
||||
<div class="wrapper" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div class="grid-item"><%= endpoint.target_url %></a></div>
|
||||
<div class="grid-item"><%= endpoint.id %></div>
|
||||
<div class="grid-item"><%= endpoint.events.join(", ") %></a></div>
|
||||
<div class="grid-item"><%= endpoint.source %></div>
|
||||
<div class="grid-item"><%= link_to endpoint.user.username, endpoint.user.path %></div>
|
||||
<div class="grid-item"><%= endpoint.created_at.strftime("%H:%M %d %b %Y") %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= paginate @endpoints %>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
<div class="notice"><%= flash[:notice] %></div>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= link_to "Create A New Welcome Thread", "/internal/welcome", method: :post %>
|
||||
<h1>All Welcome Threads</h1>
|
||||
|
||||
<div class="row justify-content-end">
|
||||
<%= link_to "Create A New Welcome Thread", "/internal/welcome", method: :post, class: "btn btn-primary" %>
|
||||
</div>
|
||||
|
||||
<h2>All Welcome Threads</h2>
|
||||
<hr>
|
||||
<% @daily_threads.each do |thread| %>
|
||||
<a href="<%= thread.path %>"><%= thread.title %></a>
|
||||
<hr style="border-top: dotted 1px;">
|
||||
<% end %>
|
||||
|
||||
<div class="row">
|
||||
<div class="list-group-flush">
|
||||
<% @daily_threads.each do |thread| %>
|
||||
<a class="list-group-item list-group-item-action" href="<%= thread.path %>"><%= thread.title %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,173 +9,48 @@
|
|||
<meta name="author" content="">
|
||||
<%= csrf_meta_tags %>
|
||||
<%= favicon_link_tag ApplicationConfig["FAVICON_URL"] %>
|
||||
<title><%= controller_name.titleize %></title>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Bootstrap and FontAwesome -->
|
||||
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||
|
||||
<title><%= controller_name %></title>
|
||||
<%= stylesheet_link_tag "internal/layout" %>
|
||||
|
||||
<%# Latest compiled and minified CSS %>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
|
||||
<%# Optional theme %>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
||||
|
||||
<%# Latest compiled and minified JavaScript %>
|
||||
<%= javascript_include_tag "internal" %>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<style>
|
||||
.starter-template {
|
||||
padding-top: 5em;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-top: 1vw;
|
||||
border: 1px solid gray;
|
||||
padding: 1vw;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 25% 15% 15% 15% 15% 15%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.wrapper-8 {
|
||||
display: grid;
|
||||
grid-template-columns: 4% 15% 25% 7% 7% 7% 20% 15%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.wrapper-3 {
|
||||
display: grid;
|
||||
grid-template-columns: 25% 40% 25%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.wrapper-3 div {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.inner-row form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.flex-column form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-column textarea {
|
||||
font-size: 12px;
|
||||
width: 45%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-size: 12px;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-width: 100px;
|
||||
width: fit-content;
|
||||
width: -moz-fit-content;
|
||||
width: -webkit-fit-content;
|
||||
}
|
||||
|
||||
.single-internal-listing {
|
||||
border-bottom: 1px solid grey;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.buffering-area-for-single-listing {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 10px solid white;
|
||||
}
|
||||
|
||||
.tab-current {
|
||||
border-bottom: 10px solid rgb(193, 209, 224);
|
||||
}
|
||||
|
||||
.tab-current .btn {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.row-plain {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.featured-bg {
|
||||
background: #bbffd2
|
||||
}
|
||||
|
||||
.approved-bg {
|
||||
background: #92e8ae;
|
||||
border: 12px solid #ff9900;
|
||||
}
|
||||
|
||||
.highlighted-bg {
|
||||
background: #2effa8 !important;
|
||||
border: 20px solid black;
|
||||
}
|
||||
|
||||
.submitting-no-border {
|
||||
background: #96f2cc !important;
|
||||
}
|
||||
|
||||
.highlighted-no-border {
|
||||
background: #2effa8 !important;
|
||||
}
|
||||
|
||||
.highlighted-no-border input[type="submit"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.highlighted-border {
|
||||
border: 20px solid black;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<nav class="navbar navbar-expand-xl navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">
|
||||
<img src="<%= asset_path("rainbowdev.svg") %>" width="30" height="30" class="d-inline-block align-top" alt="DEV Logo">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<%= render "internal/shared/navbar" %>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="starter-template">
|
||||
<% flash.each do |type, message| %>
|
||||
<div class="alert alert-<%= type %>">
|
||||
<button class="close" data-dismiss="alert">X</button>
|
||||
<%= message %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= yield %>
|
||||
</div>
|
||||
<div class="container mt-3">
|
||||
<% flash.each do |type, message| %>
|
||||
<div class="alert alert-<%= type %>">
|
||||
<button class="close" data-dismiss="alert">
|
||||
<i class="fa fa-times" aria-hidden="true"></i>
|
||||
</button>
|
||||
<%= message %>
|
||||
</div>
|
||||
<% end %>
|
||||
<h1><%= controller_name.titleize %></h1>
|
||||
<%= yield %>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap Dependencies -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
|
||||
<%= javascript_include_tag "internal" %>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -31,3 +31,4 @@ Rails.application.config.assets.precompile += %w[classified_listings.css]
|
|||
Rails.application.config.assets.precompile += %w[lib/xss.js]
|
||||
Rails.application.config.assets.precompile += %w[lib/pulltorefresh.js]
|
||||
Rails.application.config.assets.precompile += %w[internal.js]
|
||||
Rails.application.config.assets.precompile += %w[internal/layout]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue