Create a Ticket Sales Web App with .NET Core 2 and Angular from scratch

So, I wanted to get more practice in building web e-commerce apps, specifically using .NET Core REST API for the back-end, so I can easily plug in whatever front-end framework I want to use, in this case, I chose Angular 6 single page app (SPA). After all, the name of the game is money, money, and mo' money! So, let's get started so we can see the stacks of cash start piling up! :) 

1. Prep

  • Make sure Node.js is install on your machine.  You can check if it is by going to a command prompt or PowerShell and type:
node --version

If it is not installed, you can go here to get the latest version, https://nodejs.org/en/download/

  • Make sure the DotNetCLI (command-line interface) is installed. Again, you can tell if it is installed by going to a command-line prompt and type:
dotnet --version

If it is not installed, you can go here to the latest version to download the .NET Core SDK, https://dotnet.microsoft.com/download

2. Create a New App using the Angular project template with ASP.NET Core

  • Create a new project from the command prompt in an empty directory by typing the following:
dotnet new angular -o TicketSalesWebApp
cd TicketSalesWebApp

NOTE - Make sure your environment variable is set to Development, go to a command prompt and type the following:

SET ASPNETCORE_Environment=Development
  • Then, build and run your application to make sure everything was set up correctly:

dotnet build

This command restores npm dependencies and the first time, can several minutes. The next builds will be much faster. Then you want to start up the Angular CLI server and run the application by typing the following (make sure you are inside the Project folder when you run the command)

dotnet run

You'll get a message that the server is listening on http://localhost:<port>

  • Navigate to that url and port in your browser, you should see something similar to the following:

 3. Create a Stripe Account

So, now that we have our Angular CLI application up and running, we need a way to accept payments on the web. You can create a free developer account on Stripe here, https://stripe.com/

Once you are registered, they will ask you to verify your email. Go ahead and do that, then go back to your Stripe dashboard. Make sure the "Viewing Test Data" toggle is on. 

Then, click Developers > API Keys and copy the Publishable key to use in your Angular app.

 Make sure that the publishable key starts with pk_test. If it doesn't, you're using the production key, and you don't want to use that yet.

Add Stripe to the Angular Web App

In the ClientApp > 

Create the Stripe Ticket Registration Page

In the Powershell command prompt, go to the src/app directory, then type in the command:

ng generate component registration --module app

NOTE - If you get an error "The file C:\Users\HambleyK\AppData\Roaming\npm\ng.ps1 is not digitally signed. You cannot run this script on the current system." Then, type the following at the command line prompt:

Set-ExecutionPolicy Unrestricted

Add HTML markup and CSS styling to the registration.component.html and .css files. This is what my HTML page looks like:

src > app > registration > registration.component.html

<h1>Register for SuperDuperConf</h1>
<div class="ticket conf-only">
  <span class="title">Conference Only Pass</span>
  <span class="price">$295</span>
  <button (click)="selectTicket('Conference Only', 295)">Register Now!</button>
</div>
<div class="ticket full">
  <span class="title">Full Conference + Workshop Pass</span>
  <span class="price">$395</span>
  <span class="value">Best Value!</span>
  <button (click)="selectTicket('Full Conference + Workshop', 395)">Register Now!</button>
</div>
<div class="ticket work-only">
  <span class="title">Workshop Only Pass</span>
  <span class="price">$195</span>
  <button (click)="selectTicket('Workshop Only', 195)">Register Now!</button>
</div>
<div class="alert alert-success" *ngIf="model.successMessage">{{successMessage}}</div>
<div class="alert alert-danger" *ngIf="model.errorMessage">{{errorMessage}}</div>
<div *ngIf="model.ticket.price">
  <form (submit)="purchaseTicket()" class="needs-validation" novalidate #regForm="ngForm">
    <div class="form-group">
      <label for="firstName">First Name:</label>
      <input type="text" class="form-control" name="firstName" id="firstName" [(ngModel)]="model.firstName" required #firstName="ngModel">
      <div [hidden]="firstName.valid || firstName.pristine" class="text-danger">First Name is required.</div>
    </div>
    <div class="form-group">
      <label for="lastName">Last Name:</label>
      <input type="text" class="form-control" name="lastName" id="lastName" [(ngModel)]="model.lastName" required #lastName="ngModel">
      <div [hidden]="lastName.valid || lastName.pristine" class="text-danger">Last Name is required.</div>
    </div>
    <div class="form-group">
      <label for="email">Email Address:</label>
      <input type="text" class="form-control" name="email" id="email" [(ngModel)]="model.emailAddress" required #email="ngModel">
      <div [hidden]="email.valid || email.pristine" class="text-danger">Email Address is required.</div>
    </div>
    <div class="form-group">
      <label for="password">Password:</label>
      <input type="password" class="form-control" name="password" id="password" [(ngModel)]="model.password" required #password="ngModel">
      <div [hidden]="password.valid || password.pristine" class="text-danger">Password is required.</div>
    </div>
    <div class="form-group">
      <label for="cardNumber">Card Number:</label>
      <input type="text" class="form-control" name="cardNumber" id="cardNumber" [(ngModel)]="model.card.number" required>
    </div>
    <div class="form-group form-inline">
      <label for="expiry">Expiry:</label>
      <br/>
      <input type="text" class="form-control mb-1 mr-sm-1" name="expiryMonth" id="expiryMonth" [(ngModel)]="model.card.exp_month"
        required> /
      <input type="text" class="form-control" name="expiryYear" id="expiryYear" [(ngModel)]="model.card.exp_year" required>
    </div>
    <div class="form-group">
      <label for="cvc">Security Code:</label>
      <input type="text" class="form-control" name="cvc" id="cvc" [(ngModel)]="model.card.cvc" required>
    </div>
    <button type="submit" class="btn btn-success" [disabled]="!regForm.form.valid">Pay ${{model.ticket.price / 100}}</button>
  </form>
</div>

And the registration.component.css page:

.ticket {
  text-align: center;
  display: inline-block;
  width: 31%;
  border-radius: 1rem;
  color: #fff;
  padding: 1rem;
  margin: 1rem;
}
.ticket.conf-only,
.ticket.work-only {
  background-color: #333;
}
.ticket.full {
  background-color: #060;
}
.ticket span {
  display: block;
}
.ticket .title {
  font-size: 2rem;
}
.ticket .price {
  font-size: 2.5rem;
}
.ticket .value {
  font-style: italic;
}
.ticket button {
  border-radius: 0.5rem;
  text-align: center;
  font-weight: bold;
  color: #333;
  margin: 1rem;
}

Now for the actual TypeScript component. You need:

  • a model to store the user-entered values
  • a ticket selection element - a user selects a ticket to purchase
  • a ticket payment element - a user pays for the ticket selected

 

 

 

 

 

 

Add comment

Loading