フロントエンドプレイアブル
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled

This commit is contained in:
2026-02-15 14:57:17 +09:00
commit f25fd6f802
198 changed files with 10342 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
<% content_for :title, "ユーザー編集" %>
<div class="max-w-2xl mx-auto">
<div class="mb-6">
<h1 class="text-3xl font-bold text-gray-900">ユーザー編集</h1>
<p class="mt-2 text-sm text-gray-600"><%= @user.username %> の情報を編集</p>
</div>
<%= form_with model: @user, class: "space-y-6" do |f| %>
<% if @user.errors.any? %>
<div class="bg-red-100 border border-red-400 text-red-800 px-4 py-3 rounded relative" role="alert">
<strong class="font-bold">エラーがあります:</strong>
<ul class="mt-2 list-disc list-inside">
<% @user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= f.label :username, "ユーザー名", class: "block text-sm font-medium text-gray-700" %>
<%= f.text_field :username, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" %>
</div>
<div>
<%= f.label :email, "メールアドレス", class: "block text-sm font-medium text-gray-700" %>
<%= f.email_field :email, class: "mt-1 block w-full rounded-md border-gray-300 bg-gray-100 shadow-sm", disabled: true %>
<p class="mt-1 text-sm text-gray-500">メールアドレスは変更できません</p>
</div>
<div class="border-t border-gray-200 pt-6">
<h3 class="text-lg font-medium text-gray-900 mb-4">パスワード変更</h3>
<p class="text-sm text-gray-600 mb-4">パスワードを変更する場合のみ入力してください。空欄の場合は変更されません。</p>
<div class="space-y-4">
<div>
<%= f.label :password, "新しいパスワード", class: "block text-sm font-medium text-gray-700" %>
<%= f.password_field :password, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500", autocomplete: "new-password" %>
<p class="mt-1 text-sm text-gray-500">6文字以上</p>
</div>
<div>
<%= f.label :password_confirmation, "新しいパスワード(確認)", class: "block text-sm font-medium text-gray-700" %>
<%= f.password_field :password_confirmation, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500", autocomplete: "new-password" %>
</div>
</div>
</div>
<div class="flex items-center justify-between pt-6 border-t border-gray-200">
<%= link_to "キャンセル", user_path(@user), class: "inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50" %>
<%= f.submit "更新", class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,82 @@
<% content_for :title, "ユーザー管理" %>
<div class="mb-6">
<h1 class="text-3xl font-bold text-gray-900">ユーザー管理</h1>
<p class="mt-2 text-sm text-gray-600">登録されているユーザーの一覧と管理</p>
</div>
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
<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">
ユーザー名
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
メールアドレス
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
権限
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
登録日
</th>
<th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
操作
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<% @users.each do |user| %>
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="text-sm font-medium text-gray-900">
<%= user.username %>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900"><%= user.email %></div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<% if user.admin? %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">
管理者
</span>
<% else %>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">
一般ユーザー
</span>
<% end %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<%= user.created_at.strftime("%Y年%m月%d日") %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-2">
<%= link_to "詳細", user_path(user), class: "text-indigo-600 hover:text-indigo-900" %>
<%= link_to "編集", edit_user_path(user), class: "text-blue-600 hover:text-blue-900" %>
<% if user != current_user %>
<%= button_to "#{user.admin? ? '管理者解除' : '管理者に昇格'}",
toggle_admin_user_path(user),
method: :patch,
class: "inline text-yellow-600 hover:text-yellow-900",
data: { confirm: "#{user.admin? ? '管理者権限を削除' : '管理者権限を付与'}しますか?" } %>
<%= button_to "削除",
user_path(user),
method: :delete,
class: "inline text-red-600 hover:text-red-900",
data: { confirm: "#{user.username}を削除しますか?" } %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<div class="mt-6">
<p class="text-sm text-gray-600">
合計: <%= @users.count %>ユーザー
</p>
</div>

View File

@@ -0,0 +1,50 @@
<% content_for :title, "新規登録" %>
<div class="max-w-md mx-auto">
<h1 class="text-3xl font-bold text-gray-900 mb-6">新規登録</h1>
<%= form_with model: @user, url: signup_path, class: "space-y-6" do |f| %>
<% if @user.errors.any? %>
<div class="bg-red-100 border border-red-400 text-red-800 px-4 py-3 rounded relative" role="alert">
<strong class="font-bold">エラーがあります:</strong>
<ul class="mt-2 list-disc list-inside">
<% @user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= f.label :username, "ユーザー名", class: "block text-sm font-medium text-gray-700" %>
<%= f.text_field :username, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500", autofocus: true %>
</div>
<div>
<%= f.label :email, "メールアドレス", class: "block text-sm font-medium text-gray-700" %>
<%= f.email_field :email, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" %>
</div>
<div>
<%= f.label :password, "パスワード", class: "block text-sm font-medium text-gray-700" %>
<%= f.password_field :password, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" %>
<p class="mt-1 text-sm text-gray-500">6文字以上</p>
</div>
<div>
<%= f.label :password_confirmation, "パスワード(確認)", class: "block text-sm font-medium text-gray-700" %>
<%= f.password_field :password_confirmation, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" %>
</div>
<div>
<%= f.submit "登録", class: "w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
<% end %>
<div class="mt-6 text-center">
<p class="text-sm text-gray-600">
既にアカウントをお持ちですか?
<%= link_to "ログイン", login_path, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
</p>
</div>
</div>

View File

@@ -0,0 +1,83 @@
<% content_for :title, @user.username %>
<div class="mb-6 flex items-center justify-between">
<div>
<h1 class="text-3xl font-bold text-gray-900"><%= @user.username %></h1>
<% if @user.admin? %>
<span class="mt-2 inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800">
管理者
</span>
<% end %>
</div>
<div class="flex space-x-3">
<%= link_to "編集", edit_user_path(@user), class: "inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50" %>
<%= link_to "一覧に戻る", users_path, class: "inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50" %>
</div>
</div>
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
<div class="px-4 py-5 sm:px-6">
<h3 class="text-lg leading-6 font-medium text-gray-900">
ユーザー情報
</h3>
</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">
ユーザー名
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<%= @user.username %>
</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">
メールアドレス
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<%= @user.email %>
</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">
権限
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<%= @user.admin? ? "管理者" : "一般ユーザー" %>
</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">
登録日
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<%= @user.created_at.strftime("%Y年%m月%d日 %H:%M") %>
</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">
最終更新日
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<%= @user.updated_at.strftime("%Y年%m月%d日 %H:%M") %>
</dd>
</div>
</dl>
</div>
</div>
<% if @user != current_user %>
<div class="mt-6 flex space-x-3">
<%= button_to "#{@user.admin? ? '管理者権限を削除' : '管理者権限を付与'}",
toggle_admin_user_path(@user),
method: :patch,
class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-yellow-600 hover:bg-yellow-700",
data: { confirm: "#{@user.admin? ? '管理者権限を削除' : '管理者権限を付与'}しますか?" } %>
<%= button_to "ユーザーを削除",
user_path(@user),
method: :delete,
class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700",
data: { confirm: "#{@user.username}を削除しますか?" } %>
</div>
<% end %>