0% found this document useful (0 votes)
76 views13 pages

Angular Calendar View Examples

The document provides a comprehensive guide for setting up a booking application using Spring Boot and Angular. It includes code snippets for creating a Booking API, integrating FullCalendar for scheduling, and implementing user authentication with JWT. Additionally, it outlines steps for managing provider availability, conflict checking, and enhancing the UI/UX of the booking experience.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
76 views13 pages

Angular Calendar View Examples

The document provides a comprehensive guide for setting up a booking application using Spring Boot and Angular. It includes code snippets for creating a Booking API, integrating FullCalendar for scheduling, and implementing user authentication with JWT. Additionally, it outlines steps for managing provider availability, conflict checking, and enhancing the UI/UX of the booking experience.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

To get started with a working example, you’ll need to log in to use ChatGPT canvas,

where we can collaboratively build out the code. In the meantime, I’ll give you the code
snippets right here so you can try them in your project.

✅ 1. Spring Boot – Basic Booking API Setup


🧩 Booking Entity
java Copy Edit
@Entity public class Booking { @Id @GeneratedValue private Long id;
@ManyToOne private Service service; @ManyToOne private User user;
private LocalDateTime startTime; private LocalDateTime endTime; //
Getters and setters... }

🧩 BookingRepository
java Copy Edit
public interface BookingRepository extends JpaRepository<Booking, Long>
{ List<Booking> findByUserId(Long userId); }

🧩 BookingController
java Copy Edit
@RestController @RequestMapping("/api/bookings") public class
BookingController { @Autowired private BookingRepository bookingRepo;
@PostMapping public Booking createBooking(@RequestBody Booking booking)
{ return bookingRepo.save(booking); } @GetMapping public List<Booking>
getBookings(@RequestParam(required = false) Long userId) { return userId
== null ? bookingRepo.findAll() : bookingRepo.findByUserId(userId); } }

✅ 2. Angular 15 + FullCalendar Setup


🧩 Install FullCalendar
bash Copy Edit
npm install @fullcalendar/angular @fullcalendar/daygrid

🧩 calendar.module.ts
ts Copy Edit
import { FullCalendarModule } from '@fullcalendar/angular'; import {
NgModule } from '@angular/core'; @NgModule({ imports:
[FullCalendarModule], exports: [FullCalendarModule], }) export class
CalendarModule {}

🧩 calendar.component.ts
ts Copy Edit
import { Component } from '@angular/core'; import { CalendarOptions }
from '@fullcalendar/core'; import dayGridPlugin from
'@fullcalendar/daygrid'; import { HttpClient } from
'@angular/common/http'; @Component({ selector: 'app-calendar',
templateUrl: './calendar.component.html' }) export class
CalendarComponent { calendarOptions: CalendarOptions;
constructor(private http: HttpClient) { this.http.get<any[]>
('/api/bookings').subscribe(bookings => { this.calendarOptions = {
plugins: [dayGridPlugin], initialView: 'dayGridMonth', events:
bookings.map(b => ({ title: 'Booked: ' + b.service.name, start:
b.startTime, end: b.endTime, })), dateClick:
this.handleDateClick.bind(this), }; }); } handleDateClick(arg: any) {
alert('You clicked on ' + arg.dateStr); // Optionally open a dialog to
show available slots and book one } }

🧩 calendar.component.html
html Copy Edit
<full-calendar [options]="calendarOptions"></full-calendar>

✅ Optional: Booking Dialog (Angular Material)


You can use MatDialog to open a booking form when a date is clicked. If you'd like, I
can show that next.
Would you like:
1. Dialog form for selecting and confirming a booking?
2. Availability slot generation logic?
3. Role-based service provider vs user view?
Let me know what you want to focus on next.

ok what is the next


Great! The next logical step is to allow users to book a service by selecting from
available time slots, and for that, we need:

✅ Step 3: Availability Slot Selection and Booking Dialog


This is what we’ll do:
1. When the user clicks a date in the calendar, open a dialog.
2. Fetch available time slots for a service on that date.
3. Let the user pick one and confirm the booking.

🧩 3.1 Angular – Booking Dialog


Step 1: Generate the dialog component
bash Copy Edit
ng generate component booking-dialog

