Owner Management Portal

  • Angular
  • SCSS
  • JSP
  • Java

An Angular 11 application living inside a legacy Java application to guide users through common functions of the Owner Account Management portal.

  • Designer Angela Shockey
  • Lead Angular Developer Josh Delgado
  • Angular Developers Rebecca Terry,
    Shianne Dyges
  • Java Developers Khondaker Sadman,
    Francisco Felix
  • Client Westgate Resorts
Owner Account Management Dashboard

The Problem(s)

This was one of the older projects in the company's codebase which means there was A LOT of undocumneted and spaghetti code. Few developers wanted to work on the project since it was difficult to find the code you needed to address and when you did, it would often change something else in addition.

The demographic for this application skews older and less tech-savvy so support calls and messages were aggressively high.

This is a the first part of a multi-phase transition to an entirely angular application. The phase one purpose was to create a guided flow that would direct the user to the existing page to complete their goal. Since this was an addition to the site instead of a conversion, it allowed our team to discover pitfalls in our design through live user testing.

The Project

The Process

The Angular application lives within the existing Java/JSP website. Angular preloads the base module and remains hidden until the user clicks the "Show Guided Flow" bar that exists throughout the website.

  • HTML
  • Typescript
  • Base Typescript
  • Design
<app-guided-flow-heading [heading]="'guidedFlow.step.init.title' | messageBundle"
	[welcome]="'guidedFlow.header.welcome' | messageBundle: userName"></app-guided-flow-heading>
<div class="init-step">
<app-guided-flow-card class="init-step__card-socket"
	[card]="card"
	[highlightCard]="first"
	*ngFor="let card of response.cards; let first=first;"></app-guided-flow-card>
</div>
<app-guided-flow-footer [additionalOptions]="response.additionalOptions"></app-guided-flow-footer>
<app-flow-actions [isFirstStep]="true"></app-flow-actions>
					
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from "@angular/router";
import {BaseStep} from '../../../../common/components/steps/base-step/base-step';
import {GuidedFlowStoreService} from "../../../../common/services/guided-flow-store.service";

@Component({
	selector: 'app-init-step',
	templateUrl: './init-step.component.html',
	styleUrls: ['./init-step.component.scss'],
})
export class InitStepComponent extends BaseStep implements OnInit {

	userName: string;

	constructor(protected activatedRoute: ActivatedRoute,
				protected guidedFlowStoreService: GuidedFlowStoreService) {
		super(activatedRoute, guidedFlowStoreService);
	}

	ngOnInit(): void {
		super.initStep();
		this.activatedRoute.data.subscribe((data) => {
			this.userName = data.greeting;
		});
	}
}
					
import {ActivatedRoute} from "@angular/router";
import {GuidedFlowStep} from "../../../domain/guided-flow-step";
import {Directive} from '@angular/core';
import {GuidedFlowStoreService} from "../../../services/guided-flow-store.service";

@Directive()
export class BaseStep {

	response: GuidedFlowStep;

	loading: boolean = false;

	constructor(protected activatedRoute: ActivatedRoute,
				protected guidedFlowStoreService: GuidedFlowStoreService) {
	}

	initStep(): void {
		this.activatedRoute.data.subscribe((data) => {
			this.response = data.response;
		});
		this.guidedFlowStoreService.setPageTitle(undefined);
	}
}
					
Buttons

It has a data-driven, card-based design reduces the number of front-end components that need to be written.

The project is split into multiple modules to reduce bandwidth and speed up page load times.

Owner Account Management File Structure

The user base is 90% desktop users (the demographic skews older) but the development is still mobile focused.

We utilize Angular Material Forms and Icons to do some of the heavy lifting and reduce our development time. Who wants to reinvent the wheel?

Angular Library Icons
  • Typescript
  • Java
@Injectable({
	providedIn: 'root'
})
export class GuidedFlowHttpService {

	readonly baseUrl: string = 'service/guided-flow/';
	readonly profileUrl: string = 'service/profile/';

	constructor(private httpService: HttpService) {
	}

	getGreeting(): Promise<any> {
		return this.httpService.get<any>(this.baseUrl + 'greeting/', {responseType: 'text'});
	}

	getInitialGuidedFlow(cardLimit: number): Promise<GuidedFlowStep> {
		return this.httpService.get<GuidedFlowStep>(this.baseUrl + 'initial/', {params: {cardLimit: cardLimit}}, GuidedFlowStep);
	}
}
			
@RestController
@RequestMapping("/service/guided-flow")
public class GuidedFlowServiceController {

	@Autowired
	@Qualifier("westgateGuidedFlowService")
	private WestgateGuidedFlowService westgateGuidedFlowService;

	@Autowired
	@Qualifier("reservationsWestgateGuidedFlowService")
	private ReservationsWestgateGuidedFlowService reservationsWestgateGuidedFlowService;

	@Autowired
	private CompanySettings companySettings;

	@GetMapping("/initial")
	public WGRGuidedFlowStep getInitialGuidedFlow(@RequestParam("cardLimit") int cardLimit) {
		if (UserUtil.isVacpacUser()) {
			return reservationsWestgateGuidedFlowService.getInitialGuidedFlowStep(UserUtil.getVacpacUserDetails());
		} else {
			return westgateGuidedFlowService.getInitialGuidedFlowStep(UserUtil.getWestgateUserDetails(), cardLimit);
		}
	}
}
				

We create Angular analogs for services, objects, etc that exist on the Java side. This helps our front-end and back-end devs communicate and eliminates many common misunderstandings.

Conclusion

This project pushed us to bring our common angular library to the next level with further abstractions and increased organization. It was a pain at first to stop development to work on the library but the time has already been made up for.

Early user testing has been received well. The common use-cases are much easier for our applications demographic to navigate through.

Going forward, more documentation for the project is needed. As it's an in-progress application, certain patterns are still up for debate so we haven't written extensive documentation for it. If you'd like to see examples of my documentation style you can do so here.

And lastly, If you happen to have a Westgate account, check it out!

Get In Touch

I'm not actively looking for new oppourtunities but I'm not a hermit. Reach out with questions, comments, or even just to say hey.

Say What's Up