[FE] Admin CRUD pages — ArcadeGames index, create, edit + sidebar link

Open
#475 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
45/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
frontend

Research direction

Start from resources/js/Pages/CRUD/Product/Index.vue, Create.vue and Edit.vue, which the issue names as the pattern to copy, then add the three new ArcadeGames pages and the sidebar link in resources/js/Components/Navigation/AdminSidebar.vue. The issue depends on #474 (the controller) and #460 (the ArcadeGame type), so confirm those exist first. Done when /admin/arcadeGames lists, creates, edits and deletes games, and the edit form shows the current payout_config JSON.

Written by the indexing model from the issue text.

Description

frontend gamification P2

Context & Objective

Create the admin Vue CRUD pages for managing arcade games. Follow the exact same pattern as existing CRUD pages (resources/js/Pages/CRUD/Product/Index.vue) using CRUDView, HeaderRow, Row, Cell, Header components.

Files to Create / Modify

  • Create: resources/js/Pages/CRUD/ArcadeGames/Index.vue
  • Create: resources/js/Pages/CRUD/ArcadeGames/Create.vue
  • Create: resources/js/Pages/CRUD/ArcadeGames/Edit.vue
  • Modify: resources/js/Components/Navigation/AdminSidebar.vue — add "Arcade" section with link

Technical Requirements

Index.vue
<script setup lang="ts">
import type ArcadeGame from "@/Types/Arcade";
import type Paginated from "@/Types/Paginated";
import CRUDView from "@/Components/CRUD/CRUDView.vue";
// ... other CRUD components

interface Props {
    items: Paginated<ArcadeGame>;
    with: { editions: Edition[] };
    isSearchable?: boolean;
}
</script>

<template>
    <CRUDView title="Jogos do Arcade" view="ArcadeGames" ...>
        <template #header>
            <HeaderRow>
                <Header sort-by="name">Nome</Header>
                <Header sort-by="slug">Slug</Header>
                <Header sort-by="is_active">Ativo</Header>
                <Header sort-by="min_wager">Aposta Mín.</Header>
                <Header sort-by="max_wager">Aposta Máx.</Header>
                <Header sort-by="daily_win_cap">Limite Diário</Header>
                <Header filter-by="edition_id" :filter-values="editions">Edição</Header>
            </HeaderRow>
        </template>
        <template #row="{ item }">
            <Row :item="item" name="arcadeGames">
                <Cell class="font-medium text-white">{{ item.name }}</Cell>
                <Cell><span class="font-mono text-xs text-neutral-400">{{ item.slug }}</span></Cell>
                <Cell>
                    <span :class="item.is_active ? 'text-green-400' : 'text-red-400'">
                        {{ item.is_active ? 'Ativo' : 'Inativo' }}
                    </span>
                </Cell>
                <Cell>{{ item.min_wager }} pts</Cell>
                <Cell>{{ item.max_wager }} pts</Cell>
                <Cell>{{ item.daily_win_cap ?? '—' }}</Cell>
                <Cell class="text-xs text-neutral-400">{{ editions[item.edition_id] ?? '—' }}</Cell>
            </Row>
        </template>
    </CRUDView>
</template>
Create.vue and Edit.vue

Look at resources/js/Pages/CRUD/Product/Create.vue and Edit.vue for the exact pattern.

Form fields:

  • edition_id — <select> populated from with.editions
  • slug — <input type="text"> with helper text showing valid slug values
  • name — <input type="text">
  • is_active — <input type="checkbox">
  • is_pvp — <input type="checkbox">
  • min_wager, max_wager — <input type="number">
  • daily_win_cap — <input type="number"> with "deixe em branco para ilimitado" hint
  • payout_config — <textarea> for raw JSON, with a helper text block documenting the expected shape for each slug:
    coin-flip:     {"house_edge_pct": 10}
    high-low:      {"under_threshold":34,"over_threshold":67,"under_multiplier":2.88,...}
    bug-sweeper:   {"click_multipliers":[1.3,1.7,2.2,2.9,3.8],"bomb_count":3}
    mastermind:    {"max_attempts":5,"attempt_multipliers":{"1":6.0,"2":4.0,...}}
    binary-blitz:  {"question_count":3,"time_limit_seconds":12,"win_multiplier":2.5,...}
    
AdminSidebar.vue

Find the section where other admin nav items are listed and add:

<SidebarLink href="/admin/arcadeGames" :active="isCurrentRoute('admin.arcadeGames.index')">
    🎮 Arcade
</SidebarLink>

Acceptance Criteria

  • /admin/arcadeGames renders the paginated list with all columns
  • Create form submits and creates a new ArcadeGame record
  • Edit form pre-fills values and submits updates
  • Delete works (row disappears from list)
  • payout_config textarea shows current JSON value in Edit form
  • AdminSidebar has "Arcade" link pointing to /admin/arcadeGames

Dependencies

  • #474 (ArcadeCRUDController)
  • #460 (ArcadeGame model — for TypeScript type import)
Dominant language
Vue
Stars
12
Forks
1
Avg merge
3d 42m
Merged PRs (30d)
4

Getting set up

  • Ships a Dockerfile or Docker Compose file
  • No pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from semanadeinformatica/website

All issues in semanadeinformatica/website

Similar issues

More Web Dev issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.