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
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
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>
A series of prompts will appear as a result of the command. Here are the defaults we recommend:
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
Nuxt.js will start a hot-reloading development environment accessible by default at http://localhost:3000.
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",
},
],
},
//...
};
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
}
]
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>
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>
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>
In the code snippet above,
- We import data from a JSON file named
courses.json
. - The
data()
function returns an object with the key ofcourses
and its value set to the importedcoursesData
variable.
We should have something similar to what is shown below.
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">×</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>
//...
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 thecourse
object to display the modal using theopenCourseModal
method - The
selectedCourse
becomesnull
when the close modal icon is clicked, which triggers thecloseCourseModal
method
Testing the application, we should have something similar to what is shown below.
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.
Top comments (0)