Files
kondiplo_front/app/views/games/_form.html.erb
kontei f25fd6f802
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
フロントエンドプレイアブル
2026-02-15 14:57:17 +09:00

212 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%= form_with(model: game, class: "space-y-6") do |form| %>
<% if game.errors.any? %>
<div class="rounded-md bg-red-50 p-4 mb-6">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-red-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
</svg>
</div>
<div class="ml-3">
<h3 class="text-sm font-medium text-red-800">
<%= pluralize(game.errors.count, "error") %> prohibited this game from being saved:
</h3>
<div class="mt-2 text-sm text-red-700">
<ul class="list-disc pl-5 space-y-1">
<% game.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
</div>
</div>
</div>
<% end %>
<div>
<%= form.label :title, "ゲームタイトル", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.text_field :title, class: "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md", placeholder: "例: 定例ディプロマシー会 #1" %>
</div>
</div>
<% unless game.persisted? %>
<% if current_user&.admin? %>
<div>
<%= form.label :game_mode, "ゲームモード", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.select :game_mode,
options_for_select([
['ソロモード (単独プレイ)', 'admin_mode'],
['マルチプレイヤーモード (複数プレイ)', 'player_mode']
], game.is_solo_mode ? 'admin_mode' : 'player_mode'),
{},
{ id: 'game-mode-select', class: 'shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md' } %>
</div>
</div>
<% end %>
<div id="participants-count-field" style="<%= game.solo_mode? ? 'display: none;' : '' %>">
<%= form.label :participants_count, "参加人数", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.number_field :participants_count, min: 1, max: 7, step: 1, class: "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md" %>
</div>
<p class="mt-2 text-sm text-gray-500">1人から7人まで設定可能です。</p>
</div>
<div id="password-field" style="<%= game.solo_mode? ? 'display: none;' : '' %>">
<%= form.label :password, "パスワード (任意)", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.password_field :password, class: "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md" %>
</div>
<p class="mt-2 text-sm text-gray-500">知人同士でプレイする場合など、アクセス制限をかけたい場合に設定してください。</p>
</div>
<% end %>
<div id="auto-fill-mode-field" style="<%= (game.solo_mode? && !game.persisted?) ? 'display: none;' : '' %>">
<%= form.label :auto_order_mode, "自動処理モード", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.select :auto_order_mode,
options_for_select([
['HOLD (待機)', 'hold'],
['ランダム動作', 'random']
], game.auto_order_mode || 'hold'),
{},
{ class: 'shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md' } %>
</div>
<p class="mt-2 text-sm text-gray-500">注文未入力の国や、プレイヤー不在の国の動作を設定します。</p>
</div>
<div id="turn-schedule-field" style="<%= (game.solo_mode? && !game.persisted?) ? 'display: none;' : '' %>">
<%= form.label :turn_schedule, "ターン進行方式", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<% current_schedule = game.turn_schedule.presence %>
<% preset_value = case current_schedule
when nil then "manual"
when "0" then "daily_0"
else "custom"
end %>
<select id="turn_schedule_preset"
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"
onchange="handleSchedulePresetChange(this)">
<option value="manual" <%= 'selected' if preset_value == 'manual' %>>手動(管理者が処理)</option>
<option value="daily_0" <%= 'selected' if preset_value == 'daily_0' %>>毎日1回0時</option>
<option value="custom" <%= 'selected' if preset_value == 'custom' %>>カスタム...</option>
</select>
</div>
<div id="custom-schedule-field" style="<%= preset_value == 'custom' ? '' : 'display: none;' %>" class="mt-2">
<input type="text" id="custom_schedule_input"
value="<%= current_schedule if preset_value == 'custom' %>"
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"
placeholder="例: 0,12,18毎日0時・12時・18時"
oninput="document.getElementById('turn_schedule_value').value = this.value">
</div>
<%= form.hidden_field :turn_schedule, id: "turn_schedule_value", value: current_schedule %>
<p class="mt-2 text-sm text-gray-500">
自動の場合、締切時刻を過ぎると未入力国はAutoOrderで処理され、ターンが自動進行します。
</p>
</div>
<script>
function handleSchedulePresetChange(select) {
const customField = document.getElementById('custom-schedule-field');
const hiddenField = document.getElementById('turn_schedule_value');
const customInput = document.getElementById('custom_schedule_input');
switch (select.value) {
case 'manual':
customField.style.display = 'none';
hiddenField.value = '';
break;
case 'daily_0':
customField.style.display = 'none';
hiddenField.value = '0';
break;
case 'custom':
customField.style.display = 'block';
hiddenField.value = customInput.value;
break;
}
}
</script>
<div>
<%= form.label :memo, "メモ", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.textarea :memo, rows: 3, class: "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md" %>
</div>
<p class="mt-2 text-sm text-gray-500">ゲームに関するメモや注意事項があれば記載してください。</p>
</div>
<!-- ハウスルール設定 -->
<div class="border-t border-gray-200 pt-6 mt-6">
<h3 class="text-lg font-medium text-gray-900 mb-4">ハウスルール</h3>
<div class="space-y-4">
<div>
<%= form.label :year_limit, "年数制限", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.number_field :year_limit, min: 1901, max: 1999, step: 1, class: "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md", placeholder: "空欄 = 無制限" %>
</div>
<p class="mt-2 text-sm text-gray-500">指定した年を超えるとゲームが自動終了します(例: 1910。空欄で無制限。</p>
</div>
<div>
<%= form.label :victory_sc_count, "目標SC数", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.number_field :victory_sc_count, min: 1, max: 34, step: 1, value: game.victory_sc_count || 18, class: "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md" %>
</div>
<p class="mt-2 text-sm text-gray-500">ソロ勝利に必要なSC数デフォルト: 18。</p>
</div>
<div>
<%= form.label :scoring_system, "スコアリング方式", class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= form.select :scoring_system,
options_for_select([
['なし', 'none'],
['SC数獲得SC数がスコア', 'sc_count'],
['SC比率全SC中の割合%', 'sc_ratio'],
['DSS生存国で均等分割', 'dss'],
['SoS二乗和比率', 'sos']
], game.scoring_system || 'none'),
{},
{ class: 'shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md' } %>
</div>
<p class="mt-2 text-sm text-gray-500">ゲーム終了時のスコア計算方式を選択します。</p>
</div>
</div>
</div>
<div class="pt-5">
<div class="flex justify-end">
<%= form.submit "保存する", class: "ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm 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>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const gameModeSelect = document.getElementById('game-mode-select');
const participantsField = document.getElementById('participants-count-field');
const passwordField = document.getElementById('password-field');
const autoFillField = document.getElementById('auto-fill-mode-field');
if (gameModeSelect) {
gameModeSelect.addEventListener('change', function() {
const isAdminMode = this.value === 'admin_mode';
if (isAdminMode) {
if(participantsField) participantsField.style.display = 'none';
if(passwordField) passwordField.style.display = 'none';
if(autoFillField) autoFillField.style.display = 'none';
} else {
if(participantsField) participantsField.style.display = 'block';
if(passwordField) passwordField.style.display = 'block';
if(autoFillField) autoFillField.style.display = 'block';
}
});
}
});
</script>
<% end %>