Skip to content

Commit 9d0bd17

Browse files
committed
Fix comments from John
1 parent f99d987 commit 9d0bd17

File tree

5 files changed

+179
-135
lines changed

5 files changed

+179
-135
lines changed

web-app/admin/src/app/admin/admin-event/create-event/create-event.component.html

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ <h2 class="dialog-title">Create a New Event</h2>
44
</div>
55

66
<div class="dialog-content">
7-
<div *ngIf="errorMessage" class="error-alert">
7+
<div *ngIf="errorMessage" class="error-popover">
88
<i class="fa fa-exclamation-triangle"></i>
99
<span>{{ errorMessage }}</span>
1010
</div>
@@ -18,15 +18,16 @@ <h2 class="dialog-title">Create a New Event</h2>
1818
formControlName="name"
1919
placeholder="Enter event name"
2020
/>
21-
<div
22-
*ngIf="
23-
eventForm.get('name').invalid &&
24-
(eventForm.get('name').touched || eventForm.get('name').dirty)
25-
"
26-
class="field-error"
27-
>
28-
<i class="fa fa-exclamation-circle"></i>
29-
Name is required
21+
<div class="field-error">
22+
<span
23+
class="error-text"
24+
[class.visible]="
25+
eventForm.get('name').invalid &&
26+
(eventForm.get('name').touched || eventForm.get('name').dirty)
27+
"
28+
>
29+
Name is required
30+
</span>
3031
</div>
3132
</div>
3233

Lines changed: 113 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,138 @@
11
.error-alert {
2-
display: flex;
3-
align-items: center;
4-
gap: 0.5rem;
5-
padding: 1rem;
6-
background-color: #fef2f2;
7-
border: 1px solid #fecaca;
8-
border-radius: 8px;
9-
margin-bottom: 1.5rem;
10-
color: #dc2626;
11-
font-size: 0.875rem;
2+
display: flex;
3+
align-items: center;
4+
gap: 0.5rem;
5+
padding: 1rem;
6+
background-color: #fef2f2;
7+
border: 1px solid #fecaca;
8+
border-radius: 8px;
9+
margin-bottom: 1.5rem;
10+
color: #dc2626;
11+
font-size: 0.875rem;
1212

13-
i {
14-
flex-shrink: 0;
15-
font-size: 1rem;
16-
}
13+
i {
14+
flex-shrink: 0;
15+
font-size: 1rem;
16+
}
1717
}
1818

1919
.event-form {
20-
display: flex;
21-
flex-direction: column;
22-
gap: 1.5rem;
20+
display: flex;
21+
flex-direction: column;
22+
gap: 1.5rem;
2323
}
2424

