Designing a User-Friendly Course Catalog With Pink Design and Nuxt

Idris Olubisi💡 - May 8 '23 - - Dev Community

Creating a course catalogue that is both visually appealing and easy to use can be a challenge. However, with the combination of Pink Design and Nuxt.js, we can design an excellent and intuitive catalogue for users.

In this article, we'll learn how to build a course catalogue that allows users to search, filter through the available courses, and view course descriptions & prerequisites.

Sandbox

We completed this project in a Code Sandbox; fork and run it to get started quickly.

GitHub repository

GitHub logo Olanetsoft / Course-Catalog-With-Pink-Design-Nuxt.js

This is a project of an article to build a course catalogue that allows users to search and filter through available courses, view course descriptions and prerequisites.

Course-Catalog-With-Pink-Design-and-Nuxt

Build Setup

# install dependencies
$ yarn install

# serve with hot reload at localhost:3000
$ yarn dev

# build for production and launch server
$ yarn build
$ yarn start

# generate static project
$ yarn generate
Enter fullscreen mode Exit fullscreen mode

For detailed explanation on how things work, check out the documentation.

Special Directories

You can create the following extra directories, some of which have special behaviors. Only pages is required; you can delete them if you don't want to use their functionality.

assets

The assets directory contains your uncompiled assets such as Stylus or Sass files, images, or fonts.

More information about the usage of this directory in the documentation.

components

The components directory contains your Vue.js components. Components make up the different parts of your page and can be reused and imported into your pages, layouts and even other components.

More information about the usage of this directory…

Getting Started with Nuxt.js

Nuxt.js is the bedrock of our Vue.js project, providing structure and flexibility while allowing us to scale confidently.

It is extensible, offering a robust module ecosystem and hooks engine. Integrating our REST or GraphQL endpoints, favourite CMS, CSS frameworks, and other third-party applications is seamless.

Project Setup and Installation

To create a new project, we will use the command below to scaffold a new project:

    npx create-nuxt-app <project-name>
Enter fullscreen mode Exit fullscreen mode

A series of prompts will appear as a result of the command. Here are the defaults we recommend:

Designing a User-Friendly Course Catalog With Pink Design and Nuxt.js

The command above creates a new Nuxt.js project.

Next, we navigate to the project directory and start the development server using the command below.

    cd <project name> && yarn dev
Enter fullscreen mode Exit fullscreen mode

Nuxt.js will start a hot-reloading development environment accessible by default at http://localhost:3000.

Nuxt.js default page

Appwrite Pink Design Setup

