mirror of
https://github.com/ryankazokas/turbovault-app.git
synced 2026-04-17 02:52:55 +00:00
Moving to github
This commit is contained in:
155
app/views/games/index.html.erb
Normal file
155
app/views/games/index.html.erb
Normal file
@@ -0,0 +1,155 @@
|
||||
<div>
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-3xl font-bold">My Games</h1>
|
||||
<div class="flex items-center space-x-2">
|
||||
<div id="bulk-actions" style="display: none;" class="mr-4">
|
||||
<button type="button" onclick="bulkEdit()" class="px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700">
|
||||
Bulk Edit (<span id="selected-count">0</span>)
|
||||
</button>
|
||||
</div>
|
||||
<%= link_to "Import CSV", import_games_path, class: "px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700" %>
|
||||
<%= link_to "Add Game", new_game_path, class: "px-4 py-2 bg-indigo-600 text-white rounded hover:bg-indigo-700" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filters -->
|
||||
<%= form_with url: games_path, method: :get, class: "bg-white p-4 rounded-lg shadow mb-6" do |f| %>
|
||||
<div class="grid grid-cols-1 md:grid-cols-5 gap-4">
|
||||
<div>
|
||||
<%= f.text_field :search, placeholder: "Search games...", value: params[:search], class: "w-full rounded-md border-gray-300" %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= f.select :platform_id, options_from_collection_for_select(@platforms, :id, :name, params[:platform_id]), { include_blank: "All Platforms" }, class: "w-full rounded-md border-gray-300" %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= f.select :genre_id, options_from_collection_for_select(@genres, :id, :name, params[:genre_id]), { include_blank: "All Genres" }, class: "w-full rounded-md border-gray-300" %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= f.select :format, options_for_select([["Physical", "physical"], ["Digital", "digital"]], params[:format]), { include_blank: "All Formats" }, class: "w-full rounded-md border-gray-300" %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= f.select :completion_status, options_for_select([["Backlog", "backlog"], ["Currently Playing", "currently_playing"], ["Completed", "completed"], ["On Hold", "on_hold"], ["Not Playing", "not_playing"]], params[:completion_status]), { include_blank: "All Statuses" }, class: "w-full rounded-md border-gray-300" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 flex justify-between">
|
||||
<%= f.submit "Filter", class: "px-4 py-2 bg-indigo-600 text-white rounded hover:bg-indigo-700" %>
|
||||
<%= link_to "Clear Filters", games_path, class: "px-4 py-2 bg-gray-200 rounded hover:bg-gray-300" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Sort -->
|
||||
<div class="mb-4">
|
||||
<span class="text-gray-600 mr-2">Sort by:</span>
|
||||
<%= link_to "Alphabetical", games_path(filter_params_for_sort("alphabetical")), class: "text-indigo-600 hover:text-indigo-800 mr-4" %>
|
||||
<%= link_to "Recently Added", games_path(filter_params_for_sort("recent")), class: "text-indigo-600 hover:text-indigo-800 mr-4" %>
|
||||
<%= link_to "Highest Rated", games_path(filter_params_for_sort("rated")), class: "text-indigo-600 hover:text-indigo-800" %>
|
||||
</div>
|
||||
|
||||
<!-- Games List -->
|
||||
<% if @games.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 class="px-6 py-3 text-left">
|
||||
<input type="checkbox" id="select-all" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" onchange="toggleAll(this)">
|
||||
</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Title</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Platform</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Format</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Rating</th>
|
||||
<th 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">
|
||||
<% @games.each do |game| %>
|
||||
<tr>
|
||||
<td class="px-6 py-4">
|
||||
<input type="checkbox" name="game_ids[]" value="<%= game.id %>" class="game-checkbox rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" onchange="updateBulkActions()">
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<%= link_to game.title, game, class: "text-indigo-600 hover:text-indigo-800 font-medium" %>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<%= game.platform.name %>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full <%= game.physical? ? 'bg-blue-100 text-blue-800' : 'bg-green-100 text-green-800' %>">
|
||||
<%= game.format.titleize %>
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<%= game.completion_status&.titleize || "N/A" %>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<%= game.user_rating ? "⭐ #{game.user_rating}/5" : "Not rated" %>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||
<%= link_to "View", game, class: "text-indigo-600 hover:text-indigo-900 mr-2" %>
|
||||
<%= link_to "Edit", edit_game_path(game), class: "text-blue-600 hover:text-blue-900 mr-2" %>
|
||||
<%= button_to "Delete", game, method: :delete, data: { turbo_confirm: "Are you sure you want to delete '#{game.title}'? This action cannot be undone." }, class: "text-red-600 hover:text-red-900" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Pagination would go here -->
|
||||
<div class="mt-4">
|
||||
<%#= paginate @games %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="bg-white p-8 rounded-lg shadow text-center">
|
||||
<p class="text-gray-500 mb-4">No games found matching your filters.</p>
|
||||
<%= link_to "Clear Filters", games_path, class: "text-indigo-600 hover:text-indigo-800" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleAll(checkbox) {
|
||||
const gameCheckboxes = document.querySelectorAll('.game-checkbox');
|
||||
gameCheckboxes.forEach(cb => {
|
||||
cb.checked = checkbox.checked;
|
||||
});
|
||||
updateBulkActions();
|
||||
}
|
||||
|
||||
function updateBulkActions() {
|
||||
const checkedBoxes = document.querySelectorAll('.game-checkbox:checked');
|
||||
const count = checkedBoxes.length;
|
||||
const bulkActions = document.getElementById('bulk-actions');
|
||||
const selectedCount = document.getElementById('selected-count');
|
||||
|
||||
if (count > 0) {
|
||||
bulkActions.style.display = 'block';
|
||||
selectedCount.textContent = count;
|
||||
} else {
|
||||
bulkActions.style.display = 'none';
|
||||
document.getElementById('select-all').checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
function bulkEdit() {
|
||||
const checkedBoxes = document.querySelectorAll('.game-checkbox:checked');
|
||||
const gameIds = Array.from(checkedBoxes).map(cb => cb.value);
|
||||
|
||||
if (gameIds.length === 0) {
|
||||
alert('Please select at least one game');
|
||||
return;
|
||||
}
|
||||
|
||||
// Build URL with game IDs
|
||||
const params = new URLSearchParams();
|
||||
gameIds.forEach(id => params.append('game_ids[]', id));
|
||||
|
||||
window.location.href = '<%= bulk_edit_games_path %>?' + params.toString();
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user