2525
.form-field {
26-
display: flex;
27-
flex-direction: column;
28-
gap: 0.5rem;
29-
30-
.field-label {
31-
font-size: 0.875rem;
32-
font-weight: 600;
33-
color: #374151;
34-
text-transform: uppercase;
35-
letter-spacing: 0.05em;
26+
display: flex;
27+
flex-direction: column;
28+
gap: 0.5rem;
29+
30+
.field-label {
31+
font-size: 0.875rem;
32+
font-weight: 600;
33+
color: #374151;
34+
text-transform: uppercase;
35+
letter-spacing: 0.05em;
36+
}
37+
38+
.form-input {
39+
width: 100%;
40+
padding: 0.75rem 1rem;
41+
border: 1px solid #d1d5db;
42+
border-radius: 8px;
43+
font-size: 0.875rem;
44+
background-color: #f9fafb;
45+
transition: all 0.2s ease;
46+
resize: vertical;
47+
48+
&:focus {
49+
outline: none;
50+
border-color: #3b82f6;
51+
background-color: white;
52+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
3653
}
3754

38-
.form-input {
39-
width: 100%;
40-
padding: 0.75rem 1rem;
41-
border: 1px solid #d1d5db;
42-
border-radius: 8px;
43-
font-size: 0.875rem;
44-
background-color: #f9fafb;
45-
transition: all 0.2s ease;
46-
resize: vertical;
47-
48-
&:focus {
49-
outline: none;
50-
border-color: #3b82f6;
51-
background-color: white;
52-
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
53-
}
54-
55-
&::placeholder {
56-
color: #9ca3af;
57-
}
58-
59-
&:disabled {
60-
background-color: #f3f4f6;
61-
color: #9ca3af;
62-
cursor: not-allowed;
63-
}
55+
&::placeholder {
56+
color: #9ca3af;
6457
}
6558

66-
.field-error {
67-
display: flex;
68-
align-items: center;
69-
gap: 0.25rem;
70-
color: #dc2626;
71-
font-size: 0.75rem;
72-
margin-top: 0.25rem;
73-
74-
i {
75-
font-size: 0.75rem;
76-
}
59+
&:disabled {
60+
background-color: #f3f4f6;
61+
color: #9ca3af;
62+
cursor: not-allowed;
7763
}
64+
}
65+
66+
.field-error {
67+
min-height: 1.2em;
68+
display: flex;
69+
align-items: center;
70+
gap: 4px;
71+
}
72+
73+
.field-error .error-text {
74+
opacity: 0;
75+
transition: opacity 0.2s ease;
76+
color: #d9534f;
77+
}
78+
79+
.field-error .error-text.visible {
80+
opacity: 1;
81+
}
7882
}
7983

8084
::ng-deep .mat-dialog-container {
81-
padding: 0;
82-
border-radius: 12px;
83-
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04) !important;
85+
padding: 0;
86+
border-radius: 12px;
87+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
88+
0 10px 10px -5px rgba(0, 0, 0, 0.04) !important;
89+
}
90+
91+
::ng-deep mat-dialog-container {
92+
height: 460px;
93+
width: 700px;
8494
}
8595

8696
::ng-deep .mat-dialog-actions {
87-
padding: 0;
88-
margin: 0;
97+
padding: 0;
98+
margin: 0;
8999
}
90100

91101
::ng-deep .mat-dialog-content {
92-
padding: 0;
93-
margin: 0;
102+
padding: 0;
103+
margin: 0;
94104
}
95105

96106
::ng-deep .mat-dialog-title {
97-
padding: 0;
98-
margin: 0;
99-
}
107+
padding: 0;
108+
margin: 0;
109+
}
110+
111+
.error-popover {
112+
position: absolute;
113+
top: 10px;
114+
left: 50%;
115+
transform: translateX(-50%);
116+
background-color: #f8d7da;
117+
color: #721c24;
118+
padding: 10px 20px;
119+
border-radius: 4px;
120+
border: 1px solid #f5c6cb;
121+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
122+
display: flex;
123+
align-items: center;
124+
gap: 8px;
125+
z-index: 1000;
126+
animation: slideDown 0.3s ease;
127+
}
128+
129+
@keyframes slideDown {
130+
from {
131+
opacity: 0;
132+
transform: translate(-50%, -10px);
133+
}
134+
to {
135+
opacity: 1;
136+
transform: translate(-50%, 0);
137+
}
138+
}

web-app/admin/src/app/admin/admin-event/create-event/create-event.component.ts

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,57 +9,61 @@ import { Event } from 'src/app/filter/filter.types';
99
* Provides a form interface with validation for event name (required) and description (optional).
1010
*/
1111
@Component({
12-
selector: 'mage-admin-event-create',
13-
templateUrl: './create-event.component.html',
14-
styleUrls: ['./create-event.component.scss']
12+
selector: 'mage-admin-event-create',
13+
templateUrl: './create-event.component.html',
14+
styleUrls: ['./create-event.component.scss']
1515
})
1616
export class CreateEventDialogComponent {
17-
eventForm: FormGroup;
18-
errorMessage: string = '';
17+
eventForm: FormGroup;
18+
errorMessage: string = '';
1919

20-
constructor(
21-
public dialogRef: MatDialogRef<CreateEventDialogComponent>,
22-
@Inject(MAT_DIALOG_DATA) public data: { event: Partial<Event> },
23-
private fb: FormBuilder,
24-
private eventsService: EventsService
25-
) {
26-
this.eventForm = this.fb.group({
27-
name: [data.event?.name || '', [Validators.required]],
28-
description: [data.event?.description || '']
29-
});
20+
constructor(
21+
public dialogRef: MatDialogRef<CreateEventDialogComponent>,
22+
@Inject(MAT_DIALOG_DATA) public data: { event: Partial<Event> },
23+
private fb: FormBuilder,
24+
private eventsService: EventsService
25+
) {
26+
this.eventForm = this.fb.group({
27+
name: [data.event?.name ?? '', [Validators.required]],
28+
description: [data.event?.description ?? '']
29+
});
30+
}
31+
32+
/**
33+
* Handles form submission for creating a new event.
34+
* Validates the form, creates the event via the events service, and closes the dialog on success.
35+
*/
36+
save(): void {
37+
if (this.eventForm.invalid) {
38+
this.errorMessage = 'Please fill in all required fields.';
39+
return;
3040
}
3141

32-
/**
33-
* Handles form submission for creating a new event.
34-
* Validates the form, creates the event via the events service, and closes the dialog on success.
35-
*/
36-
save(): void {
37-
if (this.eventForm.invalid) {
38-
this.errorMessage = 'Please fill in all required fields.';
39-
return;
42+
this.errorMessage = '';
43+
const eventData = this.eventForm.value;
44+
this.eventsService.createEvent(eventData).subscribe({
45+
next: (newEvent) => {
46+
this.dialogRef.close(newEvent);
47+
},
48+
error: (err) => {
49+
if (err.status === 400 && err.error?.errors) {
50+
const fieldErrors = err.error.errors;
51+
if (fieldErrors.name?.type === 'unique') {
52+
this.errorMessage = fieldErrors.name.message;
53+
} else {
54+
this.errorMessage = err.error.message ?? 'Validation failed';
55+
}
56+
} else {
57+
this.errorMessage = 'Failed to create event. Please try again.';
4058
}
59+
}
60+
});
61+
}
4162

42-
this.errorMessage = '';
43-
const eventData = this.eventForm.value;
44-
this.eventsService.createEvent(eventData).subscribe({
45-
next: (newEvent) => {
46-
this.dialogRef.close(newEvent);
47-
},
48-
error: (err) => {
49-
if (err.status === 409) {
50-
this.errorMessage = err.error;
51-
}
52-
else {
53-
this.errorMessage = 'Failed to create event. Please try again.';
54-
}
55-
}
56-
});
57-
}
58-
59-
/**
60-
* Closes the dialog without saving any data or making any changes.
61-
*/
62-
cancel(): void {
63-
this.dialogRef.close();
64-
}
63+
/**
64+
* Closes the dialog without saving any data or making any changes.
65+
*/
66+
cancel(): void {
67+
this.dialogRef.close();
68+
}
6569
}

web-app/admin/src/app/admin/admin-event/dashboard/event-dashboard.component.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ $max-height: 72.8vh;
413413

414414
::ng-deep .mat-form-field-label-wrapper {
415415
top: -12px;
416-
left: -7px;
416+
left: -1px;
417417
}
418418
}
419419
::ng-deep input.search-input.ng-untouched.ng-pristine.ng-valid,

web-app/admin/src/app/admin/admin-event/dashboard/event-dashboard.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ export class EventDashboardComponent implements OnInit {
8282
const term = this.eventSearch.trim().toLowerCase();
8383
this.filteredEvents = this.events.items.filter(
8484
(e) =>
85-
!term ||
86-
e.name?.toLowerCase().includes(term) ||
87-
e.description?.toLowerCase().includes(term)
85+
!term || (
86+
e.name?.toLowerCase().includes(term) ??
87+
e.description?.toLowerCase().includes(term))
8888
);
89-
this.totalEvents = this.events.totalCount || 0;
89+
this.totalEvents = this.events.totalCount ?? 0;
9090
}
9191

9292
/** Handle search term change */

0 commit comments

Comments
 (0)