Skip to content

Commit fa774ab

Browse files
feat: Implement edit functionality for map rotation server assignments with UI updates
1 parent 4c2368c commit fa774ab

8 files changed

Lines changed: 569 additions & 11 deletions

File tree

.github/copilot-instructions.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ ASP.NET Core 9 web application (`src/XtremeIdiots.Portal.Web/`) providing the Xt
3333
## Key Documentation
3434

3535
- [Development Workflows](docs/development-workflows.md) — Branch strategy, CI/CD triggers, and PR flows.
36+
- [UI Standards Guide](docs/ui-standards-guide.md) — Button hierarchy, icons, forms, detail pages, filters, destructive operation gating, and legacy patterns to avoid.
3637
- [Datatable Implementation Guide](docs/DATATABLE-IMPLEMENTATION-GUIDE.md) — Server-backed data table patterns.
3738
- [Credentials Permissions Matrix](docs/credentials-permissions-matrix.md) — Roles, claims, and access mapping.
3839
- [Permissions Matrices](docs/permissions/) — Per-area authorization matrices (players, game servers, admin actions, etc.).
39-
- [CSS Architecture Guide](docs/css-architecture-guide.md)Styling conventions and structure.
40+
- [CSS Architecture Guide](docs/css-architecture-guide.md)SCSS structure, tokens, components, and build process.
4041
- [Manual Steps](docs/manual-steps.md) — Post-deployment configuration.
4142

4243
## Conventions and Patterns
@@ -47,3 +48,17 @@ ASP.NET Core 9 web application (`src/XtremeIdiots.Portal.Web/`) providing the Xt
4748
- Sensitive settings use user secrets locally (`UserSecretsId` in csproj) or environment variables; Azure App Configuration and managed identity in deployed environments.
4849
- PRs trigger dev Terraform plans automatically; prod plans require the `run-prd-plan` label.
4950
- Copilot and Dependabot PRs skip Terraform plans unless explicitly labeled.
51+
52+
## UI Conventions (Razor Views)
53+
54+
**Always read [docs/ui-standards-guide.md](docs/ui-standards-guide.md) before creating or modifying views.** Key rules:
55+
56+
- Wrap all content in `ibox > ibox-title (with h5) + ibox-content`. Action buttons go in `ibox-footer`.
57+
- Buttons: `btn-primary` for primary actions, `btn-outline-secondary` for cancel/back, `btn-danger` for destructive confirms, `btn-outline-danger btn-sm` for inline delete links.
58+
- Icons: always use `fa-solid fa-fw fa-[icon]` with `aria-hidden="true"`. Use `fa-pen-to-square` (edit), `fa-eye` (details), `fa-trash` (delete), `fa-plus` (create), `fa-floppy-disk` (save), `fa-arrow-left` (back).
59+
- Forms: vertical labels (`form-label`), `form-select` for dropdowns, `form-text` for help text, `mb-3` spacing.
60+
- Detail pages: use `detail-fields` component with `detail-label` / `detail-value` in a `row` grid.
61+
- Filters: use `list-filters` class, label reset button "Reset Filters".
62+
- Destructive actions: Tier 1 (confirmation page) for entity deletes, Tier 2 (`data-confirm` attribute) for inline actions. Never use inline `onclick`/`onsubmit` confirm handlers.
63+
- Tables: `table table-striped table-hover`, `table-date-col` on date headers, `table-action-col` on action headers.
64+
- Do not use legacy patterns: `control-label`, `help-block`, `float-e-margins`, `btn-xs`, `dl-horizontal`, `admin-actions-filters`, `fa-save`, `fa-edit`, `type="button"` on `<a>` tags.

