Add mailroom

This commit is contained in:
Max Wofford 2025-05-14 12:32:38 -04:00
parent 55503499ff
commit 46f192297e
7 changed files with 97 additions and 8 deletions

View file

@ -0,0 +1,9 @@
module My
class MailroomController < ApplicationController
def index
@user = current_user
@physical_mails = @user.physical_mails.order(created_at: :desc)
@has_mailing_address = @user.mailing_address.present?
end
end
end

View file

@ -15,14 +15,14 @@ class CheckStreakPhysicalMailJob < ApplicationJob
over_7_day_streaks = streaks.select { |_, streak| streak > 7 }.keys
over_7_day_streaks.each do |user_id|
next if PhysicalMail.going_out.exists?(user_id: user_id, mission_type: :first_streak)
next if PhysicalMail.going_out.exists?(user_id: user_id, mission_type: :first_time_7_streak)
user = User.find(user_id)
# Create the physical mail record
PhysicalMail.create!(
user: user,
mission_type: :first_streak,
mission_type: :first_time_7_streak,
status: :pending
)
end

View file

@ -10,19 +10,35 @@ class PhysicalMail < ApplicationRecord
}
enum :mission_type, {
hackatime_first_time_7_streak: 0
admin_mail: 0,
first_time_7_streak: 1
}
def link_to_theseus
return nil if theseus_id.nil?
"https://hack.club/#{theseus_id}"
end
def deliver!
slug = "hackatime_#{mission_type.to_s.underscore.gsub("_", "-")}"
slug = "hackatime-#{mission_type.to_s.gsub("_", "-")}"
flavors = FlavorText.compliment
flavors.concat(FlavorText.rare_compliment) if rand(10) == 0
# authorization: Bearer <token>
response = HTTP.auth("Bearer #{ENV["MAIL_HACKCLUB_TOKEN"]}").post("https://mail.hackclub.com/api/v1/letter_queues/#{slug}", json: {
recipient_email: user.email,
address: user_address,
recipient_email: user.email_addresses.first.email,
address: {
first_name: user.mailing_address.first_name,
last_name: user.mailing_address.last_name,
line_1: user.mailing_address.line_1,
line_2: user.mailing_address.line_2,
city: user.mailing_address.city,
state: user.mailing_address.state,
postal_code: user.mailing_address.zip_code,
country: user.mailing_address.country
},
rubber_stamps: flavors.sample,
idempotency_key: "physical_mail_#{id}",
metadata: {
@ -31,7 +47,9 @@ class PhysicalMail < ApplicationRecord
})
if response.status.success?
update(status: :sent)
data = JSON.parse(response.body.to_s)
puts "Successfully delivered physical mail: #{data["id"]}"
update(status: :sent, theseus_id: data["id"])
else
update(status: :failed)
raise "Failed to deliver physical mail: #{response.body}"
@ -44,6 +62,6 @@ class PhysicalMail < ApplicationRecord
private
def user_address
user.address
user.mailing_address
end
end

View file

@ -19,6 +19,7 @@ class User < ApplicationRecord
has_many :sign_in_tokens, dependent: :destroy
has_many :project_repo_mappings
has_one :mailing_address, dependent: :destroy
has_many :physical_mails
has_many :hackatime_heartbeats,
foreign_key: :user_id,

View file

@ -0,0 +1,55 @@
<% content_for :title do %>
Mailroom
<% end %>
<main class="container">
<header>
<h1>The Mailroom</h1>
</header>
<% if @has_mailing_address %>
<section class="mailing-address-status">
<p class="super">
Your mailing address is set up and ready to receive mail!
<%= link_to "View my mailing address", my_mailing_address_path %>
</p>
</section>
<% else %>
<section class="mailing-address-status warning">
<h2>Mailing Address Required</h2>
<p>You need to add your mailing address for your mail to be sent.</p>
<%= link_to "Add my address", edit_my_mailing_address_path, class: "button" %>
</section>
<% end %>
<section class="physical-mail">
<h2>My Mail</h2>
<% if @physical_mails.any? %>
<div class="mail-list" style="display: flex; flex-direction: column; gap: 1.5rem; margin-top: 1rem;">
<% @physical_mails.each do |mail| %>
<% theseus_link = mail.link_to_theseus %>
<div class="mail-card" style="background: #23272f; border-radius: 12px; padding: 1.25rem 1.5rem; box-shadow: 0 2px 8px rgba(0,0,0,0.08); border: 1px solid #333; position: relative;">
<% if theseus_link %>
<a href="<%= theseus_link %>" target="_blank" style="position: absolute; inset: 0; z-index: 1;"></a>
<% end %>
<div style="position: relative; z-index: 2;">
<h3 style="margin: 0 0 0.5rem 0; font-size: 1.25rem; font-weight: 600;">
<%= mail.mission_type.titleize %>
<% if theseus_link %>
<span style="font-size: 0.9em; margin-left: 0.5em; color: #6cf;">↗</span>
<% end %>
</h3>
<p style="margin: 0.25rem 0; color: #aaa;">Status: <%= mail.status.titleize %></p>
<p style="margin: 0.25rem 0; color: #aaa;">Created: <%= mail.created_at.strftime("%B %d, %Y") %></p>
<% if theseus_link %>
<p style="margin: 0.5rem 0 0 0;"><a href="<%= theseus_link %>" target="_blank" style="color: #6cf; text-decoration: underline;">View on Theseus</a></p>
<% end %>
</div>
</div>
<% end %>
</div>
<% else %>
<p>No mail yet. Keep coding to earn rewards!</p>
<% end %>
</section>
</main>

View file

@ -62,6 +62,11 @@
Mailing Address
<% end %>
<% end %>
<li>
<%= link_to my_mailroom_path, class: "nav-item #{current_page?(my_mailroom_path) ? 'active' : ''}" do %>
Mailroom
<% end %>
</li>
<% admin_tool(nil, "li") do %>
<%= link_to ahoy_captain_path, class: "nav-item #{current_page?(ahoy_captain_path) ? 'active' : ''}" do %>
Ahoy Captain

View file

@ -78,6 +78,7 @@ Rails.application.routes.draw do
namespace :my do
resources :project_repo_mappings, param: :project_name, only: [ :edit, :update ]
resource :mailing_address, only: [ :show, :edit ]
get "mailroom", to: "mailroom#index"
end
get "my/wakatime_setup", to: "users#wakatime_setup"