feat: CRUD UI — race form, detail fields, edit/delete actions
Some checks failed
CI / build-and-test (pull_request) Has been cancelled
Some checks failed
CI / build-and-test (pull_request) Has been cancelled
- RaceDetailsPage: show all non-null fields (officialUrl, startTime, clusterSchedule, bibPickup) - RaceDetailsPage: add edit link and delete button with confirmation banner - RaceFormPage: universal create/edit form with validation, auto-generated id for new races - Router: add /races/new and /races/:raceId/edit routes - AppLayout: add navigation link to create new race - CSS: buttons (primary/secondary/danger), form fields, confirm banner, responsive layout Made-with: Cursor
This commit is contained in:
@@ -408,6 +408,175 @@ a {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* ─── Buttons ──────────────────────────────────────────── */
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--space-2) var(--space-4);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius-sm);
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: var(--font-size-caption);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.55;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn--primary {
|
||||
background: var(--color-accent);
|
||||
color: var(--color-surface);
|
||||
}
|
||||
|
||||
.btn--primary:hover:not(:disabled) {
|
||||
background: #1766be;
|
||||
}
|
||||
|
||||
.btn--secondary {
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
border-color: var(--color-border);
|
||||
}
|
||||
|
||||
.btn--secondary:hover:not(:disabled) {
|
||||
background: #eef2f6;
|
||||
}
|
||||
|
||||
.btn--danger {
|
||||
background: var(--color-error);
|
||||
color: var(--color-surface);
|
||||
}
|
||||
|
||||
.btn--danger:hover:not(:disabled) {
|
||||
background: #a82e2e;
|
||||
}
|
||||
|
||||
/* ─── Confirm banner ───────────────────────────────────── */
|
||||
|
||||
.confirm-banner {
|
||||
margin-top: var(--space-4);
|
||||
padding: var(--space-4);
|
||||
border: 1px solid var(--color-error);
|
||||
border-radius: var(--radius-md);
|
||||
background: #fef2f2;
|
||||
}
|
||||
|
||||
.confirm-banner__text {
|
||||
margin: 0 0 var(--space-3);
|
||||
font-weight: 600;
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
.confirm-banner__actions {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
/* ─── Race details actions ─────────────────────────────── */
|
||||
|
||||
.race-details-actions {
|
||||
margin-top: var(--space-4);
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.race-details-meta__link {
|
||||
color: var(--color-accent);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.race-details-meta__link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* ─── Race form ────────────────────────────────────────── */
|
||||
|
||||
.race-form {
|
||||
margin-top: var(--space-6);
|
||||
}
|
||||
|
||||
.race-form__group {
|
||||
margin: 0 0 var(--space-6);
|
||||
padding: var(--space-5);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: #fcfdff;
|
||||
}
|
||||
|
||||
.race-form__legend {
|
||||
font-size: var(--font-size-body);
|
||||
font-weight: 700;
|
||||
color: var(--color-text);
|
||||
padding: 0 var(--space-2);
|
||||
}
|
||||
|
||||
.race-form__field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-1);
|
||||
margin-top: var(--space-4);
|
||||
}
|
||||
|
||||
.race-form__field:first-of-type {
|
||||
margin-top: var(--space-3);
|
||||
}
|
||||
|
||||
.race-form__label {
|
||||
font-size: var(--font-size-caption);
|
||||
font-weight: 600;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.race-form__input {
|
||||
font: inherit;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.race-form__input:focus {
|
||||
outline: 2px solid var(--color-accent);
|
||||
outline-offset: -1px;
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.race-form__input--textarea {
|
||||
resize: vertical;
|
||||
min-height: 5rem;
|
||||
}
|
||||
|
||||
.race-form__actions {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-errors {
|
||||
margin: var(--space-3) 0 0;
|
||||
padding: var(--space-3) var(--space-5);
|
||||
border: 1px solid var(--color-error);
|
||||
border-radius: var(--radius-sm);
|
||||
background: #fef2f2;
|
||||
color: var(--color-error);
|
||||
font-size: var(--font-size-caption);
|
||||
}
|
||||
|
||||
.form-errors__item {
|
||||
margin: var(--space-1) 0;
|
||||
}
|
||||
|
||||
/* ─── Responsive ───────────────────────────────────────── */
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.dashboard-grid,
|
||||
.race-lists,
|
||||
@@ -418,4 +587,9 @@ a {
|
||||
.race-details-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.race-form__actions {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user