docs/css-architecture-guide.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,47 @@ Styles/
1313
├── tokens/ # Design system variables
1414
│ ├── _colors.scss # Color palette and CSS custom properties
1515
│ ├── _spacing.scss # Spacing scale and component spacing
16-
│ └── _typography.scss # Font families, sizes, weights
16+
│ └── _typography.scss # Font families, sizes, weights, $stat-value-size
1717
├── base/ # Foundation styles
1818
│ ├── _reset.scss # CSS reset
1919
│ ├── _base.scss # HTML element styles
20-
│ └── _accessibility.scss # Accessibility improvements
20+
│ ├── _accessibility.scss # Accessibility improvements
21+
│ └── _animations.scss # CSS animations (fadeInRight etc.)
2122
├── layout/ # Page structure
2223
│ ├── _responsive.scss # Breakpoints and responsive mixins
2324
│ ├── _navbar.scss # Top navigation bar
2425
│ ├── _sidebar.scss # Off-canvas sidebar
25-
│ ├── _footer.scss # Page footer
2626
│ └── _wrapper.scss # Main content wrapper
2727
├── utilities/ # Helper classes
2828
│ ├── _spacing.scss # Margin and padding utilities
2929
│ ├── _flex.scss # Flexbox utilities
3030
│ ├── _text.scss # Text alignment, colors, sizing
3131
│ └── _zindex.scss # Z-index layering utilities
3232
├── components/ # Reusable UI components
33-
│ ├── _buttons.scss # Button styles
34-
│ ├── _cards.scss # ibox card component
33+
│ ├── _buttons.scss # Button styles + btn-xs bridge
34+
│ ├── _cards.scss # ibox card component + float-e-margins no-op
3535
│ ├── _tables.scss # Table styles
3636
│ ├── _forms.scss # Form controls
3737
│ ├── _badges.scss # Badge components
38-
│ └── _pagination.scss # Pagination controls
38+
│ ├── _pagination.scss # Pagination controls
39+
│ ├── _detail-fields.scss # Label-value display for detail pages
40+
│ ├── _empty-state.scss # Empty state placeholder component
41+
│ ├── _page-header.scss # Page-level heading component
42+
│ └── _sticky-footer.scss # Sticky form footer for long pages
3943
├── features/ # Page-specific styles
40-
│ ├── _admin-actions.scss # Admin actions pages
44+
│ ├── _admin-actions.scss # Admin actions + list-filters component
4145
│ ├── _players.scss # Players pages
4246
│ ├── _chatlog.scss # Chat log pages
4347
│ ├── _maps.scss # Maps pages
4448
│ ├── _demos.scss # Demos pages
45-
│ └── _users.scss # User management pages
49+
│ ├── _users.scss # User management pages
50+
│ ├── _game-servers.scss # Game server reorder
51+
│ ├── _map-rotations.scss # Map rotation editor
52+
│ ├── _changelog.scss # Change log dashboard
53+
│ └── ... # Other feature files
4654
├── vendor/ # Third-party overrides
4755
│ ├── _bootstrap-overrides.scss # Bootstrap customizations
48-
│ └── _datatable-overrides.scss # DataTables customizations
56+
│ └── _datatable-overrides.scss # DataTables + table column utilities
4957
└── app.scss # Main entry point (imports all partials)
5058
```
5159

@@ -229,6 +237,7 @@ The previous Inspinia theme (inspinia.css) has been absorbed into the structured
229237
5. **Avoid !important** - Use proper specificity instead
230238
6. **Mobile-first** - Design for mobile first, enhance for desktop
231239
7. **Test responsive** - Always test changes across breakpoints
240+
8. **Follow UI standards** - See [UI Standards Guide](ui-standards-guide.md) for button hierarchy, icon usage, form layout, detail-field patterns, and destructive operation gating
232241

233242
## Troubleshooting
234243

docs/ui-standards-guide.md

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
# UI Standards Guide
2+
3+
This document defines the canonical UI patterns for the XtremeIdiots Portal. All views must follow these standards to ensure visual consistency across the site.
4+
5+
## Page Structure
6+
7+
Every page follows this wrapper structure:
8+
9+
```html
10+
<div class="wrapper wrapper-content animated fadeInRight">
11+
<div class="row">
12+
<div class="col-12">
13+
<div class="container-fluid">
14+
<div class="ibox">
15+
<div class="ibox-title"><h5>Section Title</h5></div>
16+
<div class="ibox-content"><!-- Content --></div>
17+
<div class="ibox-footer"><!-- Action buttons --></div>
18+
</div>
19+
</div>
20+
</div>
21+
</div>
22+
</div>
23+
```
24+
25+
### Rules
26+
27+
- Every content section **must** be wrapped in `ibox > ibox-title + ibox-content`.
28+
- The `ibox-title` **must** contain an `<h5>` element. Never place raw text in `ibox-title`.
29+
- Action buttons (Save, Cancel, Delete, Back) go in `ibox-footer`, not loose inside `ibox-content`.
30+
- Use `ibox-footer--sticky` on long forms (e.g. GameServers/Edit) to keep the save bar visible.
31+
32+
---
33+
34+
## Buttons
35+
36+
### Hierarchy
37+
38+
| Role | Class | Icon | Size |
39+
|------|-------|------|------|
40+
| **Primary action** (Save, Create, Submit) | `btn btn-primary` | Optional FA icon + text | Default |
41+
| **Secondary action** (Cancel, Back) | `btn btn-outline-secondary` | No icon, or `fa-arrow-left` for back | Default |
42+
| **Destructive action** (Delete link in table) | `btn btn-outline-danger` | `fa-trash` | `btn-sm` |
43+
| **Destructive confirm** (Delete button on confirmation page) | `btn btn-danger` | `fa-trash` | Default |
44+
| **Cautionary action** (Lift ban) | `btn btn-warning` | `fa-unlock` | Default |
45+
| **Inline table actions** (Edit, Details) | `btn btn-outline-secondary` | Icon + text | `btn-sm` |
46+
| **Filter reset** | `btn btn-outline-secondary btn-sm` | No icon | `btn-sm` |
47+
48+
### Prohibited Button Classes for Actions
49+
50+
Do **not** use these for action buttons (reserve for badges/status only):
51+
52+
- `btn-success` — use `btn-primary` instead
53+
- `btn-info` — use `btn-outline-secondary` instead
54+
- `btn-xs` — use `btn-sm` instead (btn-xs is a bridge alias only)
55+
56+
### Button Placement
57+
58+
- **List pages:** "Create New" button in `.ibox-tools` within `.ibox-title` (top-right).
59+
- **Form pages:** Submit + Cancel in `.ibox-footer`. Primary action on the right, Cancel on the left.
60+
- **Detail pages:** Action buttons in `.ibox-footer`.
61+
- **Table rows:** `btn-group btn-group-sm` in the last column.
62+
- **Confirmation pages:** Cancel (left) + Confirm (right) in `.ibox-footer`.
63+
64+
### Cancel Button Wording
65+
66+
- On **confirmation pages**: use `Cancel` (no icon).
67+
- On **form/edit pages**: use `Back to List` or `Back to [Parent]` with `fa-arrow-left` icon.
68+
69+
---
70+
71+
## Icons
72+
73+
All icons use Font Awesome 6 solid style with fixed-width class: `fa-solid fa-fw fa-[icon-name]`.
74+
75+
### Standard Action Icons
76+
77+
| Action | Icon | Usage |
78+
|--------|------|-------|
79+
| Create / Add | `fa-plus` | Create buttons, add links |
80+
| Edit | `fa-pen-to-square` | Edit buttons and links |
81+
| Delete | `fa-trash` | Delete buttons and links |
82+
| View / Details | `fa-eye` | Details/view buttons |
83+
| Back | `fa-arrow-left` | Back navigation buttons |
84+
| Save | `fa-floppy-disk` | Save/submit buttons |
85+
| Clone | `fa-clone` | Clone/copy actions |
86+
| Import | `fa-file-import` | Import actions |
87+
| Refresh / Sync | `fa-rotate` | Sync/refresh actions |
88+
| Cancel (operation) | `fa-ban` | Cancel running operations |
89+
90+
### Rules
91+
92+
- **Always** include `fa-fw` on icons for fixed-width alignment.
93+
- **Never** use deprecated icons: `fa-save``fa-floppy-disk`, `fa-edit``fa-pen-to-square`, `fa-file-text` → use `fa-flag` or contextual icon.
94+
- Include `aria-hidden="true"` on decorative icons (those accompanied by text).
95+
- Do not use `me-1` for spacing when `fa-fw` is present — `fa-fw` provides consistent width.
96+
97+
---
98+
99+
## Forms
100+
101+
### Layout
102+
103+
- Use **vertical labels** (label above input) with `form-label` class.
104+
- Wrap each field in `<div class="mb-3">`.
105+
- Never use horizontal form layout (`col-sm-2` + `col-sm-10`).
106+
- Use `form-select` for `<select>` elements, not `form-control`.
107+
- Use `form-text` for helper text beneath inputs, not `help-block`.
108+
- Use `form-check` + `form-check-input` + `form-check-label` for checkboxes.
109+
110+
### Textarea Rows
111+
112+
- Short text fields: `rows="3"`
113+
- Descriptions / content: `rows="6"`
114+
115+
### Long Forms
116+
117+
- Use **Bootstrap nav-tabs** for forms with 5+ logical sections (e.g. GameServers/Edit).
118+
- Use `ibox-footer--sticky` to keep Save/Cancel visible during scrolling.
119+
- Toggle tab visibility with CSS class `d-none`, not inline `style="display:none"`.
120+
121+
### Validation
122+
123+
- Always include `<div asp-validation-summary="ModelOnly" class="text-danger"></div>` at the top of forms.
124+
- Use `<span asp-validation-for="Field" class="text-danger"></span>` below inputs.
125+
126+
---
127+
128+
## Detail Pages
129+
130+
Use the `detail-fields` component for label-value displays:
131+
132+
```html
133+
<dl class="detail-fields row">
134+
<div class="detail-field col-sm-6">
135+
<dt class="detail-label">Label</dt>
136+
<dd class="detail-value">Value</dd>
137+
</div>
138+
</dl>
139+
```
140+
141+
### Rules
142+
143+
- Always use `<dl>` semantics with `detail-fields` class.
144+
- Use `detail-label` (uppercase, muted, small) and `detail-value` (normal text).
145+
- Arrange fields in a responsive grid: `col-sm-6` (two-column) or `col-sm-4` (three-column).
146+
- Never use `dl-horizontal` (legacy Bootstrap 3 class).
147+
148+
---
149+
150+
## Filter Bars
151+
152+
Use the `list-filters` class for filter bars on list/index pages:
153+
154+
```html
155+
<div class="list-filters mb-2">
156+
<div class="filter-group">
157+
<label class="form-label" for="filterGameType">Game Type</label>
158+
<select id="filterGameType" class="form-select">...</select>
159+
</div>
160+
<div class="filter-group">
161+
<label class="form-label" for="resetFilters">Reset</label>
162+
<button type="button" id="resetFilters" class="btn btn-outline-secondary btn-sm">Reset Filters</button>
163+
</div>
164+
</div>
165+
```
166+
167+
### Rules
168+
169+
- Use `list-filters` class, not `admin-actions-filters` (legacy alias retained for backward compatibility).
170+
- Always label the reset button **"Reset Filters"** — not "Clear Filters" or "Reset".
171+
- Place the filter bar **inside** `.ibox-content`, above the table.
172+
173+
---
174+
175+
## Tables & DataTables
176+
177+
### Table Classes
178+
179+
All data tables must use: `table table-striped table-hover`.
180+
181+
### Column Width Utilities
182+
183+
- Date/timestamp columns: add `class="table-date-col"` to `<th>` — applies `white-space: nowrap; width: 1%`.
184+
- Action button columns: add `class="table-action-col"` to `<th>` — same constrained width.
185+
186+
### Empty States
187+
188+
- DataTables: set `language.emptyTable` to a contextual message (e.g. `"No game servers found"`). A global fallback of `"No records found"` is set in `site.js`.
189+
- Non-table contexts: use the `.empty-state` component:
190+
191+
```html
192+
<div class="empty-state">
193+
<i class="fa-solid fa-fw fa-folder-open empty-state-icon"></i>
194+
<p class="empty-state-message">No records found</p>
195+
<div class="empty-state-action">
196+
<a href="..." class="btn btn-primary btn-sm">Create New</a>
197+
</div>
198+
</div>
199+
```
200+
201+
---
202+
203+
## Destructive Operations
204+
205+
All destructive actions must have a confirmation gate. Use one of two tiers:
206+
207+
### Tier 1: Dedicated Confirmation Page
208+
209+
For permanent, irreversible deletes of primary entities (game servers, admin actions, ban file monitors, demos, tags, map rotations).
210+
211+
**Standard structure:**
212+
213+
```html
214+
<div class="ibox">
215+
<div class="ibox-title"><h5>Delete [Entity Type]</h5></div>
216+
<div class="ibox-content">
217+
<p>Are you sure you want to delete this [entity type]?</p>
218+
<div class="alert alert-warning mb-3">
219+
<i class="fa-solid fa-fw fa-triangle-exclamation" aria-hidden="true"></i>
220+
This action cannot be undone. [Specific consequence describing sub-entity impact.]
221+
</div>
222+
<dl class="detail-fields row">
223+
<!-- Entity details shown here -->
224+
</dl>
225+
</div>
226+
<div class="ibox-footer">
227+
<a class="btn btn-outline-secondary" asp-action="Index">Cancel</a>
228+
<button type="submit" class="btn btn-danger">
229+
<i class="fa-solid fa-fw fa-trash"></i> Delete [Entity Type]
230+
</button>
231+
</div>
232+
</div>
233+
```
234+
235+
### Tier 2: Inline `data-confirm` Dialog
236+
237+
For quick destructive actions within list/detail views (unassign, remove tag, delete map from host, delete permission).
238+
239+
Add a `data-confirm` attribute to the button or link:
240+
241+
```html
242+
<button type="submit" class="btn btn-outline-danger btn-sm"
243+
data-confirm="Are you sure you want to [verb] this [entity]? [Consequence if applicable.]">
244+
<i class="fa-solid fa-fw fa-trash"></i> Delete
245+
</button>
246+
```
247+
248+
The `data-confirm` handler in `enhanced-ui.js` intercepts the click and shows a browser confirm dialog. No inline `onclick` or `onsubmit` handlers.
249+
250+
### Confirm Message Format
251+
252+
All confirmation messages follow this pattern:
253+
254+
> Are you sure you want to **[verb]** this **[entity]**? **[Consequence if applicable.]**
255+
256+
Examples:
257+
- "Are you sure you want to delete this protected name?"
258+
- "Are you sure you want to unassign this server? Maps will be removed from the server."
259+
- "Are you sure you want to remove this permission? It may take up to 15 minutes to take effect."
260+
261+
### What NOT to Do
262+
263+
-`onclick="return confirm('...')"` — use `data-confirm` instead.
264+
-`onsubmit="return confirm('...')"` — use `data-confirm` on the submit button instead.
265+
- ❌ Direct POST with no confirmation on destructive actions.
266+
-`btn-danger` on non-destructive actions (Claim, Lift) — use `btn-primary` or `btn-warning`.
267+
268+
---
269+
270+
## Badges & Status Indicators
271+
272+
- Use SCSS-defined `badge-*` classes or Bootstrap 5 `bg-*` classes.
273+
- Colour semantics: green = active/online/success, red = error/expired/danger, amber = warning/pending, teal = primary.
274+
- Use square badges (border-radius: 3px), not pill badges.
275+
- All status values must be wrapped in a badge — never raw text.
276+
277+
---
278+
279+
## Typography
280+
281+
- Font: Open Sans throughout (loaded via Google Fonts).
282+
- ibox-title `<h5>`: renders at 16px (`$h3-size`) with `font-weight: 600`.
283+
- Dashboard stat numbers: use `stat-value` class (renders at `$stat-value-size: 2rem`).
284+
- Never hardcode `px` values in views — use token variables in SCSS.
285+
286+
---
287+
288+
## Legacy Patterns to Avoid
289+
290+
These patterns are deprecated. The SCSS retains bridge definitions for backward compatibility, but new code must not use them:
291+
292+
| Deprecated | Replacement |
293+
|-----------|-------------|
294+
| `control-label` | `form-label` |
295+
| `help-block` | `form-text` |
296+
| `float-e-margins` | Remove — no replacement needed |
297+
| `btn-xs` | `btn-sm` |
298+
| `dl-horizontal` | `detail-fields` with `detail-field` / `detail-label` / `detail-value` |
299+
| `admin-actions-filters` | `list-filters` |
300+
| `form-control` on `<select>` | `form-select` |
301+
| `fa-save` | `fa-floppy-disk` |
302+
| `fa-edit` | `fa-pen-to-square` |
303+
| `type="button"` on `<a>` | Remove — not valid HTML on anchors |

0 commit comments

Comments
 (0)