Kris 972cc6e5d9
UX: restyling for 2025 (#28)
This generally updates the styles for the 2025 version. I also made more
features work in development environments (so it's easier to test) and
fixed an issue with invites that was causing the report to not show.


<img width="400" alt="image"
src="https://github.com/user-attachments/assets/69a62b79-12e3-4539-a82c-9bbf9673abe2"
/>

<img width="1554" height="896" alt="image"
src="https://github.com/user-attachments/assets/60fabac5-6f20-4e01-9679-fd228c6850c2"
/>

<img width="754" height="459" alt="image"
src="https://github.com/user-attachments/assets/6725c6e2-1bac-417e-b4ee-190841ab656b"
/>

<img width="1472" height="490" alt="image"
src="https://github.com/user-attachments/assets/87c95e6a-5d78-4fb6-9f2d-dad13bcc9788"
/>

<img width="1480" height="702" alt="image"
src="https://github.com/user-attachments/assets/67bec8f9-dce5-4077-a07d-fe9e13696958"
/>
2025-11-18 09:03:41 -05:00

82 lines
2.6 KiB
Ruby

# frozen_string_literal: true
# Invite statistics
# Shows how many users this user invited and the impact of those invitees
module DiscourseRewind
module Action
class Invites < BaseReport
def call
# Get all invites created by this user in the date range
invites = Invite.where(invited_by_id: user.id).where(created_at: date)
total_invites = invites.count
return if total_invites == 0
# Redeemed invites (users who actually joined)
redeemed_count = invites.where("redemption_count > 0").count
# Get the users who were invited (via InvitedUser or redeemed invites)
invited_user_ids = InvitedUser.where(invite: invites).pluck(:user_id).compact
invited_users = User.where(id: invited_user_ids)
# Calculate impact of invitees
invitee_post_count =
Post.where(user_id: invited_user_ids).where(created_at: date).where(deleted_at: nil).count
invitee_topic_count =
Topic
.where(user_id: invited_user_ids)
.where(created_at: date)
.where(deleted_at: nil)
.count
invitee_like_count =
UserAction
.where(user_id: invited_user_ids)
.where(action_type: UserAction::LIKE)
.where(created_at: date)
.count
# Calculate average trust level of invitees
avg_trust_level = invited_users.average(:trust_level)&.to_f&.round(1) || 0
# Most active invitee
most_active_invitee = nil
if invited_user_ids.any?
most_active_id =
Post
.where(user_id: invited_user_ids)
.where(created_at: date)
.where(deleted_at: nil)
.group(:user_id)
.count
.max_by { |_, count| count }
&.first
if most_active_id
most_active_user = User.find_by(id: most_active_id)
most_active_invitee =
BasicUserSerializer.new(most_active_user, root: false).as_json if most_active_user
end
end
{
data: {
total_invites: total_invites,
redeemed_count: redeemed_count,
redemption_rate:
total_invites > 0 ? (redeemed_count.to_f / total_invites * 100).round(1) : 0,
invitee_post_count: invitee_post_count,
invitee_topic_count: invitee_topic_count,
invitee_like_count: invitee_like_count,
avg_trust_level: avg_trust_level,
most_active_invitee: most_active_invitee,
},
identifier: "invites",
}
end
end
end
end