feat: Implement promoter payout system for event revenue processing

- Add Payout model with associations to User and Event
- Create payout requests for completed events with proper earnings calculation
- Exclude refunded tickets from payout calculations
- Add promoter dashboard views for managing payouts
- Implement admin interface for processing payouts
- Integrate with Stripe for actual payment processing
- Add comprehensive tests for payout functionality

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
kbe
2025-09-17 00:29:20 +02:00
parent 58141dca94
commit 59e1854803
20 changed files with 587 additions and 254 deletions

View File

@@ -1,2 +1,78 @@
<h1>Admin::Payouts#index</h1>
<p>Find me in app/views/admin/payouts/index.html.erb</p>
<div class="container mx-auto px-4 py-8">
<div class="flex justify-between items-center mb-6">
<h1 class="text-3xl font-bold text-gray-900">Admin Payouts</h1>
</div>
<% if @payouts.any? %>
<div class="bg-white rounded-lg shadow overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Promoter</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<% @payouts.each do |payout| %>
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900"><%= payout.event.name %></div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900"><%= payout.user.name.presence || payout.user.email %></div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">€<%= payout.amount_euros %></div>
<div class="text-sm text-gray-500">Net: €<%= payout.net_amount_euros %> (Fee: €<%= payout.fee_euros %>)</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<% case payout.status %>
<% when 'pending' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">
Pending
</span>
<% when 'processing' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800">
Processing
</span>
<% when 'completed' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
Completed
</span>
<% when 'failed' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">
Failed
</span>
<% end %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<%= payout.created_at.strftime("%b %d, %Y") %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<% if payout.can_process? %>
<%= button_to "Process", admin_payout_path(payout), method: :post,
class: "text-indigo-600 hover:text-indigo-900 bg-indigo-100 hover:bg-indigo-200 px-3 py-1 rounded" %>
<% end %>
<%= link_to "View", promoter_payout_path(payout), class: "text-indigo-600 hover:text-indigo-900 ml-2" %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% if @payouts.respond_to?(:total_pages) %>
<div class="mt-6">
<%= paginate @payouts %>
</div>
<% end %>
<% else %>
<div class="bg-white rounded-lg shadow p-6 text-center">
<p class="text-gray-500">No payouts found.</p>
</div>
<% end %>
</div>

View File

@@ -151,6 +151,15 @@
<%= link_to promoter_event_path(event), class: "text-purple-600 hover:text-purple-800 text-xs font-medium" do %>
Gérer →
<% end %>
<% if event.event_ended? && event.can_request_payout? %>
<% if event.payout_status == "not_requested" %>
<%= link_to "Demander le paiement", promoter_payouts_path(event_id: event.id), method: :post,
class: "text-green-600 hover:text-green-800 text-xs font-medium" %>
<% else %>
<%= link_to "Voir le paiement", promoter_payouts_path,
class: "text-gray-600 hover:text-gray-800 text-xs font-medium" %>
<% end %>
<% end %>
</div>
</div>
<% end %>
@@ -165,41 +174,46 @@
</div>
</div>
<!-- Recent Orders -->
<% if @recent_orders.any? %>
<div class="bg-white rounded-2xl shadow-lg mb-8">
<div class="border-b border-gray-100 p-6">
<h2 class="text-xl font-bold text-gray-900">Commandes Récentes</h2>
<p class="text-gray-600 mt-1">Dernières commandes pour vos événements</p>
<!-- Recent orders for promoter events -->
<div class="mt-8">
<div class="flex justify-between items-center mb-4">
<h2 class="text-lg font-medium text-gray-900">Recent Orders</h2>
<%= link_to "View All Payouts", promoter_payouts_path, class: "text-sm font-medium text-indigo-600 hover:text-indigo-500" if current_user.promoter? %>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="w-full">
<thead>
<tr class="text-left border-b border-gray-200">
<th class="pb-3 text-sm font-medium text-gray-600">Événement</th>
<th class="pb-3 text-sm font-medium text-gray-600">Client</th>
<th class="pb-3 text-sm font-medium text-gray-600">Billets</th>
<th class="pb-3 text-sm font-medium text-gray-600">Montant</th>
<th class="pb-3 text-sm font-medium text-gray-600">Date</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
<% @recent_orders.each do |order| %>
<tr class="hover:bg-gray-50">
<td class="py-3 text-sm font-medium text-gray-900"><%= order.event.name %></td>
<td class="py-3 text-sm text-gray-700"><%= order.user.email %></td>
<td class="py-3 text-sm text-gray-700"><%= order.tickets.count %></td>
<td class="py-3 text-sm font-medium text-gray-900">€<%= order.total_amount_euros %></td>
<td class="py-3 text-sm text-gray-500"><%= order.created_at.strftime("%d/%m/%Y") %></td>
</tr>
<% end %>
</tbody>
</table>
<% if @recent_orders.any? %>
<div class="bg-white overflow-hidden shadow rounded-lg">
<ul class="divide-y divide-gray-200">
<% @recent_orders.each do |order| %>
<li>
<div class="px-4 py-4 flex items-center sm:px-6">
<div class="min-w-0 flex-1 sm:flex sm:items-center sm:justify-between">
<div class="truncate">
<div class="flex text-sm">
<p class="font-medium text-indigo-600 truncate"><%= order.event.name %></p>
<p class="ml-1 flex-shrink-0 font-normal text-gray-500">for <%= order.user.name.presence || order.user.email %></p>
</div>
<div class="mt-2 flex">
<div class="flex items-center text-sm text-gray-500">
<svg class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd" />
</svg>
<span><%= order.created_at.strftime("%B %d, %Y") %></span>
</div>
</div>
</div>
<div class="ml-5 flex-shrink-0">
<p class="text-sm font-medium text-gray-900">€<%= order.total_amount_euros %></p>
</div>
</div>
</div>
</li>
<% end %>
</ul>
</div>
</div>
<% else %>
<p class="text-gray-500">No recent orders.</p>
<% end %>
</div>
<% end %>
<% end %>
<!-- Draft orders needing payment -->

View File

@@ -84,6 +84,36 @@
À la une
</span>
<% end %>
<% if event.event_ended? && event.can_request_payout? %>
<% case event.payout_status %>
<% when "not_requested" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-orange-100 text-orange-800 ml-1">
<i data-lucide="dollar-sign" class="w-3 h-3 mr-1"></i>
Paiement disponible
</span>
<% when "requested" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800 ml-1">
<i data-lucide="clock" class="w-3 h-3 mr-1"></i>
Paiement demandé
</span>
<% when "processing" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800 ml-1">
<i data-lucide="refresh-cw" class="w-3 h-3 mr-1"></i>
Paiement en cours
</span>
<% when "completed" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800 ml-1">
<i data-lucide="check-circle" class="w-3 h-3 mr-1"></i>
Paiement effectué
</span>
<% when "failed" %>
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800 ml-1">
<i data-lucide="x-circle" class="w-3 h-3 mr-1"></i>
Paiement échoué
</span>
<% end %>
<% end %>
</td>
<td class="px-6 py-4 text-sm text-gray-500">
<% if event.start_time %>

View File

@@ -290,6 +290,53 @@
<% end %>
<% end %>
<!-- Payout section -->
<% if @event.event_ended? && @event.can_request_payout? %>
<hr class="border-gray-200">
<div class="space-y-3">
<h4 class="text-md font-medium text-gray-900">Paiement des revenus</h4>
<div class="text-sm text-gray-500">
<p>Revenus disponibles : <span class="font-medium">€<%= @event.net_earnings_cents / 100.0 %></span></p>
<p>Frais de plateforme : <span class="font-medium">€<%= @event.total_fees_cents / 100.0 %></span></p>
</div>
<% if @event.payout_status == "not_requested" %>
<%= button_to promoter_payouts_path(event_id: @event.id), method: :post,
data: { confirm: "Êtes-vous sûr de vouloir demander le paiement des revenus ?" },
class: "w-full inline-flex items-center justify-center px-4 py-3 bg-green-600 text-white font-medium text-sm rounded-lg hover:bg-green-700 transition-colors duration-200" do %>
<i data-lucide="dollar-sign" class="w-4 h-4 mr-2"></i>
Demander le paiement
<% end %>
<% elsif @event.payout_status == "requested" %>
<div class="w-full inline-flex items-center justify-center px-4 py-3 bg-yellow-100 text-yellow-800 font-medium text-sm rounded-lg">
<i data-lucide="clock" class="w-4 h-4 mr-2"></i>
Paiement demandé
</div>
<% elsif @event.payout_status == "processing" %>
<div class="w-full inline-flex items-center justify-center px-4 py-3 bg-blue-100 text-blue-800 font-medium text-sm rounded-lg">
<i data-lucide="refresh-cw" class="w-4 h-4 mr-2"></i>
Paiement en cours
</div>
<% elsif @event.payout_status == "completed" %>
<div class="w-full inline-flex items-center justify-center px-4 py-3 bg-green-100 text-green-800 font-medium text-sm rounded-lg">
<i data-lucide="check-circle" class="w-4 h-4 mr-2"></i>
Paiement effectué
</div>
<% elsif @event.payout_status == "failed" %>
<div class="w-full inline-flex items-center justify-center px-4 py-3 bg-red-100 text-red-800 font-medium text-sm rounded-lg">
<i data-lucide="x-circle" class="w-4 h-4 mr-2"></i>
Paiement échoué
</div>
<%= button_to promoter_payouts_path(event_id: @event.id), method: :post,
data: { confirm: "Êtes-vous sûr de vouloir redemander le paiement des revenus ?" },
class: "w-full inline-flex items-center justify-center px-4 py-3 bg-green-600 text-white font-medium text-sm rounded-lg hover:bg-green-700 transition-colors duration-200" do %>
<i data-lucide="dollar-sign" class="w-4 h-4 mr-2"></i>
Redemander le paiement
<% end %>
<% end %>
</div>
<% end %>
<hr class="border-gray-200">
<%= button_to promoter_event_path(@event), method: :delete,
data: { confirm: "Êtes-vous sûr de vouloir supprimer cet événement ? Cette action est irréversible." },

View File

@@ -1,39 +1,70 @@
<div class="container mx-auto px-4 py-8">
<h1 class="text-3xl font-bold mb-6">My Payouts</h1>
<div class="flex justify-between items-center mb-6">
<h1 class="text-3xl font-bold text-gray-900">Payouts</h1>
</div>
<% if @events.any? %>
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<% @events.each do |event| %>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-semibold mb-2"><%= event.name %></h3>
<p class="text-gray-600 mb-2">Date: <%= event.start_time.strftime('%B %d, %Y at %I:%M %p') %></p>
<p class="text-gray-600 mb-4">Status: <span class="font-medium"><%= event.payout_status.humanize %></span></p>
<% if event.earnings.pending.any? %>
<div class="mb-4">
<p class="text-lg font-semibold text-green-600">Gross: €<%= (event.total_earnings_cents / 100.0).round(2) %></p>
<p class="text-sm text-gray-500">Fees (10%): €<%= (event.total_fees_cents / 100.0).round(2) %></p>
<p class="text-lg font-semibold text-blue-600">Net: €<%= (event.net_earnings_cents / 100.0).round(2) %></p>
</div>
<% if event.can_request_payout? %>
<%= button_to "Request Payout", promoter_payouts_path(event_id: event.id),
method: :post,
class: "w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" %>
<% else %>
<p class="text-sm text-gray-500">Payout not available yet</p>
<% end %>
<% else %>
<p class="text-gray-500">No pending earnings</p>
<% if @payouts.any? %>
<div class="bg-white rounded-lg shadow overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Event</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<% @payouts.each do |payout| %>
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900"><%= payout.event&.name || "Event not found" %></div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">€<%= payout.amount_euros %></div>
<div class="text-sm text-gray-500">Net: €<%= payout.net_amount_euros %> (Fee: €<%= payout.fee_euros %>)</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<% case payout.status %>
<% when 'pending' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">
Pending
</span>
<% when 'processing' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800">
Processing
</span>
<% when 'completed' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
Completed
</span>
<% when 'failed' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">
Failed
</span>
<% end %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<%= payout.created_at.strftime("%b %d, %Y") %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<%= link_to "View", promoter_payout_path(payout), class: "text-indigo-600 hover:text-indigo-900" %>
</td>
</tr>
<% end %>
</div>
<% end %>
</tbody>
</table>
</div>
<% if @payouts.respond_to?(:total_pages) %>
<div class="mt-6">
<%= paginate @payouts %>
</div>
<% end %>
<% else %>
<div class="text-center py-12">
<h2 class="text-2xl font-semibold mb-2">No events found</h2>
<p class="text-gray-600 mb-4">You haven't created any events yet.</p>
<%= link_to "Create Event", new_promoter_event_path, class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" %>
<div class="bg-white rounded-lg shadow p-6 text-center">
<p class="text-gray-500">No payouts found.</p>
</div>
<% end %>
</div>
</div>

View File

