Project Structure (Frontend)
Example: Create the required files as seen in project structure and add the following codes
<!-- register.component.html -->
<div class="container">
<h2>Register</h2>
<form (submit)="register()">
<div class="form-group">
<label for="username">Username</label>
<input
type="text"
id="username"
class="form-control"
[(ngModel)]="username"
name="username"
required
/>
</div>
<div class="form-group">
<label for="email">Email</label>
<input
type="email"
id="email"
class="form-control"
[(ngModel)]="email"
name="email"
required
/>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
type="password"
id="password"
class="form-control"
[(ngModel)]="password"
name="password"
required
/>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
</div>
<!-- login.component.html -->
<div class="container">
<h2>Login</h2>
<form (ngSubmit)="login()">
<div class="form-group">
<label for="email">Email:</label>
<input
type="email"
class="form-control"
id="email"
name="email"
[(ngModel)]="email"
required
/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input
type="password"
class="form-control"
id="password"
name="password"
[(ngModel)]="password"
required
/>
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
<!-- activities.component.html -->
<div class="container">
<a class="link-button"
(click)="showAddFormFunction()">
Add New Activity</a>
<h2>Activities</h2>
<div class="search-bar">
<input type="text" [(ngModel)]="searchQuery"
placeholder="Search by name" />
<button (click)="applyFilter()"
class="link-button-search">Search</button>
<button (click)="clearFilter()"
class="link-button-clear">Clear</button>
</div>
<div class="search-bar">
<input
type="date"
[(ngModel)]="searchQueryDate"
placeholder="Search by date"
/>
<button (click)="applyFilter()"
class="link-button-search">Search</button>
<button (click)="clearFilterDate()"
class="link-button-clear">Clear</button>
</div>
<div></div>
<div *ngIf="activities.length > 0;
else noActivities" class="table-container">
<table class="activity-table">
<thead>
<tr>
<th>Activity Name</th>
<th>Duration</th>
<th>Calories Burned</th>
<th>Steps</th>
<th>Distance Covered</th>
<th>Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let activity of displayedActivities">
<td>{{ activity.activityName }}</td>
<td>{{ activity.duration }}</td>
<td>{{ activity.caloriesBurned }}</td>
<td>{{ activity.steps }}</td>
<td>{{ activity.distance }}</td>
<td>{{ activity.date.toString().slice(0, 10) }}</td>
<td>
<button class="btn"
(click)="getActivityById(activity._id)">
Get Activity
</button>
<button class="btn"
(click)="populateForm(activity)">Update</button>
<button
class="btn delete-btn"
(click)="confirmDelete(activity._id)"
>
Delete
</button>
</td>
</tr>
</tbody>
</table>
</div>
<ng-template #noActivities>
<div class="no-activities-container">
<p>No activities available</p>
</div>
</ng-template>
<div *ngIf="showUpdateForm"
class="update-form-container">
<button class="close-button"
(click)="cancelUpdate()">X</button>
<h2>Update Activity</h2>
<form class="update-form"
(ngSubmit)="updateActivity()">
<div>
<label for="updateActivityName">
Activity Name:</label>
<input
type="text"
id="updateActivityName"
name="updateActivityName"
[(ngModel)]="updatedActivity.activityName"
required
/>
</div>
<div>
<label for="updateDuration">
Duration (minutes):</label>
<input
type="number"
id="updateDuration"
name="updateDuration"
[(ngModel)]="updatedActivity.duration"
required
/>
</div>
<div>
<label for="updateCaloriesBurned">
Calories Burned:</label>
<input
type="number"
id="updateCaloriesBurned"
name="updateCaloriesBurned"
[(ngModel)]="updatedActivity.caloriesBurned"
required
/>
</div>
<div>
<label for="updateSteps">Steps:</label>
<input
type="number"
id="updateSteps"
name="updateSteps"
[(ngModel)]="updatedActivity.steps"
required
/>
</div>
<div>
<label for="updateDistance">Distance:</label>
<input
type="number"
id="updateDistance"
name="updateDistance"
[(ngModel)]="updatedActivity.distance"
required
/>
</div>
<div>
<button type="submit"
(click)="ifLoggedIn()">Update Activity</button>
<button type="button"
(click)="cancelUpdate()">Cancel</button>
</div>
</form>
</div>
<div
*ngIf="!showUpdateForm && activityById._id"
class="view-activity-container"
>
<button class="close-button"
(click)="closeView()">X</button>
<h2>View Activity</h2>
<form class="view-activity-form">
<div>
<label for="activityName">Activity Name:</label>
<input
type="text"
id="activityName"
name="activityName"
[(ngModel)]="activityById.activityName"
readonly
/>
</div>
<div>
<label for="duration">Duration (minutes):</label>
<input
type="number"
id="duration"
name="duration"
[(ngModel)]="activityById.duration"
readonly
/>
</div>
<div>
<label for="caloriesBurned">Calories Burned:</label>
<input
type="number"
id="caloriesBurned"
name="caloriesBurned"
[(ngModel)]="activityById.caloriesBurned"
readonly
/>
</div>
<div>
<label for="steps">Steps:</label>
<input
type="number"
id="steps"
name="steps"
[(ngModel)]="activityById.steps"
readonly
/>
</div>
<div>
<label for="distance">Distance:</label>
<input
type="number"
id="distance"
name="distance"
[(ngModel)]="activityById.distance"
readonly
/>
</div>
<div>
<label for="date">Date:</label>
<input
type="text"
id="date"
name="date"
[(ngModel)]="getActivityByIdDate"
readonly
/>
</div>
<div>
<a href="/activities"
class="link-button">Get All Activities</a>
</div>
</form>
</div>
<div
class="update-form-container"
*ngIf="showAddForm && !showUpdateForm && !activityById._id"
>
<button class="close-button"
(click)="closeAddForm()">X</button>
<h2>Add Activity</h2>
<form class="update-form"
(ngSubmit)="addActivity()">
<div>
<label for="activityName">Activity Name:</label>
<input
type="text"
id="activityName"
name="activityName"
[(ngModel)]="activity.activityName"
required
/>
</div>
<div>
<label for="duration">Duration (minutes):</label>
<input
type="number"
id="duration"
name="duration"
[(ngModel)]="activity.duration"
required
/>
</div>
<div>
<label for="caloriesBurned">Calories Burned:</label>
<input
type="number"
id="caloriesBurned"
name="caloriesBurned"
[(ngModel)]="activity.caloriesBurned"
required
/>
</div>
<div>
<label for="steps">Steps:</label>
<input
type="number"
id="steps"
name="steps"
[(ngModel)]="activity.steps"
required
/>
</div>
<div>
<label for="distance">Distance:</label>
<input
type="number"
id="distance"
name="distance"
[(ngModel)]="activity.distance"
required
/>
</div>
<div>
<label for="date">Date:</label>
<input
type="date"
id="date"
name="date"
[(ngModel)]="activity.date"
required
/>
</div>
<div>
<button type="submit"
(click)="ifLoggedIn()">Add Activity</button>
<button type="button"
(click)="resetForm()">Clear</button>
</div>
</form>
</div>
</div>
<!-- app.component.html -->
<main class="main" *ngIf="componentReload">
<div class="content">
<div class="left-side">
<h1>{{ title }}</h1>
<div>
<ul>
<li><a href="login" *ngIf="!isLoggedIn">Login</a></li>
<li><a href="register" *ngIf="!isLoggedIn">Register</a></li>
<li><a (click)="logout()" *ngIf="isLoggedIn">Logout</a></li>
</ul>
</div>
</div>
</div>
</main>
<router-outlet></router-outlet>
/* app.component.css */
.main {
display: flex;
flex-direction: column;
align-items: center;
background-color: darkslategrey;
color: white;
}
.content {
width: 100%;
max-width: 1200px;
padding: 20px;
}
.left-side {
display: flex;
justify-content: space-between;
align-items: center;
}
.left-side h1 {
margin: 0;
margin-left: 3%;
}
.left-side ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.left-side li {
display: inline;
margin-right: 20px;
}
.left-side li a {
text-decoration: none;
color: white;
font-weight: bold;
font-size: 1.5rem;
}
.left-side li a:hover {
color: lightgray;
}
a {
cursor: pointer;
}
/* app.component.css */
.main {
display: flex;
flex-direction: column;
align-items: center;
background-color: darkslategrey;
color: white;
}
.content {
width: 100%;
max-width: 1200px;
padding: 20px;
}
.left-side {
display: flex;
justify-content: space-between;
align-items: center;
}
.left-side h1 {
margin: 0;
margin-left: 3%;
}
.left-side ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.left-side li {
display: inline;
margin-right: 20px;
}
.left-side li a {
text-decoration: none;
color: white;
font-weight: bold;
font-size: 1.5rem;
}
.left-side li a:hover {
color: lightgray;
}
a {
cursor: pointer;
}
/* login.component.css */
.container {
width: 50%;
margin: 2rem auto;
padding: 1.5vmax;
padding-right: 3.5vmax;
border: 1px solid #ccc;
border-radius: 5px;
}
h2 {
text-align: center;
margin-bottom: 20px;
font-size: 2rem;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="email"],
input[type="password"] {
width: 99%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
button[type="submit"] {
width: 20%;
padding: 1.1vmax;
background-color: #0056b3;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
font-size: 1rem;
align-self: center;
margin-top: 1vmax;
}
/* activities.component.css */
.container {
max-width: 100%;
margin: 0 auto;
padding: 20px;
}
.search-bar {
display: flex;
margin-bottom: 10px;
}
.search-bar input {
flex: 1;
margin-right: 10px;
}
.activity-table {
width: 100%;
border-collapse: collapse;
}
.activity-table th,
.activity-table td {
padding: 10px;
border: 1px solid #ccc;
text-align: center;
}
.activity-table th {
background-color: #f0f0f0;
}
.update-form-container,
.view-activity-container {
margin-top: 20px;
padding: 20px;
border: 1px solid #ccc;
}
.update-form,
.view-activity-form {
display: flex;
flex-direction: column;
}
.update-form input,
.view-activity-form input {
margin-bottom: 10px;
}
.btn {
padding: 8px 16px;
margin-right: 10px;
margin-bottom: 1.5vmax;
cursor: pointer;
background-color: #0056b3;
color: #fff;
border: none;
border-radius: 4px;
}
.delete-btn {
background-color: #dc3545;
}
.link-button {
display: inline-block;
padding: 8px 16px;
background-color: #1b599a;
color: #fff;
text-decoration: none;
border-radius: 4px;
cursor: pointer;
}
.link-button-search {
display: inline-block;
padding: 8px 16px;
background-color: green;
color: #fff;
text-decoration: none;
border-radius: 4px;
cursor: pointer;
border: none;
margin-right: 1vmax;
}
.link-button-clear {
display: inline-block;
padding: 8px 16px;
background-color: #dc3545;
color: #fff;
text-decoration: none;
border-radius: 4px;
cursor: pointer;
border: none;
}
.no-activities-container {
margin-top: 20px;
padding: 10px;
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
border-radius: 4px;
}
.no-activities-container p {
text-align: center;
margin: 0;
}
.update-form-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90%;
background-color: rgba(255, 255, 255, 1);
padding: 3.7vmax;
border-radius: 5px;
}
.update-form-container h2 {
text-align: center;
font-size: 2rem;
}
.update-form-container .close-btn {
position: absolute;
top: 5px;
right: 5px;
font-size: 18px;
color: #555;
cursor: pointer;
}
.update-form-container .close-btn:hover {
color: #333;
}
.update-form label {
display: block;
margin-bottom: 5px;
}
.update-form input[type="text"],
.update-form input[type="number"],
.update-form input[type="date"] {
width: calc(100% - 12px);
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.update-form button[type="submit"],
.update-form button[type="button"] {
width: 10%;
padding: 10px;
background-color: green;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
margin-right: 10px;
}
.update-form button[type="button"] {
background-color: #dc3545;
}
.view-activity-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90%;
background-color: rgba(255, 255, 255, 1);
padding: 3.7vmax;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.view-activity-container h2 {
text-align: center;
font-size: 2rem;
}
.view-activity-form label {
display: block;
margin-bottom: 5px;
}
.view-activity-form input[type="text"],
.view-activity-form input[type="number"],
.view-activity-form input[type="date"] {
width: calc(100% - 12px);
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.view-activity-form button[type="submit"],
.view-activity-form a {
width: 10%;
padding: 10px;
background-color: #0056b3;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
text-align: center;
display: inline-block;
text-decoration: none;
}
.view-activity-form button[type="submit"]:hover,
.view-activity-form a:hover {
background-color: #0056b3;
}
.close-button {
position: absolute;
top: 10px;
right: 10px;
padding: 5px 10px;
background-color: #ccc;
border: none;
border-radius: 5px;
cursor: pointer;
}
.close-button:hover {
background-color: #aaa;
}
// register.component.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../auth.service';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
@Component({
selector: 'app-register',
standalone: true,
imports: [FormsModule],
templateUrl: './register.component.html',
styleUrls: ['./register.component.css'],
})
export class RegisterComponent implements OnInit {
username!: string;
email!: string;
password!: string;
constructor(private authService: AuthService,
private router: Router) { }
ngOnInit(): void {
}
register(): void {
const userData = {
username: this.username,
email: this.email,
password: this.password
};
this.authService.register(userData).subscribe(
(res: any) => {
this.router.navigate(["/login"]);
},
(err: any) => {
console.error(err);
}
);
}
}
// app/auth/login/login.component.ts
import { Component, EventEmitter, Output } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../../auth.service';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-login',
standalone: true,
imports: [FormsModule],
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
email!: string;
password!: string;
credentials: any = {};
constructor(private authService: AuthService,
private router: Router) { }
ngOnInit(): void {
}
login(): void {
const credentials = {
email: this.email,
password: this.password
};
this.authService.login(credentials).subscribe(
(response) => {
const token = response.token;
localStorage.setItem("token", token);
this.authService.setAuthenticationStatus(true);
this.router.navigate(['/activities']);
},
error => {
console.error('Error logging in:', error);
}
);
}
}
// activities.component.ts
import { Component, OnInit } from '@angular/core';
import { Activity } from '../activity.model';
import { ActivityService } from '../activity.service';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { AuthService } from '../auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-activities',
standalone: true,
imports: [FormsModule, CommonModule],
templateUrl: './activities.component.html',
styleUrls: ['./activities.component.css']
})
export class ActivitiesComponent implements OnInit {
activities: Activity[] = [];
activityById: Activity = {
_id: '',
activityName: '',
duration: 0,
caloriesBurned: 0,
steps: 0,
distance: 0,
date: new Date()
};
showUpdateForm: boolean = false;
updatedActivity: Activity = {
_id: '', activityName: '', duration: 0,
caloriesBurned: 0, steps: 0, distance: 0, date: new Date()
};
searchQuery: any;
searchQueryDate: any;
displayedActivities: Activity[] = [];
activity: Activity = {
_id: '',
activityName: '',
duration: 0,
caloriesBurned: 0,
steps: 0,
distance: 0,
date: new Date()
};
showAddForm: boolean = false;
getActivityByIdDate: string = '';
constructor(private activityService: ActivityService,
private authService: AuthService, private router: Router) { }
ngOnInit(): void {
if (this.authService.isAuthenticated()) {
this.getAllActivities();
}
}
ifLoggedIn(): void {
this.authService.isAuthenticated().subscribe(isAuthenticated => {
return isAuthenticated;
});
}
getAllActivities(): void {
if (typeof localStorage !== 'undefined') {
const token = localStorage.getItem('token');
if (token) {
this.activityService.getAllActivities(token).subscribe(
(activities: Activity[]) => {
this.activities = activities;
this.displayedActivities = [...this.activities];
},
error => {
console.error('Error fetching activities:', error);
}
);
}
}
}
getActivityById(id: string): void {
const token = localStorage.getItem('token');
this.showUpdateForm = false;
this.showAddForm = false;
console.log(id);
if (token) {
this.activityService.getActivityById(token, id).subscribe(
(activity) => {
this.activityById = activity;
this.getActivityByIdDate = this.activityById.date.toString().slice(0, 10);
},
error => {
console.error('Error in getting activity:', error);
}
)
}
}
populateForm(activity: Activity): void {
this.updatedActivity = { ...activity };
this.showUpdateForm = true;
}
updateActivity(): void {
const token = localStorage.getItem('token');
if (token) {
this.activityService.updateActivity(token, this.updatedActivity).subscribe(
(updatedActivity) => {
const index = this.activities.findIndex(a => a._id === updatedActivity._id);
if (index !== -1) {
this.router.navigate(["/activities"]);
this.activities[index] = updatedActivity;
this.getAllActivities();
this.showUpdateForm = false;
}
this.cancelUpdate();
},
error => {
console.error('Error updating activity:', error);
}
);
}
}
cancelUpdate(): void {
this.showUpdateForm = false;
this.updatedActivity = {
_id: '', activityName: '',
duration: 0, caloriesBurned: 0, steps: 0, distance: 0,
date: new Date()
};
this.activityById = {
_id: '',
activityName: '',
duration: 0,
caloriesBurned: 0,
steps: 0,
distance: 0,
date: new Date()
};
}
closeView(): void {
this.activityById = {
_id: '',
activityName: '',
duration: 0,
caloriesBurned: 0,
steps: 0,
distance: 0,
date: new Date()
};
}
confirmDelete(activityId: string): void {
const confirmDelete = window.confirm('Are you sure you want to delete this activity?');
if (confirmDelete) {
this.deleteActivity(activityId);
}
}
deleteActivity(id: string): void {
const token = localStorage.getItem('token');
this.showUpdateForm = false;
if (token) {
this.activityService.deleteActivity(token, id).subscribe(
() => {
this.activities = this.activities.filter(activity => activity._id !== id);
this.displayedActivities = [...this.activities]
},
error => {
console.error('Error deleting activity:', error);
}
);
}
}
addActivity(): void {
const token = localStorage.getItem('token');
if (token) {
this.showAddForm = true;
this.showUpdateForm = false;
this.activityService.addActivity(token, this.activity).subscribe(
(newActivity: Activity) => {
this.closeAddForm();
this.getAllActivities();
this.router.navigate(["/activities"]);
},
error => {
console.error('Error adding activity:', error);
}
);
}
}
resetForm(): void {
this.activity = {
_id: '',
activityName: '',
duration: 0,
caloriesBurned: 0,
steps: 0,
distance: 0,
date: new Date()
};
}
closeAddForm(): void {
this.activity = {
_id: '',
activityName: '',
duration: 0,
caloriesBurned: 0,
steps: 0,
distance: 0,
date: new Date()
};
this.showAddForm = false;
}
showAddFormFunction(): void {
this.showAddForm = true;
}
applyFilter(): void {
if (!this.searchQuery?.trim() && !this.searchQueryDate?.trim()) {
this.displayedActivities = [...this.activities];
}
else if (this.searchQueryDate?.trim() && !this.searchQuery?.trim()) {
const queryDate = this.searchQueryDate ?
this.searchQueryDate.toLowerCase().trim() : this.searchQueryDate;
this.displayedActivities = this.activities.filter(activity =>
activity.date.toString().toLowerCase().includes(queryDate)
);
}
else if (!this.searchQueryDate?.trim() && this.searchQuery?.trim()) {
const query = this.searchQuery ?
this.searchQuery.toLowerCase().trim() : this.searchQuery;
this.displayedActivities = this.activities.filter(activity =>
activity.activityName.toLowerCase().includes(query)
);
}
else {
const query = this.searchQuery ?
this.searchQuery.toLowerCase().trim() : this.searchQuery;
const queryDate = this.searchQueryDate ?
this.searchQueryDate.toLowerCase().trim() : this.searchQueryDate;
this.displayedActivities = this.activities.filter(activity =>
activity.activityName.toLowerCase().includes(query) &&
activity.date.toString().toLowerCase().includes(queryDate)
);
}
}
clearFilter(): void {
this.searchQuery = '';
this.applyFilter();
}
clearFilterDate(): void {
this.searchQueryDate = "";
this.applyFilter();
}
}
// app.component.ts
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Output } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Router, RouterOutlet } from '@angular/router';
import { AuthService } from './auth.service';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, FormsModule, CommonModule,],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'w3wiki Health Tracker';
isLoggedIn: any;
componentReload: boolean = false;
constructor(private router: Router,
private authService: AuthService) { }
ngOnInit(): void {
if (typeof localStorage !== 'undefined'
&& localStorage.getItem('token')) {
this.isLoggedIn = true;
}
else {
this.ifLoggedIn();
}
this.componentReload = true;
}
ifLoggedIn(): void {
this.authService.isAuthenticated()
.subscribe(isAuthenticated => {
this.isLoggedIn = isAuthenticated;
});
}
logout(): void {
this.authService.setAuthenticationStatus(false);
this.isLoggedIn = false;
localStorage.removeItem('token');
this.router.navigate(["/login"]);
}
}
// app.routes.ts
import { Routes } from '@angular/router';
import { LoginComponent } from './auth/login/login.component';
import { RegisterComponent } from './auth/register/register.component';
import { ActivitiesComponent } from './activities/activities.component';
import { AppComponent } from './app.component';
export const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: 'activities', component: ActivitiesComponent },
{ path: 'activities/create', component: ActivitiesComponent },
{ path: 'activities/update/:id', component: ActivitiesComponent },
{ path: 'activities/delete/:id', component: ActivitiesComponent },
{ path: 'activities/:id', component: ActivitiesComponent },
];
// app.module.ts
import { InjectionToken, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { RegisterComponent } from './auth/register/register.component';
import { LoginComponent } from './auth/login/login.component';
import { ActivitiesComponent } from './activities/activities.component';
import { JwtHelperService, JWT_OPTIONS } from '@auth0/angular-jwt';
import { RouterModule } from '@angular/router';
import { routes } from './app.routes';
@NgModule({
declarations: [
AppComponent,
RegisterComponent,
LoginComponent,
ActivitiesComponent
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes),
],
exports: [RouterModule],
providers: [{ provide: JWT_OPTIONS, useValue: JWT_OPTIONS },
JwtHelperService],
bootstrap: [AppComponent]
})
export class AppModule { }
To start the frontend run the following command.
ng serve
Output:
Health Tracker using MEAN Stack
In the fast-paced world, maintaining a healthy lifestyle is more important than ever. Technology can play a significant role in helping individuals monitor and improve their health. In this article, we’ll explore how to use the power of the MEAN (MongoDB, Express.js, Angular, Node.js) stack to build a robust and feature-rich Health Tracker application.
Project Preview: Let us have a look at how the final output will look like.
Contact Us