This is a solution to the Dine Website Challenge challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.
- Solution URL: Github Solution
- Live Site URL: Live Site
- View the optimal layout for each page depending on their device's screen size
- Mobile @
375px
- Tablet @
768px
- Desktop @
1440px
- Mobile @
- See hover states for all interactive elements throughout the site
- See the correct content for the Family Gatherings, Special Events, and Social Events section when the user clicks each tab
- Receive an error message when the booking form is submitted if:
- The
Name
orEmail Address
fields are empty should show "This field is required" - The
Email Address
is not formatted correctly should show "Please use a valid email address" - Any of the
Pick a date
orPick a time
fields are empty should show "This field is incomplete"
- The
- Angular (JavaScript framework)
Angular Material- Reactive Forms 😭
- RxJs - library for composing asynchronous and event-based programs by using observable sequences.
- TypeScript
- JavaScript
- ⏰ Moment.js - To validate reservation dates and times
- Figma
- Sass/CSS custom properties(❗️this project required ALOT of CSS)
fxLayout API Angular Flexbox API- Mobile-first workflow
- Semantic HTML5 markup
I created the reservation form in the booking
component using Angular Reactive forms. I also added custom validation for input
and select
<form novalidate
class="rezForm"
(ngSubmit)="saveReservation()"
[formGroup]="rezzoForm">
...
<!-- Name Input -->
<input class="form-control form-input full"
type="text"
placeholder="Name"
formControlName="name"
[ngClass]="{'alert-danger': nameValidationErrorMessage }" />
<span class="alert-danger">
{{nameValidationErrorMessage}}
</span>
...
<div class="group">
<!-- Date Input -->
<div class="error">
<h3
[ngClass]="{'alert-danger':
dateValidationErrorMessage }">Pick a Date</h3>
<span class="alert-danger">{{dateValidationErrorMessage}}</span>
</div>
<div formGroupName="dateGroup"
class="dates">
<!-- Month Select -->
<select formControlName="month"
type="text"
class="form-control form-select small date"
[ngClass]="{'alert-danger': dateValidationErrorMessage }">
<option disabled>MM</option>
<option *ngFor="let month of months">
{{ month }}
</option>
</select>
...
</div>
</div>
<span class="alert-danger mobile">{{dateValidationErrorMessage}}</span>
...
<button class="btn btn-light"
type="submit"
[disabled]="!rezzoForm.valid"> Make
Reservation</button>
</div>
private nameValidationMessages: any = {
required: 'Please enter your name.',
minlength: 'Name must be longer than 4 characters.'
}
...
this.rezzoForm = this.fb.group({
name: ['', [Validators.required, Validators.minLength(4)]],
...
});
...
const nameControl = this.rezzoForm.get('name');
nameControl.valueChanges.pipe(
debounceTime(1000)
).subscribe(
(value: any) =>
this.setNameValidationErrorMessage(nameControl));
...
setNameValidationErrorMessage(n: AbstractControl): void {
this.nameValidationErrorMessage = '';
if ((n.touched || n.dirty) && n.errors) {
this.nameValidationErrorMessage = Object.keys(n.errors).map(
key => this.nameValidationMessages[key]).join(' ')
}
}
...
This project contained many images that would change at each breakpoint. I created a seperate component to render images responsively, using Attribute Binding
picture-responsive.html
<picture>
<source media="(min-width: 900px)"
srcset='/assets/images/homepage/{{imageTitle}}-desktop.jpg'>
<source media="(min-width: 600px)"
srcset='/assets/images/homepage/{{imageTitle}}-tablet.jpg'>
<img src='/assets/images/homepage/{{imageTitle}}-mobile.jpg' />
</picture>
<app-picture-responsive *ngIf="selectedEvent"
imageTitle="{{selectedEvent.imageTitle}}"
class="event-photo"></app-picture-responsive>
...
EventItem[] = [
{
id: 1,
...
imageTitle: "family-gathering",
mobileImage: "../assets/images/homepage/family-gathering-mobile.jpg",
tabletImage: "../assets/images/homepage/family-gathering-tablet.jpg",
desktopImage: "../assets/images/homepage/family-gathering-desktop.jpg"
},
...
⏰ Moment.js library for custom form validation
I used the Moment.js library to validate the date
and time
selects before displaying error messages
...
setDateValidationErrorMessage(month, day, year): void {
this.dateValidationErrorMessage = '';
let now = moment();
let reservation = moment([year.value, moment(month.value, 'MMM').month(), day.value]);
let later = moment().add(6, 'months');
if (!reservation.isValid() || now > reservation || reservation > later) {
this.dateValidationErrorMessage = 'Please select a valid date within the next 6 months'
}
}
...
This Dine project would be a good opportunity to add several useful/interesting features. Usually it is challenging to create ideas for extras to add to these projects. A few features I would like to add are listed below.
➕ Cool animations, this could be a good project to practice parallex, and play with Angular or CSS animations
➕ Authenticate/Authorization with ability to update
- Add authentication /Authorization
- Login/logout, with a password, for managers/admins so that they can update menu options, reservations, and events
- view/edit menu options
- view/edit menu event options
- view/edit menu reservations
- button? reset to default menu/event data default. for testing purposes
➕ Authenticate/Authorization with ability to view only
- add a view only option for admins to view menu, reservations, and events
➕ Menu Page
- add menu component to show list of all current offerings.
➕ About page
- add about chef/restaraunt section/page
➕ Event Booking Component
- add event booking component so that users can book events, similar to the reservation component
- 🙌🏾 Angular Reactive Forms By Deborah Kurata(Pluralsight Course) - This is an amazing YouTube which helped me understand how to build Reactive Forms with Angular. I'd recommend it to anyone still learning this concept.
- ⏰ Moment.js - To validate reservation dates and times
- Reactive forms - This helped me... I really liked this pattern and will use it going forward.
- 🙌🏾 Angular Reactive Forms in 10 Minutes - This is an amazing YouTube which helped me finally understand how to build Reactive Forms with Angular. I'd recommend it to anyone still learning this concept.
- /angular/flex-layout -
This helped me because it's much easier to incorporate Flexbox into a template than a CSS stylesheet 🤔 . I really liked this pattern and will use it going forward.Now, I prefer to create flex styles with Sass - Udemy: Angular (Full App) with Angular Material, Angularfire & NgRx Created by Maximilian Schwarzmüller - Great Tutorials. Would Recommend.
- Managing Image Breakpoints With Angular - Yes. Then I moved the resonsive images into a seperate component👌🏽
- Using forms for user input - 🤷🏽♀️
- Angular 13 Select Dropdown with Reactive Forms Examples - This is an amazing article which helped me finally understand XYZ. I'd recommend it to anyone still learning this concept.
- Frontend Mentor - @Chanda-Abdul
- Website - Chanda Codes
- GitHub - github.com/Chanda-Abdul