To set up an Appwrite pink design in this project, we will configure our project using the Appwrite pink design CDN. Navigate to the nuxt.config.js in the root directory and add the following configuration.

    export default {
      // Global page headers: https://go.nuxtjs.dev/config-head
      head: {
         //...
        link: [
          { rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
          {
            rel: "stylesheet",
            href: "https://unpkg.com/@appwrite.io/pink",
          },
          {
            rel: "stylesheet",
            href: "https://unpkg.com/@appwrite.io/pink-icons",
          },
        ],
      },

     //...
    };
Enter fullscreen mode Exit fullscreen mode

Creating a Sample Course Catalogue JSON

In this step, we will create a sample course catalogue which we will utilize in our application as a database for our courses. In the project's root, create a new JSON file called courses.json and add the following course sample.

    [
      {
        "id": 1,
        "title": "Introduction to Web Development",
        "description": "Learn the basics of web development with HTML, CSS, and JavaScript.",
        "level": "Beginner",
        "prerequisites": [],
        "category": 1
      },
      {
        "id": 2,
        "title": "Advanced Web Development",
        "description": "Build complex web applications with React, Node.js, and MongoDB.",
        "level": "Intermediate",
        "prerequisites": ["Introduction to Web Development"],
        "category": 1
      },
      {
        "id": 3,
        "title": "Introduction to Mobile Development",
        "description": "Learn the basics of mobile development with React Native and Expo.",
        "level": "Beginner",
        "prerequisites": ["Introduction to Web Development"],
        "category": 2
      },
      {
        "id": 4,
        "title": "Data Analysis with Python",
        "description": "Learn how to analyze and visualize data using Python and Pandas.",
        "level": "Intermediate",
        "prerequisites": ["Introduction to Web Development"],
        "category": 3
      },
      {
        "id": 5,
        "title": "User Interface Design Fundamentals",
        "description": "Learn the basics of user interface design with Sketch.",
        "level": "Beginner",
        "prerequisites": [],
        "category": 4
      },
      {
        "id": 6,
        "title": "Cloud Computing with AWS",
        "description": "Learn how to deploy and scale web applications on Amazon Web Services.",
        "level": "Intermediate",
        "prerequisites": ["Introduction to Web Development"],
        "category": 5
      }
    ]
Enter fullscreen mode Exit fullscreen mode

In the sample data above, we have the identifier for each record id, a title, category, description, level, prerequisites, and category.

Designing the layout for the Course Catalogue

Let's design an aesthetically appealing design for the course catalogue in this section by updating the pages/index.vue with the following code snippet.

    <template>
      <div>
        <div class="container">
          <div class="sidebar">
            <!-- Sidebar content goes here -->
           </div>
          <div class="content">
             <!-- Search and Course list goes here -->
          </div>
        </div>
        <div class="course-modal" v-if="selectedCourse">
          <div class="modal-content">
            <!-- Modal goes here -->
          </div>
        </div>
      </div>
    </template>
Enter fullscreen mode Exit fullscreen mode

Let's add CSS by creating a new file called styles.css in the root directory and updating it with the following CSS snippet.

Import the style by updating the pages/index.vue with the following code snippet.

    <template>
      <!--  -->
    </template>

    <style>
    @import '@/styles.css';
    </style>
Enter fullscreen mode Exit fullscreen mode

Developing the Functionality to Retrieve All Courses

In the previous step, we successfully designed the application layout; now, we will implement the functionality to retrieve all courses from the JSON file we created earlier.

Inside the pages/index.vue file, update it with the following code snippet.

    <template>
      <div>
        <div class="container">
          <div class="sidebar">

          </div>
          <div class="content">
            <h1 class="course-catalogue-title">
              Course Catalog With Pink Design and Nuxt.js
            </h1>
             <!-- Search goes here -->
            <div class="courses">
              <div
                class="course-card"
                v-for="course in filteredCourses"
                :key="course.id"
              >
                <div class="card" @click="openCourseModal(course)">
                  <div class="card-content">
                    <h3 class="title">{{ course.title }}</h3>
                    <div class="description">{{ course.description }}</div>
                    <div class="details">
                      <div class="level">{{ course.level }}</div>
                    </div>
                  </div>

                </div>
              </div>
            </div>
          </div>
        </div>
        </div>
        <div class="course-modal" v-if="selectedCourse">
          <div class="modal-content">
           <!-- Modal goes here -->
          </div>
        </div>
      </div>
    </template>
    <!--  -->

    <!-- Importing data from a JSON file named courses.json -->
    <script>
    import coursesData from '../courses.json'

    export default {
      // Defining the data property of the component
      data() {
        // Returning an object with a key of 'courses' and its value set to the imported coursesData
        return {
          courses: coursesData,
        }
      },
    }
    </script>
Enter fullscreen mode Exit fullscreen mode

In the code snippet above,

  • We import data from a JSON file named courses.json.
  • The data() function returns an object with the key of courses and its value set to the imported coursesData variable.

We should have something similar to what is shown below.

Developing the functionality to retrieve all courses

Adding a Search and Filter by Category feature to the Course Catalog

In the sources, we have different categories. Let's implement the course filtering search functionality to filter based on the course category by updating the pages/index.vue file with the following code snippet.

In the code snippet above we:

  • Utilized the imported JSON file with course data
  • Defined a Vue.js component that uses the imported course data as its initial state
  • Created component's data properties, which include search searchQuery, categories, and the currently selected category
  • Defined a computed property that filters courses based on the search query and currently selected category
  • Returned the filtered courses in the component's computed property

We are almost there! We can retrieve all courses and search and filter courses but we can't view individual courses yet, let's implement that in the following step.

Implementing the Course View Functionality

To implement course view functionality, we will add a modal to view the course content whenever a user clicks on an individual course. Let's update the pages/index.vue file with the following code snippet.

    <template>
      <div>
        <div class="container">
          <!-- //... -->
        </div>
        <div class="course-modal" v-if="selectedCourse">
          <div class="modal-content">
            <span class="close-modal" @click="closeCourseModal">&times;</span>
            <h2 class="modal-title">{{ selectedCourse.title }}</h2>
            <div class="modal-description">{{ selectedCourse.description }}</div>
            <div class="details">
              <div class="modal-level">{{ selectedCourse.level }}</div>
            </div>
            <div class="modal-prerequisites">
              <h3>Prerequisites</h3>
              <ul v-if="selectedCourse.prerequisites.length">
                <li
                  v-for="prerequisite in selectedCourse.prerequisites"
                  :key="prerequisite"
                >
                  {{ prerequisite }}
                </li>
              </ul>
              <p v-else>None</p>
            </div>
          </div>
        </div>
      </div>
    </template>

    <script>
    // Import courses data from JSON file
    import coursesData from "../courses.json";
    export default {
      data() {
        return {
          //...
          selectedCourse: null,
        };
      },
      methods: {
        //...
        openCourseModal(course) {
          this.selectedCourse = course;
        },
        closeCourseModal() {
          this.selectedCourse = null;
        },
      },
      computed: {
        //...
      },
    };
    </script>

    //...
Enter fullscreen mode Exit fullscreen mode

In the code snippet above,

  • The course list container dynamically generates a course element for each course in the filtered course list using v-for
  • Each course element has an on-click event that triggers the @click="openCourseModal(course)" method
  • The selectedCourse variable is set to the course object to display the modal using the openCourseModal method
  • The selectedCourse becomes null when the close modal icon is clicked, which triggers the closeCourseModal method

Testing the application, we should have something similar to what is shown below.

Testing the application

Conclusion

This post demonstrated how to design a user-friendly course catalogue with pink design and Nuxt.js. Additionally, you learned how to search, filter through the available courses, and view course descriptions and prerequisites.

Resources

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .