Skip to content

Commit 96b47c8

Browse files
committed
Implement Newsletter CRUD for Admin
1 parent 8b87259 commit 96b47c8

File tree

12 files changed

+199
-26
lines changed

12 files changed

+199
-26
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
class Admin::NewslettersController < ApplicationController
2+
before_action :set_newsletter, only: %i[show edit update destroy]
3+
4+
# GET /admin/newsletters
5+
def index
6+
@newsletters = Newsletter.all
7+
end
8+
9+
# GET /admin/newsletters/1
10+
def show
11+
end
12+
13+
# GET /admin/newsletters/new
14+
def new
15+
@newsletter = Newsletter.new(newsletter_params)
16+
end
17+
18+
# GET /admin/newsletters/1/edit
19+
def edit
20+
end
21+
22+
# POST /admin/newsletters
23+
def create
24+
@newsletter = Newsletter.new(newsletter_params)
25+
26+
if @newsletter.save
27+
redirect_to [:admin, @newsletter], notice: "Newsletter was successfully created."
28+
else
29+
render :new, status: :unprocessable_entity
30+
end
31+
end
32+
33+
# PATCH/PUT /admin/newsletters/1
34+
def update
35+
if @newsletter.update(newsletter_params)
36+
redirect_to [:admin, @newsletter], notice: "Newsletter was successfully updated.", status: :see_other
37+
else
38+
render :edit, status: :unprocessable_entity
39+
end
40+
end
41+
42+
# DELETE /admin/newsletters/1
43+
def destroy
44+
@newsletter.destroy!
45+
redirect_to admin_newsletter_url, notice: "Newsletter was successfully destroyed.", status: :see_other
46+
end
47+
48+
private
49+
50+
# Use callbacks to share common setup or constraints between actions.
51+
def set_newsletter
52+
@newsletter = Newsletter.find(params[:id])
53+
end
54+
55+
# Only allow a list of trusted parameters through.
56+
def newsletter_params
57+
params.fetch(:newsletter, {}).permit(:title, :content)
58+
end
59+
end

app/helpers/markdown_helper.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module MarkdownHelper
2+
def basic_markdown(text)
3+
render Markdown::Base.new(text)
4+
end
5+
end

app/models/newsletter.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
class Newsletter < ApplicationRecord
2+
validates :title, presence: true
3+
validates :content, presence: true
24
end

