| 1 | <% content_for :title, @user.username %> |
| 2 | |
| 3 | <div class="mb-4"> |
| 4 | <%= link_to "← All users", admin_users_path, class: "text-sm text-gray-400 hover:text-gray-200" %> |
| 5 | </div> |
| 6 | |
| 7 | <div class="flex flex-wrap items-start justify-between gap-4 mb-6"> |
| 8 | <div class="flex items-center gap-4"> |
| 9 | <img src="<%= @user.avatar_url_or_default %>" alt="" class="w-14 h-14 rounded-full border border-surface-500"> |
| 10 | <div> |
| 11 | <h1 class="text-xl font-semibold text-gray-100 flex items-center gap-2"> |
| 12 | <%= @user.display_name_or_username %> |
| 13 | <% if @user.admin? %><span class="inline-flex items-center rounded bg-brand-500/15 text-brand-300 px-2 py-0.5 text-xs">admin</span><% end %> |
| 14 | </h1> |
| 15 | <p class="text-sm text-gray-500"><%= @user.email %></p> |
| 16 | <p class="text-xs text-gray-600 mt-0.5"> |
| 17 | <%= link_to "@#{@user.username}", user_profile_path(@user.username), class: "hover:text-gray-400", target: "_blank" %> |
| 18 | · smbCloud #<%= @user.smbcloud_id %> · joined <%= @user.created_at.strftime("%b %-d, %Y") %> |
| 19 | </p> |
| 20 | </div> |
| 21 | </div> |
| 22 | |
| 23 | <div class="flex items-center gap-2"> |
| 24 | <% if @user.admin? %> |
| 25 | <%= button_to "Revoke admin", revoke_admin_admin_user_path(@user.username), method: :patch, |
| 26 | form: { data: { turbo_confirm: "Revoke admin access from #{@user.username}?" } }, |
| 27 | class: "px-3 py-1.5 rounded border border-red-800/50 text-red-300 text-sm hover:bg-red-900/30 cursor-pointer" %> |
| 28 | <% else %> |
| 29 | <%= button_to "Grant admin", grant_admin_admin_user_path(@user.username), method: :patch, |
| 30 | form: { data: { turbo_confirm: "Grant admin (staff) access to #{@user.username}?" } }, |
| 31 | class: "px-3 py-1.5 rounded bg-brand-500/15 text-brand-300 text-sm hover:bg-brand-500/25 cursor-pointer border-0" %> |
| 32 | <% end %> |
| 33 | </div> |
| 34 | </div> |
| 35 | |
| 36 | <div class="grid grid-cols-2 lg:grid-cols-4 gap-3 mb-6"> |
| 37 | <%= render "admin/stat", label: "Repositories", value: @repos_count %> |
| 38 | <%= render "admin/stat", label: "Plan", value: (@subscription&.plan || "free").capitalize %> |
| 39 | <%= render "admin/stat", label: "Cloud used", value: "#{number_with_delimiter(@cloud_used)} / #{number_with_delimiter(@cloud_allow)}", |
| 40 | sub: "this period" %> |
| 41 | <%= render "admin/stat", label: "Entitled to cloud", value: (@user.entitled_to_cloud? ? "Yes" : "No"), |
| 42 | accent: (@user.entitled_to_cloud? ? "text-green-300" : "text-gray-300") %> |
| 43 | </div> |
| 44 | |
| 45 | <% if @subscription %> |
| 46 | <section class="mb-6"> |
| 47 | <h2 class="text-sm font-semibold text-gray-200 mb-2">Subscription</h2> |
| 48 | <div class="rounded-lg border border-surface-600 bg-surface-800 px-4 py-3 flex flex-wrap items-center gap-x-6 gap-y-2 text-sm"> |
| 49 | <span><%= admin_plan_badge(@subscription.plan) %> <%= admin_status_badge(@subscription.status) %></span> |
| 50 | <% if @subscription.current_period_end %> |
| 51 | <span class="text-gray-500">Renews <%= @subscription.current_period_end.strftime("%b %-d, %Y") %></span> |
| 52 | <% end %> |
| 53 | <% if @subscription.stripe_customer_id.present? %> |
| 54 | <span class="text-gray-600 font-mono text-xs"><%= @subscription.stripe_customer_id %></span> |
| 55 | <% end %> |
| 56 | </div> |
| 57 | </section> |
| 58 | <% end %> |
| 59 | |
| 60 | <section> |
| 61 | <h2 class="text-sm font-semibold text-gray-200 mb-2">Repositories <span class="text-gray-500 font-normal">(<%= @repos_count %>)</span></h2> |
| 62 | <div class="rounded-lg border border-surface-600 divide-y divide-surface-600 overflow-hidden"> |
| 63 | <% @repositories.each do |repo| %> |
| 64 | <%= link_to admin_repository_path(repo.id), class: "flex items-center justify-between px-3 py-2 hover:bg-surface-700 transition-colors" do %> |
| 65 | <span class="text-sm text-gray-200"><%= repo.name %> |
| 66 | <span class="text-xs text-gray-500 ml-1"><%= repo.kind %><%= " · private" if repo.is_private %></span> |
| 67 | </span> |
| 68 | <span class="text-xs text-gray-500"><%= repo.updated_at.strftime("%b %-d, %Y") %></span> |
| 69 | <% end %> |
| 70 | <% end %> |
| 71 | <% if @repositories.empty? %><p class="px-3 py-4 text-sm text-gray-500">No repositories.</p><% end %> |
| 72 | </div> |
| 73 | </section> |