booking-dialog.component.ts
ts Copy Edit
import { Component, Inject } from '@angular/core'; import {
MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import
{ HttpClient } from '@angular/common/http'; @Component({ selector: 'app-
booking-dialog', templateUrl: './booking-dialog.component.html' })
export class BookingDialogComponent { availableSlots: any[] = [];
selectedSlot: any; constructor( private http: HttpClient, private
dialogRef: MatDialogRef<BookingDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { date: string, serviceId: number
} ) { this.fetchAvailableSlots(); } fetchAvailableSlots() {
this.http.get<any[]>(`/api/services/${this.data.serviceId}/availability?
date=${this.data.date}`) .subscribe(slots => this.availableSlots =
slots); } book() { const booking = { service: { id: this.data.serviceId
}, user: { id: 1 }, // use actual logged-in user ID startTime:
this.selectedSlot.startTime, endTime: this.selectedSlot.endTime };
this.http.post('/api/bookings', booking).subscribe(() => {
this.dialogRef.close(true); }); } }

booking-dialog.component.html
html Copy Edit
<h1 mat-dialog-title>Available Time Slots</h1> <div mat-dialog-content>
<mat-selection-list [(ngModel)]="selectedSlot"> <mat-list-option
*ngFor="let slot of availableSlots" [value]="slot"> {{ slot.startTime |
date:'shortTime' }} - {{ slot.endTime | date:'shortTime' }} </mat-list-
option> </mat-selection-list> </div> <div mat-dialog-actions> <button
mat-button (click)="dialogRef.close()">Cancel</button> <button mat-
raised-button color="primary" (click)="book()"
[disabled]="!selectedSlot">Book</button> </div>

🧩 3.2 Update calendar.component.ts to open dialog


ts Copy Edit
import { MatDialog } from '@angular/material/dialog'; import {
BookingDialogComponent } from '../booking-dialog/booking-
dialog.component'; constructor(private dialog: MatDialog, private http:
HttpClient) {} handleDateClick(arg: any) { const dateStr = arg.dateStr;
this.dialog.open(BookingDialogComponent, { width: '400px', data: { date:
dateStr, serviceId: 1 // Replace with selected service ID }
}).afterClosed().subscribe(result => { if (result) { // Refresh bookings
this.ngOnInit(); // or call a method that reloads events } }); }

🧩 3.3 Backend – Add availability API


In your ServiceController :
java Copy Edit
@GetMapping("/{id}/availability") public List<TimeSlot>
getAvailability( @PathVariable Long id, @RequestParam LocalDate date) {
// Dummy slots for example List<TimeSlot> slots = new ArrayList<>();
slots.add(new TimeSlot(LocalDateTime.of(date, LocalTime.of(9, 0)),
LocalDateTime.of(date, LocalTime.of(10, 0)))); slots.add(new
TimeSlot(LocalDateTime.of(date, LocalTime.of(10, 0)),
LocalDateTime.of(date, LocalTime.of(11, 0)))); return slots; } @Data
@AllArgsConstructor public class TimeSlot { private LocalDateTime
startTime; private LocalDateTime endTime; }

✅ What’s Next?
At this point you have:
A calendar with clickable days
A dialog that shows availability
Users can select a time slot and book
You might now want to:
1. Add user authentication (JWT + Angular AuthGuard)
2. Let providers manage availability
3. Implement conflict checking on booking
Which one would you like help with next?

all possibilities will be fine

Great! Since you're open to all possibilities, here's a roadmap with three enhancements
you can choose to dive into next:

🚀 1. User Authentication & Authorization


Why?
To identify who’s booking and who’s managing services
Protect endpoints so only users can book and only providers can manage slots
Backend
Integrate Spring Security + JWT
Expose /register , /login endpoints
Secure APIs for bookings and provider-only actions
Frontend
Add login/register pages
Store JWT in local storage
Use HTTP interceptor to add Authorization header
Use route guards to control access

🗓️ 2. Provider Availability Management


Why?
To allow providers to:
Define days and times they’re available
Add or remove time slots
Control when users can book
Backend
Create AvailabilitySlot entity (start + end + provider + service)
CRUD endpoints ( /providers/{id}/availability )
Logic to only return unused slots in availability API
Frontend
Build UI for providers using a calendar or time picker
Let them add/remove slots
List available slots and booked slots

⛔ 3. Conflict Checking & Validation


Why?
To ensure users can’t double-book the same slot
Backend
In BookingController#createBooking , check repository for existing bookings that
overlap
Return 409 Conflict if there's a clash
Frontend
Handle error responses and show a message like “This slot is no longer available—
please choose another.”
Optionally refresh availability before mimicking the booking

✅ Next Step: Let me Know Which You Prefer


Just pick one or let me know if you’d like all three implemented! I can provide detailed
code snippets:
1. 🔐 Authentication (Spring Security & JWT + Angular guard)
2. 🛠 Provider availability management (entities, endpoints, UI)
3. ⚖️ Booking conflict validation (backend check + frontend handling)
Or I can walk through them sequentially. What would you like to start with?

walk through
Excellent! Let's walk through all three improvements step by step, in a structured order
so you can build a robust booking app. Here's the plan:

✅ Step 1:Authentication with Spring


Security + JWT + Angular
🔒 Backend – Spring Boot Security + JWT
1.1 Add Dependencies (Maven)
xml Copy Edit
<dependency> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> </dependency>
<dependency> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>

1.2 Create User Entity


java Copy Edit
@Entity public class User { @Id @GeneratedValue private Long id;
private String username; private String password; private String role;
// "USER" or "PROVIDER" // Getters and setters }

1.3 Implement JWT Util & Filter


Create classes:
JwtUtil : Token creation & validation

JwtFilter : Intercepts requests to extract user

1.4 Authentication Controller


java Copy Edit
@RestController @RequestMapping("/auth") public class AuthController {
@Autowired private UserRepository userRepo; @Autowired private JwtUtil
jwtUtil; @PostMapping("/login") public ResponseEntity<?>
login(@RequestBody AuthRequest request) { User user =
userRepo.findByUsername(request.getUsername()); if (user != null &&
user.getPassword().equals(request.getPassword())) { String token =
jwtUtil.generateToken(user.getUsername()); return ResponseEntity.ok(new
AuthResponse(token)); } return
ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } }
🔐 Frontend – Angular Auth Flow
1.5 Create Login Form
ts Copy Edit
// login.component.ts login() { this.http.post('/auth/login', {
username, password }).subscribe((res: any) => {
localStorage.setItem('token', res.token);
this.router.navigate(['/calendar']); }); }

1.6 Add AuthInterceptor


ts Copy Edit
@Injectable() export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) { const token =
localStorage.getItem('token'); if (token) { req = req.clone({
setHeaders: { Authorization: `Bearer ${token}` } }); } return
next.handle(req); } }

1.7 Add Route Guards


ts Copy Edit
@Injectable({ providedIn: 'root' }) export class AuthGuard implements
CanActivate { canActivate() { return !!localStorage.getItem('token'); }
}

Now only logged-in users can access protected routes like /calendar .

✅ Step 2:Provider Availability


Management
🧱 2.1 Add AvailabilitySlot Entity
java Copy Edit
@Entity public class AvailabilitySlot { @Id @GeneratedValue private
Long id; private LocalDateTime startTime; private LocalDateTime endTime;
@ManyToOne private Service service; }

2.2 Provider API to Add/Remove Slots


java Copy Edit
@RestController @RequestMapping("/api/providers") public class
ProviderController { @Autowired private AvailabilitySlotRepository repo;
@PostMapping("/{id}/slots") public AvailabilitySlot
addSlot(@PathVariable Long id, @RequestBody AvailabilitySlot slot) {
return repo.save(slot); } @DeleteMapping("/slots/{slotId}") public void
deleteSlot(@PathVariable Long slotId) { repo.deleteById(slotId); } }

🧑‍💼 Angular UI (Provider Panel)


Let the provider:
Pick a date and time using Angular Material Date + Time Pickers
Click "Add Slot" (calls POST /providers/{id}/slots )
Show all slots in a list with "Remove" option

✅ Step 3:Conflict Checking on


Booking
💥 Backend – Check Overlap Before Booking
Update BookingController :
java Copy Edit
@PostMapping public ResponseEntity<?> createBooking(@RequestBody
Booking booking) { boolean conflict =
bookingRepo.existsByServiceIdAndStartTimeLessThanEqualAndEndTimeGreaterTha
booking.getService().getId(), booking.getEndTime(),
booking.getStartTime()); if (conflict) { return
ResponseEntity.status(HttpStatus.CONFLICT).body("Time slot is already
booked"); } return ResponseEntity.ok(bookingRepo.save(booking)); }

Add this method to BookingRepository :


java Copy Edit
boolean
existsByServiceIdAndStartTimeLessThanEqualAndEndTimeGreaterThanEqual(
Long serviceId, LocalDateTime end, LocalDateTime start);

🔁 Frontend – Handle Conflict Response


Update booking dialog:
ts Copy Edit
this.http.post('/api/bookings', booking).subscribe({ next: () =>
this.dialogRef.close(true), error: err => { if (err.status === 409) {
alert('That time slot is already taken!'); } } });

✅ Conclusion: You Now Have


🔐 Secure login with JWT & role-based access
📆 Calendar view with booking ability
🧑‍💼 Provider UI to define availability
⚖️ Conflict prevention and error handling

Would you like this bundled into a GitHub-ready starter project? Or should we focus on
UI polishing next (service filters, user profiles, etc.)?

ui next

Awesome! Let’s focus on polishing the UI/UX now to make the booking experience
smooth and professional.

🎨 UI/UX Improvements & Features for


Your Booking Calendar
1. Service & Provider Selection Filter
Why:
Users need to select a service and provider before seeing available slots.
How:
Add a dropdown/select for services (fetch from backend /api/services )
When service is selected, optionally filter providers for that service
Update calendar and availability fetches accordingly
2. Better Calendar Views & Event Styling
Ideas:
Use month, week, and day views (FullCalendar supports these)
Different colors for:
Booked slots
Available slots
User’s own bookings
Tooltips on events for extra info (service name, provider, booking status)

3. Booking Confirmation Flow


Enhancements:
After selecting a slot, show a summary modal before final booking
Include cancel/confirm buttons
Optionally add fields like phone, notes

4. Responsive & Mobile Friendly


Tips:
Use Angular Material’s grid and flex layout for responsiveness
Make calendar touch-friendly for mobile users
Condense views on small screens (e.g., list view instead of full calendar)

5. Provider Dashboard (Optional)


Features:
View all bookings for their services
Manage availability with drag-and-drop on calendar
Export bookings as CSV or sync with external calendars

🎯 Quick Implementation Snippets


1. Service Dropdown in Angular
html Copy Edit
<mat-form-field> <mat-label>Choose Service</mat-label> <mat-select
[(value)]="selectedService" (selectionChange)="onServiceChange()"> <mat-
option *ngFor="let service of services" [value]="service.id">
{{service.name}} </mat-option> </mat-select> </mat-form-field>

ts Copy Edit
services = []; selectedService: number | null = null; ngOnInit() {
this.http.get('/api/services').subscribe((data: any[]) => this.services
= data); } onServiceChange() { // Reload calendar events and
availability based on selectedService }

2. FullCalendar Multiple Views


ts Copy Edit
calendarOptions: CalendarOptions = { plugins: [dayGridPlugin,
timeGridPlugin, interactionPlugin], initialView: 'dayGridMonth',
headerToolbar: { left: 'prev,next today', center: 'title', right:
'dayGridMonth,timeGridWeek,timeGridDay' }, // other options };

Install missing plugins:


bash Copy Edit
npm install @fullcalendar/timegrid @fullcalendar/interaction

3. Event Colors & Tooltips


ts Copy Edit
events: bookings.map(b => ({ title: b.service.name, start: b.startTime,
end: b.endTime, color: b.user.id === currentUserId ? 'green' : 'blue',
extendedProps: { provider: b.service.provider.name, status: b.status }
})), eventDidMount: function(info) { const tooltip = new
Tooltip(info.el, { title: `Provider:
${info.event.extendedProps.provider}\nStatus:
${info.event.extendedProps.status}`, placement: 'top', trigger: 'hover',
container: 'body' }); }

Add tooltip dependency:


bash Copy Edit
npm install tooltip.js
🙌 Ready to help with any of these?
Want me to provide:
Full Angular UI component examples for filters and dialogs?
Provider dashboard UI?
Responsive/mobile-specific UI tips and code?
Just say the word!

You might also like