Skip to content

Commit 5d0bcae

Browse files
authored
Merge pull request #186 from joyofrails/feat/first-newsletter
Add support for newsletter broadcasts
2 parents 5fac401 + 4fcc98a commit 5d0bcae

File tree

64 files changed

+1057
-69
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1057
-69
lines changed

.github/workflows/verify.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ jobs:
256256
path: public
257257
- run: ls -lahR public
258258
- run: echo ${{ secrets.RAILS_MASTER_WASM_KEY }} > config/credentials/wasm.key
259+
- run: mkdir -p .wasm
259260
- name: Build rails wasm for web
260261
run: TARGET=${{ matrix.target }} bin/wasm/build
261262
- name: Pack rails wasm for web

.wasm/.keep

Whitespace-only changes.

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ gem "vite_rails", group: [:default, :wasm] # Leverage Vite to power the frontend
2323
gem "bcrypt", "~> 3.1.7", group: [:default, :wasm] # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
2424
gem "flipper", group: [:default, :wasm] # Feature flipping for Ruby [https://www.flippercloud.io/]
2525
gem "flipper-active_record" # ActiveRecord adapter for Flipper [https://www.flippercloud.io/docs/adapters/active-record]
26-
gem "flipper-ui" # UI for the Flipper gem [https://www.flippercloud.io/docs/ui]
2726
gem "device_detector" # DeviceDetector is a precise and fast user agent parser and device detector written in Ruby [https://github.com/podigee/device_detector]
2827
gem "warden", group: [:default, :wasm] # General Rack Authentication Framework [https://github.com/wardencommunity/warden]
2928
gem "postmark-rails" # Postmark Rails gem [https://github.com/ActiveCampaign/postmark-rails]
@@ -48,6 +47,8 @@ gem "litestream" # Standalone streaming replication for SQLite [https://litestre
4847
gem "web-push" # Web Push library for Ruby [https://github.com/pushpad/web-push]
4948
gem "fog-aws", require: false # Module for the 'fog' gem to support Amazon Web Services [https://github.com/fog/fog-aws]
5049

50+
# Admin
51+
gem "flipper-ui" # UI for the Flipper gem [https://www.flippercloud.io/docs/ui]
5152
gem "mission_control-jobs" # Dashboard for Active Job [https://github.com/basecamp/mission_control-jobs]
5253

5354
group :development do

app/clients/postmark_client.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class PostmarkClient
2+
def self.deliver_messages(messages)
3+
new.deliver_messages(messages)
4+
end
5+
6+
def deliver_messages(messages)
7+
api_client.deliver_messages(messages)
8+
end
9+
10+
def api_client
11+
@api_client ||= Postmark::ApiClient.new(Rails.configuration.settings.postmark_api_token)
12+
end
13+
end
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
class Admin::NewslettersController < ApplicationController
2+
# GET /admin/newsletters
3+
def index
4+
@newsletters = Newsletter.all
5+
end
6+
7+
# GET /admin/newsletters/1
8+
def show
9+
@newsletter = Newsletter.find(params[:id])
10+
end
11+
12+
# GET /admin/newsletters/new
13+
def new
14+
@newsletter = Newsletter.new(newsletter_params)
15+
end
16+
17+
# GET /admin/newsletters/1/edit
18+
def edit
19+
@newsletter = Newsletter.find(params[:id])
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+
@newsletter = Newsletter.find(params[:id])
36+
37+
if @newsletter.update(newsletter_params)
38+
redirect_to [:admin, @newsletter], notice: "Newsletter was successfully updated.", status: :see_other
39+
else
40+
render :edit, status: :unprocessable_entity
41+
end
42+
end
43+
44+
# DELETE /admin/newsletters/1
45+
def destroy
46+
@newsletter = Newsletter.find(params[:id])
47+
48+
@newsletter.destroy!
49+
50+
redirect_to admin_newsletters_path, notice: "Newsletter was successfully destroyed.", status: :see_other
51+
end
52+
53+
# PATCH /admin/newsletters/1/deliver
54+
def deliver
55+
@newsletter = Newsletter.find(params[:id])
56+
57+
recipients = deliver_live? ? User.subscribers : User.test_recipients
58+
label = deliver_live? ? "LIVE" : "TEST"
59+
60+
if recipients.empty?
61+
return redirect_to [:admin, @newsletter], alert: "No recipients fond."
62+
end
63+
64+
NewsletterNotifier.deliver_to(recipients, newsletter: @newsletter, live: deliver_live?)
65+
66+
redirect_to [:admin, @newsletter], notice: "[#{label}] Newsletter was successfully delivered."
67+
end
68+
69+
private
70+
71+
# Only allow a list of trusted parameters through.
72+
def newsletter_params
73+
params.fetch(:newsletter, {}).permit(:title, :content)
74+
end
75+
76+
def deliver_live? = params[:live] == "true"
77+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class NewslettersController < ApplicationController
2+
def index
3+
@newsletters = Newsletter.sent
4+
end
5+
6+
def show
7+
@newsletter = Newsletter.find(params[:id])
8+
end
9+
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/javascript/controllers/forms/frame.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import debug from '../../utils/debug';
33

44
const console = debug('app:javascript:controllers:forms:frame');
55

6+
// This controller is used to handle form submissions that should redirect out
7+
// of a Turbo Frame.
68
export default class extends Controller {
79
static targets = ['refreshButton'];
810
static values = {

app/javascript/css/application.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@
3535
@import './components/anchors.scss';
3636
@import './components/callout.css';
3737
@import './components/color-scheme.scss';
38+
@import './components/table.css';

app/javascript/css/baseline.css

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ dialog {
247247

248248
textarea {
249249
resize: vertical;
250+
min-height: 18ch;
250251
}
251252

252253
input::-moz-placeholder,
@@ -583,23 +584,6 @@ pre {
583584
overflow-x: auto;
584585
}
585586

586-
button,
587-
input,
588-
optgroup,
589-
select,
590-
textarea {
591-
font-family: inherit;
592-
font-feature-settings: inherit;
593-
font-variation-settings: inherit;
594-
font-size: 100%;
595-
font-weight: inherit;
596-
line-height: inherit;
597-
letter-spacing: inherit;
598-
color: inherit;
599-
margin: 0;
600-
padding: 0;
601-
}
602-
603587
button,
604588
[role='button'] {
605589
cursor: pointer;

0 commit comments

Comments
 (0)