154 lines
5.5 KiB
Ruby
154 lines
5.5 KiB
Ruby
module ApplicationHelper
|
|
include Pagy::Frontend if defined?(Pagy)
|
|
|
|
# Helper method for time period selector styling
|
|
def time_period_class(period)
|
|
base_classes = "px-4 py-2 text-sm font-medium border-r border-gray-300 last:border-r-0"
|
|
|
|
if @time_period == period
|
|
base_classes + " bg-blue-600 text-white"
|
|
else
|
|
base_classes + " text-gray-700 hover:bg-gray-50"
|
|
end
|
|
end
|
|
|
|
# Custom pagination with Tailwind CSS styling
|
|
def pagy_nav_tailwind(pagy, pagy_id: nil)
|
|
return '' if pagy.pages <= 1
|
|
|
|
html = '<nav class="flex items-center justify-between" aria-label="Pagination">'
|
|
html += '<div class="flex-1 flex justify-between sm:hidden">'
|
|
|
|
if pagy.prev
|
|
html += link_to('← Previous', pagy_url_for(pagy, pagy.prev),
|
|
class: 'relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50')
|
|
else
|
|
html += '<span class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-300 bg-gray-100 cursor-not-allowed">← Previous</span>'
|
|
end
|
|
|
|
if pagy.next
|
|
html += link_to('Next →', pagy_url_for(pagy, pagy.next),
|
|
class: 'ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50')
|
|
else
|
|
html += '<span class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-300 bg-gray-100 cursor-not-allowed">Next →</span>'
|
|
end
|
|
|
|
html += '</div>'
|
|
html += '<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">'
|
|
html += '<div>'
|
|
html += '<p class="text-sm text-gray-700">'
|
|
html += 'Showing'
|
|
html += " <span class=\"font-medium\">#{pagy.from}</span>"
|
|
html += ' to'
|
|
html += " <span class=\"font-medium\">#{pagy.to}</span>"
|
|
html += ' of'
|
|
html += " <span class=\"font-medium\">#{pagy.count}</span>"
|
|
html += ' results'
|
|
html += '</p>'
|
|
html += '</div>'
|
|
html += '<div>'
|
|
html += '<nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">'
|
|
|
|
# Previous button
|
|
if pagy.prev
|
|
html += link_to('←', pagy_url_for(pagy, pagy.prev),
|
|
class: 'relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50')
|
|
else
|
|
html += '<span class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-gray-50 text-sm font-medium text-gray-300 cursor-not-allowed">←</span>'
|
|
end
|
|
|
|
# Page numbers
|
|
pagy.series.each do |item|
|
|
case item
|
|
when Integer
|
|
if item == pagy.page
|
|
html += "<span aria-current=\"page\" class=\"relative inline-flex items-center px-4 py-2 border border-blue-500 bg-blue-500 text-sm font-medium text-white\">#{item}</span>"
|
|
else
|
|
html += link_to(item, pagy_url_for(pagy, item),
|
|
class: 'relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50')
|
|
end
|
|
when String
|
|
html += "<span class=\"relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700\">#{item}</span>"
|
|
when :gap
|
|
html += "<span class=\"relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700\">...</span>"
|
|
end
|
|
end
|
|
|
|
# Next button
|
|
if pagy.next
|
|
html += link_to('→', pagy_url_for(pagy, pagy.next),
|
|
class: 'relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50')
|
|
else
|
|
html += '<span class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-gray-50 text-sm font-medium text-gray-300 cursor-not-allowed">→</span>'
|
|
end
|
|
|
|
html += '</nav>'
|
|
html += '</div>'
|
|
html += '</div>'
|
|
html += '</nav>'
|
|
|
|
raw html
|
|
end
|
|
|
|
# Helper methods for job queue status colors
|
|
def job_queue_status_color(status)
|
|
case status.to_s
|
|
when 'healthy'
|
|
'bg-green-500'
|
|
when 'warning'
|
|
'bg-yellow-500'
|
|
when 'critical'
|
|
'bg-red-500'
|
|
when 'error'
|
|
'bg-gray-500'
|
|
else
|
|
'bg-blue-500'
|
|
end
|
|
end
|
|
|
|
def job_queue_status_text_color(status)
|
|
case status.to_s
|
|
when 'healthy'
|
|
'text-green-600'
|
|
when 'warning'
|
|
'text-yellow-600'
|
|
when 'critical'
|
|
'text-red-600'
|
|
when 'error'
|
|
'text-gray-600'
|
|
else
|
|
'text-blue-600'
|
|
end
|
|
end
|
|
|
|
# Parse user agent string into readable components
|
|
def parse_user_agent(user_agent)
|
|
return nil if user_agent.blank?
|
|
|
|
client = DeviceDetector.new(user_agent)
|
|
|
|
{
|
|
name: client.name,
|
|
version: client.full_version,
|
|
os_name: client.os_name,
|
|
os_version: client.os_full_version,
|
|
device_type: client.device_type || "desktop",
|
|
device_name: client.device_name,
|
|
bot: client.bot?,
|
|
bot_name: client.bot_name,
|
|
raw: user_agent
|
|
}
|
|
end
|
|
|
|
# Convert country code to flag emoji
|
|
def country_flag(country_code)
|
|
return "" if country_code.blank?
|
|
|
|
# Convert ISO 3166-1 alpha-2 country code to flag emoji
|
|
# Each letter is converted to its regional indicator symbol
|
|
country_code.upcase.chars.map { |c| (c.ord + 127397).chr(Encoding::UTF_8) }.join
|
|
rescue
|
|
""
|
|
end
|
|
end
|