@@ -1,58 +1,74 @@
<div class="container mx-auto px-4 py-8">
<h1 class="text-3xl font-bold mb-6"><%= @event.name %> - Payout Details</h1>
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<h2 class="text-xl font-semibold mb-4">Event Summary</h2>
<p><strong>Date:</strong> <%= @event.start_time.strftime('%B %d, %Y at %I:%M %p') %></p>
<p><strong>Venue:</strong> <%= @event.venue_name %></p>
<p><strong>Payout Status:</strong> <span class="font-medium <%= @event.payout_status %>"><%= @event.payout_status.humanize %></span></p>
<% if @event.payout_requested_at %>
<p><strong>Requested:</strong> <%= @event.payout_requested_at.strftime('%B %d, %Y at %I:%M %p') %></p>
<% end %>
<div class="flex justify-between items-center mb-6">
<h1 class="text-3xl font-bold text-gray-900">Payout Details</h1>
<%= link_to "Back to Payouts", promoter_payouts_path, class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
<% if @earnings.any? %>
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-xl font-semibold mb-4">Earnings Breakdown</h2>
<div class="overflow-x-auto">
<table class="min-w-full table-auto">
<thead>
<tr class="bg-gray-100">
<th class="px-4 py-2 text-left">Order</th>
<th class="px-4 py-2 text-left">Gross Amount</th>
<th class="px-4 py-2 text-left">Fee</th>
<th class="px-4 py-2 text-left">Net Amount</th>
<th class="px-4 py-2 text-left">Status</th>
</tr>
</thead>
<tbody>
<% @earnings.each do |earning| %>
<tr class="<%= earning.status == 'pending' ? 'bg-yellow-50' : 'bg-green-50' %>">
<td class="border px-4 py-2">#<%= earning.order_id %></td>
<td class="border px-4 py-2">€<%= (earning.amount_cents / 100.0).round(2) %></td>
<td class="border px-4 py-2">€<%= (earning.fee_cents / 100.0).round(2) %></td>
<td class="border px-4 py-2">€<%= (earning.net_amount_cents / 100.0).round(2) %></td>
<td class="border px-4 py-2">
<span class="px-2 py-1 rounded text-xs <%= earning.status == 'pending' ? 'bg-yellow-200 text-yellow-800' : 'bg-green-200 text-green-800' %>">
<%= earning.status.humanize %>
</span>
</td>
</tr>
<div class="bg-white rounded-lg shadow overflow-hidden">
<div class="px-4 py-5 sm:px-6">
<h3 class="text-lg leading-6 font-medium text-gray-900">Payout Information</h3>
<p class="mt-1 max-w-2xl text-sm text-gray-500">Details about this payout request.</p>
</div>
<div class="border-t border-gray-200">
<dl>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Event</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"><%= @payout.event&.name || "Event not found" %></dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Gross Amount</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">€<%= @payout.amount_euros %></dd>
</div>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Platform Fees</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"><%= @payout.fee_euros %></dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Net Amount</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">€<%= @payout.net_amount_euros %></dd>
</div>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Status</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<% case @payout.status %>
<% when 'pending' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">
Pending
</span>
<% when 'processing' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800">
Processing
</span>
<% when 'completed' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
Completed
</span>
<% when 'failed' %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">
Failed
</span>
<% end %>
</tbody>
</table>
</div>
<div class="mt-4 p-4 bg-gray-50 rounded">
<h3 class="font-semibold">Total Summary</h3>
<p>Gross Total: €<%= (@earnings.sum(:amount_cents) / 100.0).round(2) %></p>
<p>Total Fees: €<%= (@earnings.sum(:fee_cents) / 100.0).round(2) %></p>
<p>Net Total: €<%= (@earnings.sum(:net_amount_cents) / 100.0).round(2) %></p>
</div>
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Total Orders</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"><%= @payout.total_orders_count %></dd>
</div>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Refunded Orders</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"><%= @payout.refunded_orders_count %></dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Requested Date</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"><%= @payout.created_at.strftime("%B %d, %Y at %I:%M %p") %></dd>
</div>
<% if @payout.stripe_payout_id.present? %>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">Stripe Payout ID</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"><%= @payout.stripe_payout_id %></dd>
</div>
<% end %>
</dl>
</div>
<% else %>
<div class="bg-white rounded-lg shadow-md p-6">
<p class="text-gray-500">No earnings recorded for this event.</p>
</div>
<% end %>
</div>
</div>
</div>