Skip to content

POD - Placement Online Diary - Repo for my dissertation project

Notifications You must be signed in to change notification settings

angus-websites/pod

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

POD

POD (placement online diary) is an application to allow students to keep track of their placement year.

Overview

POD is a website that makes life easier for students on their year in industry, it does this by allowing users to to keep a detailed record of what happens during their YII, they can then refer back to this information when creating CV's and end of year reports etc

Entries

The way in which users recount information into the website is through the use of 'entries', the user can create as many entries as they like and each entry can be formed from a single 'template'

Templates

When creating an entry, a user selects a certain template to use. This template contains a pre-defined set of inputs for the user to fill in, some examples of templates are...

  • General: For creating a general diary entry
  • Training: For when the user has completed some training
  • New skill: For when the user learns a new skill

say the user selects the "New skill" template, they would be presented with inputs to fill in related to learning a new skill, these would include...

  • The name of the skill they learned (text input)
  • The date they learned that skill (date input)
  • Details on what they learned or how they learned the skill (text-area input)

Template schema

When developing a new template a few criteria must be met in order for it to work correctly with the application, Templates are stored in MongoDB to allow them to have flexible schemas.

Format

Templates are stored as JSON, for example, the "General" template is defined as follows...

{
  "_id": {
    "$oid": "63fb3b3a0a0c8ed50908f892"
  },
  "name": "General",
  "description": "A normal diary entry",
  "icon": "general.svg",
  "fields": [
    {
      "id": "title",
      "label": "Entry title",
      "type": "text",
      "required": true,
      "validation": [
        "required",
        "max:100"
      ]
    },
    {
      "id": "date",
      "label": "Date",
      "type": "date",
      "required": true,
      "validation": [
        "required",
        "date"
      ]
    },
    {
      "id": "content",
      "label": "Entry content",
      "type": "textarea",
      "required": true,
      "validation": [
        "required",
        "max:3000"
      ]
    }
  ],
  "updated_at": {
    "$date": {
      "$numberLong": "1677409082055"
    }
  },
  "created_at": {
    "$date": {
      "$numberLong": "1677409082055"
    }
  }
}

Essential attributes

Templates contain the following top level attributes...

Key Description Type Required?
_id A unique identifier for this template, this should be automatically generated by MongoDB Int yes
name A string representing the name of the template String yes
icon The filename of the icon for this template (this needs to be stored in the applications /assets/images/templates folder) String no
description A string representing the description of the template String yes
fields An array of the fields this template contains Array yes

Fields

Fields is an array of the inputs this template will provide for the user. This array MUST have a field with an id of title

{
  "fields": [
    ...
    {
      "id": "title",
      "label": "Entry title",
      "type": "text",
      "required": true,
      "validation": [
        "required",
        "max:100"
      ]
    }
  ]
}

and each field consists of the following options

Key Description Type Options Required?
id A unique identifier for this field String yes
label What the user sees on the screen when filling in this input String yes
type What type of input this is, these must be implemented in the application, currently there are a few built in String text, date, textarea yes
required Is this input required? (used for front end validation) Boolean true, false no
validation An array of validation rules used to validate this input on the back-end Array A list of Laravel validaion rules can be found here yes

Features

An important part of the project is measuring the most effective gamification techniques in online diary applications, these gamification techniques are implemented as features in the application.

Some examples of features include...

  • A leader-board to view the status of other students
  • A streak of the number of consecutive entries made by the user

These features can then be grouped together to create a series of gamification features for different users.

Feature groups

As mentioned above, these features can be grouped together, these are known as feature-groups a feature group contains a number of users and a number of features.

Users are then randomly assigned into a feature group when they sign up for the site.

Feedback

User feedback is integrated into the application, feedback is a feature in itself so can be toggled using the active column in the features table

Accessing feedback forms

Users can fill in feedback by navigating to the feedback page where they will be presented with a form of entirely optional questions to answer, only the questions the user answers will be saved to the database.

Dynamic feedback

The reason for integrating feedback into the application was to allow a dynamic feedback form to be displayed to the users. Depending on the features the user has access to, different forms will be presented to them, allowing for a much more tailored feedback experience for the users.