app/views/admin/home/index.html.erb

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,22 @@
11
<%
22
nav = {
3+
"Newsletters" => admin_newsletters_path,
34
"Flipper" => "/admin/flipper",
45
"Mission Control Jobs" => "/admin/jobs",
56
"Litestream" => "/admin/litestream",
67
}
78
%>
89
<article>
910
<%= render Pages::Header.new(title: "Admin") %>
10-
<div class="container">
11-
<ul role="list" class="divide-y divide-gray-100">
11+
<div class="section-content container">
12+
<ul>
1213
<% nav.each do |label, url| %>
13-
<li class="relative flex py-5">
14-
<div class="flex min-w-0 gap-x-4">
15-
<div class="min-w-0 flex-auto">
16-
<p class="font-semibold leading-6">
17-
<%= link_to url do %>
18-
<span class="absolute inset-x-0 -top-px bottom-0"></span>
19-
<%= label %>
20-
<% end %>
21-
</p>
22-
</div>
23-
</div>
24-
<div class="flex shrink-0 items-center gap-x-4">
25-
<svg class="h-5 w-5 flex-none text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
26-
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
27-
</svg>
28-
</div>
14+
<li>
15+
<p class="font-semibold leading-6">
16+
<%= link_to url do %>
17+
<%= label %>
18+
<% end %>
19+
</p>
2920
</li>
3021
<% end %>
3122
</ul>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<%= form_with(model: [:admin, newsletter], class: "grid grid-gap") do |form| %>
2+
<% if newsletter.errors.any? %>
3+
<div style="color: red">
4+
<h2><%= pluralize(newsletter.errors.count, "error") %> prohibited this newsletter from being saved:</h2>
5+
6+
<ul>
7+
<% newsletter.errors.each do |error| %>
8+
<li><%= error.full_message %></li>
9+
<% end %>
10+
</ul>
11+
</div>
12+
<% end %>
13+
14+
<fieldset>
15+
<%= form.label :title, class: "block" %>
16+
<%= form.text_field :title, class: "flex-1 rounded bg-white/5 focus-ring focus:ring-0 ring-1 ring-inset ring-white/10 w-full lg:min-w-[36ch] " %>
17+
</fieldset>
18+
19+
<fieldset>
20+
<%= form.label :content, class: "block" %>
21+
<%= form.text_area :content, class: "flex-1 rounded bg-white/5 focus-ring focus:ring-0 ring-1 ring-inset ring-white/10 w-full lg:min-w-[36ch]" %>
22+
</fieldset>
23+
24+
<fieldset>
25+
<%= form.submit class: "button primary" %>
26+
<%= form.submit "Preview", class: "button secondary",
27+
formaction: new_admin_newsletter_path,
28+
formmethod: "get",
29+
formnovalidate: true,
30+
data: { turbo_frame: dom_id(newsletter, :markdown) } %>
31+
</fieldset>
32+
33+
<%= turbo_frame_tag dom_id(newsletter, :markdown) do %>
34+
<%= render newsletter %>
35+
<% end %>
36+
<% end %>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div id="<%= dom_id newsletter %>" class="joy-border p-4">
2+
<%= basic_markdown (newsletter&.content || "").html_safe %>
3+
</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<%= render Pages::Header.new(title: "Newsletter: Edit") %>
2+
<div class="section-content container py-gap">
3+
<%= render "form", newsletter: @newsletter %>
4+
5+
<div>
6+
<%= link_to "Show this newsletter", [:admin, @newsletter] %> |
7+
<%= link_to "Back to newsletters", admin_newsletters_path %>
8+
</div>
9+
</div>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<%= render Pages::Header.new(title: "Admin: Newsletters") %>
2+
<div class="section-content container py-gap">
3+
<div class="flex">
4+
<%= link_to "New newsletter", new_admin_newsletter_path, class: "button primary" %>
5+
</div>
6+
<div id="newsletters" class="table">
7+
<div class="table-row">
8+
<div class="table-cell p-2">Title</div>
9+
<div class="table-cell p-2">Sent</div>
10+
<div class="table-cell p-2"></div>
11+
</div>
12+
<% @newsletters.each do |newsletter| %>
13+
<div class="table-row">
14+
<%= link_to newsletter.title, admin_newsletter_path(newsletter), class: "table-cell p-2" %>
15+
<div class="table-cell p-2">
16+
<% if newsletter.sent_at %>
17+
<%= newsletter.sent_at.strftime("%B %d, %Y") %>
18+
<% else %>
19+
<span class="joy-text-subtle">Not sent</span>
20+
<% end %>
21+
</div>
22+
<%= link_to "Edit", edit_admin_newsletter_path(newsletter), class: "table-cell p-2" %>
23+
</div>
24+
<% end %>
25+
<div class="table-row">
26+
<div class="table-cell p-2">This is an Examplle</div>
27+
<div class="table-cell p-2">--</div>
28+
<div class="table-cell p-2">--</div>
29+
</div>
30+
</div>
31+
</div>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<%= render Pages::Header.new(title: "Admin: Create Newsletter") %>
2+
<div class="section-content container py-gap">
3+
<%= render "form", newsletter: @newsletter %>
4+
5+
<div>
6+
<%= link_to "Back to newsletters", admin_newsletters_path %>
7+
</div>
8+
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<%= render Pages::Header.new(title: "Admin: #{@newsletter.title}") %>
2+
<div class="section-content container py-gap">
3+
<%= render @newsletter %>
4+
5+
<div>
6+
<%= link_to "Edit this newsletter", edit_admin_newsletter_path(@newsletter) %> |
7+
<%= link_to "Back to newsletters", admin_newsletters_path %>
8+
9+
<%= button_to "Destroy this newsletter", [:admin, @newsletter], method: :delete %>
10+
</div>
11+
</div>

0 commit comments

Comments
 (0)