NSWI153: Advanced Web Applications

JavaScript : User Interface

Preliminaries

Please read this section at least one day prior to the seminar. This section outlines what you are expected to know, be able to do, or prepare in advance. Following these instructions will help you get the most out of the seminar and ensure smooth participation.

Remote

This is a remote practical. There is no on-site activity. Instead, you are expected to solve the assignments in the time and place of your choosing. Unless stated otherwise, you are expected to work alone. You are not allowed to share your solution with your colleagues. Each assignment has a specific deadline and submission conditions.

Preliminaries : Knowledge, Skills, and Competence


Before the start of the practical, you should be able to:

  • Create a JavaScript project using Vite.
  • Basic knowledge of JavaScript frameworks.

In this practical you will continue with the code from the "PHP : Doctrine" practical.

Rules of this practical

You are not allowed to collaborate with your colleagues.

Unlike in the "PHP : Doctrine" practical, avoid over-reliance on AI tools for core code. The project you are about to create is not complicated, but it is intended to give you hands-on experience with frontend development tools. Using AI to shortcut the implementation may reduce that learning opportunity.

You are required to finish all exercises, commit and push your solution, and deploy both backend and frontend before 2026-04-11 23:59 (UTC+1). Make sure to include the deployed URLs in your repository README.

This practical is designed as a series of exercises that build on each other. You are expected to solve the exercises in the given order and carry your source code forward. It is a good idea to commit after each exercise.

Exercise: Vite project

We utilize Vite as a simple way to develop a JavaScript client-side application.

Create Vite project

GitLab: ./practical-06/


Your first objective is to create a Vite project with a rendering library of your choice. If you are not sure any of the following list are good picks:

If you are not sure just pick React; it is a reasonable default.

You are free to choose whether you want to use TypeScript or not.

Continue to the next slide once you are done >>>

Your first application

At this point you may try to build a simple +/- counter application just to get known the framework. Try to use multiple components, share state, ... Once you feel comfortable, remove all the code you created for this slide and continue with the next exercise.

Continue to the next slide once you are done >>>

Exercise: Utilize a UI component library

We could write CSS from scratch, or use solutions like Tailwind CSS. Instead, to speed up development and get a consistent design, we recommend using an existing component library.

Find and use a UI component library

Find and use any UI component library compatible with your selected framework. Add layout to the application, and make it is reponsive. Below are libraries you may consider. Keep in mind that libraries are often framework specific.

Continue to the next slide once you are done >>>

Header

Add a header on top of your application. The header must contain logo and links to all pages (routes) we add later.

Continue to the next slide once you are done >>>

Exercise: API integration

We need a backend for you application. We utilize the one created in PHP : Doctrine. Keep in mind you can use Vite to proxy from local to remote machine.

Making HTTP request

Continue with the code from the previous exercise.

You will need to execute HTTP requests like GET, POST, DELETE, ... You can do this using the Fetch API. Alternatively, you can use libraries to make this easier. Framework-neutral libraries to consider: Axios, and state/query helpers such as react-query.

Warning: There is an active supply chain attack on axios as of 2026-03-31. Be careful and always check your dependencies before installing. Alternatively, do not use latest versions.

Knowing a library may overall help your with developer velocity. At the same time, learning a library is a time investment. If you are not sure, or feeling already overwhelmed by all the libraries .. just stick to the fetch API.

Continue to the next slide once you are done >>>

Model and request

TypeScript-only: create interfaces for your Data Transfer Objects.

Implement a layer for communicating with the PHP : Doctrine backend. You need to be able to handle following API calls.

  • GET api/v1/books
  • GET api/v1/books/{id}
  • POST api/v1/books
  • DELETE api/v1/books/{id}
  • GET api/v1/users
  • GET api/v1/users/{id}
  • POST api/v1/users
  • DELETE api/v1/users/{id}
  • GET api/v1/users/{id}/borrowed-books
  • GET api/v1/libraries
  • GET api/v1/libraries/{id}
  • POST api/v1/libraries
  • DELETE api/v1/libraries/{id}
  • GET api/v1/libraries/{id}/books
  • POST api/v1/libraries/{id}/books
  • POST api/v1/borrowings
  • PATCH api/v1/borrowings/{id}/return

Continue to the next slide once you are done >>>

Configuration

Update your code and configuration so the user can provide a base URL for all API calls. The base URL is set using BACKEND_BASE_URL environment variable or using .env file.

For example, if BACKEND_BASE_URL=./ then to get all books you need to make a request to ./api/v1/books.

The configuration can be applied in npm run dev mode or in npm run build. Once the application is deployed there will be no .env file, so make sure any production URL is baked into the deployed build or provided via runtime configuration.

Continue to the next slide once you are done >>>

Exercise: Functionality

The time has come to implement the functionality. The following slides contain description of the basic functionality you are required to implement.

Authentication and authorization

You are not expected to implement any secure authentication mechanism. Similar to the winter semester, use an e-mail to identify a user for UI purposes. Use can use cookies or local-state to store user identification.

Details on authorization are explained alongside the functional requirements below.

Functionality 1 / 2

  • F01) A user can list all libraries.
    - All users can list an see all libraries.
  • F02) A user can create a new library.
    - Any user can create a new library, by doing so they become the owner.
  • F03) A user can create a new book in a library.
    - Only a library owner can create a book.
  • F04) A user can edit an existing book.
    - Only a library owner can edit the book.
  • F05) A user can delete an existing book.
    - Only a library owner can delete the book.
  • F06) A user can list all books in a library.
    For each book the user can see whether the book is borrowed or not.
    - All users can list all books in any library.

Continue to the next slide once you are done >>>

Functionality 2 / 2

  • F07) A user can borrow a book from a library.
    - Any user can borrow any book.
  • F08) A user can return a borrowed book.
    - Only the user who borrowed the book can return it.
  • F09) A user can list all theirs borrowed and non-returned books.
    - Every user can see only the books their have borrowed.

Continue to the next slide once you are done >>>

Single-Page-Application

The objective is to split the functionality into multiple pages. Your application remains a single-page-application (SPA), you just simulate the navigation. To do this you can use a library such as React Router.

Your application needs to support the following routes:

  • {base} - Landing page, no restriction on content.
  • {base}/login - Login page.
  • {base}/logout - Logout page.
  • {base}/libraries - List of all libraries.
  • {base}/libraries/{library} - List of all books in a library.
  • {base}/borrowed - List borrowed books for the user.

Continue to the next slide once you are done >>>

Exercise: Deployment

In this step you deploy whole application, backend and frontned, to the webik.

Deploy backend

Deploy PHP application from PHP : Doctrine at https://webik.ms.mff.cuni.cz/~{your-user-name-at-webik}/nswi153/practical-06/backend.

Deploy frontend

Deploy application created in this practical at https://webik.ms.mff.cuni.cz/~{your-user-name-at-webik}/nswi153/practical-06/frontend. Use the previously deployed PHP application as a backend.

Questions, ideas, or any other feedback?

Please feel free to use the anonymous feedback form.