Customising feedback questions

The questions for feedback are stored in database/seeders/core/FeedbackSeeder.php

In order to create a question, it must have an associated FeedbackGroup which is the group of questions it belongs to on the form, think of this as a section of a form, i.e "General questions"

Feedback Groups

$general = FeedbackGroup::create([
    "name" => "General",
    "caption" => "Some general questions about the app",
    "position" => 0,
]);

Here is an example of seeding a feedback group, all three fields are required and are explained below...

Field Description
name The name of this group, this will be displayed on screen
caption A small piece of text to explain the types of questions in this group,this will be displayed on scren
position The position of this group on the screen (starting from 0 at the top)

Feedback Questions

FeedbackQuestion::create([
    "name" => "How would you rate this application?",
    "feedback_group_id" => $general->id,
    "question_type" => "radio",
    "data" => [
        "options" => [
            ["label" => "Fantastic", "id" => "fantastic"],
            ["label" => "Good", "id" => "good"],
            ["label" => "Ok", "id" => "ok"],
            ["label" => "Poor", "id" => "poor"],
        ]
    ]
]);

This example illustrates creating a new feedback question for the user that asks them to review the application from a series of radio buttons.

We can also target certain features when creating feedback questions using the following syntax...

FeedbackQuestion::create([
    "name" => "Did you enjoy using the leaderboard feature?",
    "feedback_group_id" => $featureGroup->id,
    "question_type" => "radio",
    "targeted" => true, // Note the targeted attribute set to true
    "data" => [
        "options" => [
            ["label" => "Yes", "id" => "yes"],
            ["label" => "No", "id" => "no"],
        ],
        "feature_id" => Feature::where("name", "=", "leaderboard")->firstOrFail()->id
    ]
]);

Below explains all the available attributes for a feedback question...

Field Description
name The name of this question to be displayed on screen
feedback_group_id The id of the feedback group this question belongs to
question_type The type of question this is, currently the available options are text, radio
targeted (optional) Does this question target a specific feature? true or can be missed
data An array of additional attributes that are needed for particular configurations (see below)

Certain data attributes are required for particular configrations...

  • if targeted is true then data.feature_id will need to contain a list of id's to target,
  • if targeted is true then you will need to specify an operator field which indicates how the array of data.feature_id should be handled...
    • An operator of all will mean that all user will need to match all the features specified in the array
    • An operator of any will mean the user can view the question if they have any feature in the array
    • If an operator is not specified the default will be all
  • if question_type is radio then a list of options will need to be present in data.options, each option needs a display label and a unique id.

Run Locally

Clone the project

git clone git@github.com:angus-websites/pod.git

Go to the project directory

cd pod

Setup Laravel Sail

NOTE: Ensure you have Docker installed

docker run --rm \
    -u "$(id -u):$(id -g)" \
    -v $(pwd):/var/www/html \
    -w /var/www/html \
    laravelsail/php81-composer:latest \
    composer install --ignore-platform-reqs

Generate a .env file

cp .env.example .env

Run Laravel Sail (Development server)

./vendor/bin/sail up

Open a new Terminal tab in the same project root folder

Generate an app encryption key

./vendor/bin/sail php artisan key:generate

Migrate the database

./vendor/bin/sail php artisan migrate

Database seeding

The project has two main seeding classes DevSeeder as well as the default DatabaseSeeder, DevSeeder will seed a bunch of example users and is meant for development purposes, to run this seeder run the following command...

./vendor/bin/sail php artisan db:seed --class=DevSeeder

DatabaseSeeder seeds only essential data and is meant for a production server.

Install npm dependencies

./vendor/bin/sail npm install

Run Vite

./vendor/bin/sail npm run dev

Visit Localhost

Tests

Tests are located in the tests directory and can be run from the command line...

./vendor/bin/sail php artisan test

Tips

When updating certain fields in the .env file when using Laravel Sail, you may need to restart the Docker container for changes to take affect.

Demo

A live version of POD is available here

Tech Stack

Client: Vue.js, InertiaJS, TailwindCSS

Server: PHP (Laravel framework)

Database: MYSQL, MongoDB

Authors