DevSoc Training Program Exercises

by Dylan Huynh and Nicole Chun with contributions from the DevSoc community

Welcome to DevSoc's Training Program Exercises! This is a resource created by DevSoc volunteers for the Training Program to inspire and assist novice programmers gain basic web development skill in HTML/CSS, JavaScript and React.

This site features a selection of guides and exercises intended for 2024 DevSoc Trainees and were made to go along with concurrent workshops. However you are welcome to use this for our own self learning.

Disclaimer

While we try our best, we still may make mistakes here and there. If you spot any issues, mistakes or typos on this page fee free to create a pull request with the corrections or mention it in an issue.

Source Code

The source files from which this site is generated can be found on GitHub.

Getting Started

In this chapter we will begin by setting up the requirements for the rest of the program. There's a lot of learn so stay strapped! We will go through:

  • Setting up a coding environment on Windows and macOS
  • Installing Git, Node and NPM

Setting up a Coding Environment

To start learning and coding we of course need a proper work environment. This is highly customisable however this guide will only cover some basics and recommendations to get you going.

It is highly encouraged to set some time aside to configure your personal coding environment. This will not only improve your workflow but also allow you to customise everything from the aesthetics to shortcuts.

This will be split into two main parts for the most common operating systems: Windows and macOS. If you are using a Linux system this will not be too applicable, as you do not have to set up anything specific. However you are welcome to check out Customise the Command Line Prompt.

Please select the guide for your operating system and enjoy! Both of these guides will assume a start from scratch.

macOS Setup

Start by opening the terminal and typing the command:

git

This should prompt you to install the command line developer tools. This will install various tools to help you get started.

Homebrew

Next we will install Homebrew. Homebrew is a package manager for macOS which will freely allow you to install various tools and dependencies. It also provides for seamless removal of these tools.

First head to brew.sh and type the install command into your terminal. Here is a copy of it:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Once the installation is completed the installation script will prompt you to run two lines in the terminal. Please run these two lines to add Homebrew to your path. This is necessary for the brew command to work.

Terminal

You may have noticed that the current terminal you have been working on looks ugly. Let's fix that!

Download iTerm2 from the webpage or with brew install --cask iterm2

Now to upgrade the look of the terminal install Oh My Zsh which is a framework for managing your zsh configurations which comes bundled with helpful functions, plugins and themes.

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Once installed open your zsh config file usually located at ~/.zshrc. You should find a snippet with the variable ZSH_THEME:

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="random"

You are welcome to set this as random which will give you a random theme on every terminal. Then once you find one you like you can switch to just using that one. Alternatively you can download a theme like Powerlevel10k and customise that. The options are unlimited.

Now you can also adjust the settings of iTerm2. Open up the preferences and play around with the colours, transparency or any other settings. You can even install colour themes like my personal favourite Catppuccin.

While we are here there is a little secret within macOS for developers. When you create a folder the default icon is just a folder with a plain colour. For special folders there is icons for example, Documents, Downloads, etc... If you create a folder named Developer in your home this will also grant a special icon. You can then configure your terminal to always open in this directory and you can store all your code related projects here.

Visual Studio Code

The most popular used IDE for coding is Visual Studio Code. You have most ilkley encountered and used this before and here we will go through a local setup.

First install VSCode from the website.

Once you open the application the first thing to do is install the Code command to your path. This will allow you to open VSCode from your terminal. Type Cmd + Shift + P to open the command pallet and write Install Code. Now click on the Shell command and it should install.

Further Customisation

This should be enough to get you started developing! However there are an infinite amount of further customisations and other tools and applications you can install and include.

Windows Setup

Historically, Windows has not been the preferred OS for most web developers, but with the introduction of Windows Subsystem for Linux (WSL and WSL2), this allows us to install a linux distribution on Windows. This means we can run a real linux environment on our Windows system.

If you would prefer a local install see our Windows(Local) guide.

Installing WSL

The following steps will install Linux in your Windows environment. We will reference the official WSL Install Guide.

From the start menu, search for PowerShell and run it as an administrator by right-clicking nd selecting "Run as administrator". Now enter the following command to install wsl and then restart your machine.

wsl --install

This command will enable the features necessary to run WSL and install the Ubuntu distribution of Linux.

Ubuntu is the default linux distribution installed by WSL2. It is very beginner friendly to use and has a lot of documentation + support online. You can check out the documentation here!

Windows Terminal

Windows has an official Windows Terminal app. This will make it easy to work with the command line and allow you to quickly switch between using Linux and Powerful sessions.

It is recommended to set Ubuntu as your default profile as this will open Ubuntu on every new terminal instance by default. Open up the settings by selecting the drop down beside the + tab button or Ctrl + ,. Once you open the settings you can customise this as you like such as changing the colour scheme. You can even install your own colour themes like Catppuccin.

This configuration will only customise the look of the actual terminal and not the command line. We will go through a command line shell configuration later on in this guide.

Update the Linux

Open up an Ubuntu instance and type the following command to update the kernel.

sudo apt update && sudo apt upgrade

Customise the Command Line Prompt

There is still one problem, our command line looks ugly. Let's fix that!

We are going to install Oh My ZSH to gain more control over the Linux command line. Oh My Zsh provides helpful functions, plugins and themes to allow us to manage our Zsh configuration. To install it run the commands below:

sudo apt install zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

At this point, you probably don't know what type you would like to use. Open the zsh config file, usually located at ~/.zshrc and navigate to the following snippet.

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="random"

If you change this variable to random, a new theme will be selected every time you open up a new terminal session. Once you find one you like you can copy it's name into this field. Alternatively you can download a theme like Powerlevel10k and customise that. The options are unlimited.

Visual Studio Code

The most popular used IDE for coding is Visual Studio Code. You have most ilkley encountered and used this before and here we will go through a local setup.

First install VSCode from the website and open it as usually.

To connect WSL to VSCode we will have to install the WSL extension. This will allow us to use WSL in VSCode.

Once installed, open the command pallet in VSCode by typing Ctrl + Shift + p and search for WSL: Connect to WSL in new Window. You will now see that the box in the bottom left corner should now say WSL: Ubuntu. If you open a terminal in VSCode this will be running your zsh. Everything you do in this environment will be happening on linux.

You can now open VSCode from the terminal by navigating to the folder you'd like to open. Then type code . in the terminal. When doing this for the first time, you should see VS Code fetching components needed to run in WSL.

Further Customisation

This should be enough to get you started developing! However there are an infinite amount of further customisations and other tools and applications you can install and include.

Windows Local 😈

With the current trends at UNSW and the CS as a whole, I feel obligated to say that a local windows developer setup is likely not ideal especially for UNSW undergrad CSE Work. Problems that you will run into

  • Some software (build tools, packages, etc.) may be difficult/impossible to install and configure. A significant mention for this is the C family of languages.
    • Prepare to learn some fun things about windows when customising and messing around.
    • Typically less online support for these kinds of issues.
  • Terminal commands will not be the same. Recent powershell releases have brought it close to parity with unix based systems but there are significant differences.

However that being being said having your files on one system and not having to deal with the mental overhead of managing wsl may be worth it for you. For what its worth I've used this setup for most of my time at uni with only a few fustrations.

Windows Terminal

Windows has an official Windows Terminal app. This app makes it easy to switch between different terminals, including WSL if you do end up needing a linux subsystem at somepoint.

Once install take a look around which terminals are avaliable and try playing around with some of the customisations.

Powershell & Other Alternatives

By default Windows 11 contains the following command line tools, Windows Powershell and Command Prompt. When using command prompt you will need to use the windows specific commands & terminology. With Powershell there's an effort to support UNIX commands which results in an experience that you might be more familar with. At this point feel free to shop around for other terminals/shells that might suit you, personally I'm using PowerShell 7+.

For the rest of the guide we'll proceed with MS Powershell.

Winget

Winget is a command line install tool that is picking up in popularity. It provides a similar install experience to linux systems. It should be avaliable on Windows 10/11 systems. You can check if its installed with powershell

winget

If its not avaliable, installation instructions can be found here

Editors (VSCode)

The most popular used editor for coding is Visual Studio Code. You have most likley encountered and used this before and here we will go through a local setup.

First install VSCode from the website and open it.

You can now open VSCode from the terminal by navigating to the folder you'd like to open. Then type code . in the terminal.

Other Editors

If it peeks your interest I would recommend trying out different IDEs. Some personal suggestions are

  • Jetbrains Webstorm (and other IDEs for different languages). These are heavier IDEs with inbuilt debuggers and other features. Students at UNSW get free access so I'll recommend at least giving it a go while its cheap.
  • NeoVim. Huge variety of distribution and customisation options. It's really its own rabbit hole that you can dive down. These editors take a more minimalist and streamlined approach.

Whatever your choice I recommend taking your time to learn your enviroment in particular learning/setting up keybinds that may help save your wrists in the future.

Installation

Once you have an environment to code in we will need to install a few things before we can get going.

Zsh Plugins

If using Zsh, open the ~/.zshrc file and update the plugins. This will install git and nvm for you when you start a new terminal instance. If this is done you can skip to Configuring Git, Installing Node and NPM and Troubleshooting to see if this worked. Otherwise follow with the other steps.

plugins=(git nvm)

Git

Git is a version control system that tracks changes to a set of computer files which is usually used for coordinating work among programmers who are collaboratively developing source code. Git itself isn't too handy but when paired with a Git provider like GitHub and GitLab it becomes extremely powerful.

This guide will not cover how to work and use Git. If you want to learn how to use Git please read this Git Basics Guide.

Installing Git on MacOS

If you're using macOS, open a terminal and enter the following command:

brew install git

This command will use Homebrew to install git. Git may already be installed on your system, however this will ensure you have a more updated version.

Installing Git on Linux & WSL

If you followed the previous guide your Window's setup should now be running WSL and you will be coding within a linux sub shell. To install Git run the following commands in a terminal:

sudo apt update && sudo apt upgrade
sudo apt install git

Installing Git on Windows (Local)

Install git with the following command in a powershell instance.

winget install --id Git.Git -e --source winget

Configuring Git

After installing Git we have to configure it. To do so we need to set the name and email by running the follow commands remembering to replace the name and email.

git config --global user.name "Nicole Chun"
git config --global user.email "hello@devsoc.org.au"

You will now need to setup SSH keys if you haven't already. Guide for setting up SSH with GitHub

Node and Node Package Manager (NPM) - Windows Local

This installation process doesn't include a version manager.

Download node and follow the installation process. Install with all the default options.

Node and Node Package Manager (NPM) - MacOS, Linux, WSL

Throughout this course we will be working with JavaScript, TypeScript and the React framework which all involve using both Node and NPM. The best way to install this is to use Node Version Manager (NVM) which allows you to change your node version at will.

Installing NVM

We will be following the installation documentation found here.

To install nvm, we can use the following cURL or Wget command (pick one):

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Either of these commands will download a script and run it. The script clones the nvm repository to ~/.nvm, and attempts to add the source lines from the snippet below to the correct profile file (~/.bash_profile, ~/.zshrc, ~/.profile, or ~/.bashrc).

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

Please ensure that this snippet is included in your shell config file or else nvm will not work.

Installing Node and NPM

We can now install any version of node we wish to have. To simply install the latest version run

nvm install node # "node is an alias for the latest version"

Note that NVM will install both node and NPM.

If you wish to install or switch between versions please read through the documentation found here.

Troubleshooting

To check whether Git, Node of NPM has been installed correctly we can open a terminal and type the respective lines. If you see something similar the code below, then your installation is successful.

$ git --version
git version 2.43.0
$ node --version
v18.12.1
$ npm --version
9.8.1

Optional Extras and Recommendations

Here is a list of additional recommendations for plugins and tools which aren't necessary but will improve your coding experience.

VSCode Extensions and Themes

It is recommended to install a theme and any extensions you would enjoy, below are a few suggestions:

Themes and Aesthetics:

Utility:

For fun:

Web Browsers

As a web developer, you should also have a variety of browsers installed on your system. I would at least recommend the following two:

  1. Google Chrome
    • Widely used by most people and is the best for JavaScript debugging.
  2. Mozilla Firefox or FireFox Developer Edition:
    • FireFox has a much better suite of CSS and styling tools.
    • Developer Edition provides more developer features particularly for flex box and grids.

You can read much more about these web browsers on their respective pages or online.

Zsh Autosuggestions

This is a zsh plugin which will give you suggestions for your command line based on your previously used commands. To install it simply clone the repo into $ZSH_CUSTOM/plugins:

git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

Then add the plugin to the list of plugins for Oh My Zsh to load (inside ~/.zshrc) and start a new terminal session:

plugins=(
    # other plugins...
    zsh-autosuggestions
)

Homebrew installation

You can also install this using Homebrew (on macOS) by entering the following two commands:

brew install zsh-autosuggestions
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh

This will first install the plugin and then add it to the end of your .zshrc.

GitHub CLI

GitHub CLI allows you to access GitHub from the terminal. Allowing you to view repos, issues and pull requests from the command line. To install it follow the instructions found the official page.

Docker

It is also recommended to install Docker to containerise your project however this mostly likely will not be needed for beginner web developers. If you would still like to install it you can do some from the Docker Desktop site.

Other Text Editors

Alternatively you could try setting up and using another text editor like NeoVim however this takes more time and is more advanced and may not be worth your time.

To mention a possible solution, NvChad is a Neovim config which can be installed with one command however you will still need to set a few things up.

Javascript

Below is an assortment of videos that well help you get started with javascript. Currently the exercises on offer are

Javascript Summary (Credits: Fireship)

Javascript Syntax Tutorial (Credits: Jeremy Le)

Javascript DOM Exercises

Focus: JS | Authors: Dylan H

These exercises are designed to get you familar with making changes to the DOM. You should open the file in your browser by copying the absolute file path of ex(1|2|3).html and pasting it into the top bar.

Exercise 1

For this exercise change ex1.js. Use javascript to change the following things on the html page

  • Link the javascript into the html
  • Add your name in the h2 element with id #name
  • Make the text bigger and green
  • Change the img src to show a photo of a cat
  • Change the style of all of the squares so that they appear on the page

Exercise 2

For this exercise alter both ex2.js and ex2.html so that when button(x) is pressed it will fill in the center box with the corresponding html.

Bonus ⭐: Make it so that the text fills in when the mouse leave the button instead of the click event. What happens if you add another button?

Exercise 3

Complete the fetch code in ex3.js. Add the friendly advice from the API to the given box.

Bonus ⭐: Try using another api! You could also try to use an api that takes an input and combine that with a text input.

Figma

24T1 Presentation Slides

Credit: Merry Rosalie & Daniel Huynh | Link to figma / slides

Exercise 1: Fangspook Marketplace

Credit: Rachel Bai

Redesign the spooky marketplace for Count Suckberg! The exercise is avaliable here.

About React ⚛︎

📕 Preface and Resources

You can find the official documentation here. This series of exercises is intended to be a bite-sized and practical rendition of it, but I would highly recommend having a read through of the documentation yourself and attempting any examples/exercises provided. The odin project also has a great section on react for further practice.

You may also find the following resources useful:

What is React?

React is a javascript library for building web apps and mobile applications, it essentially makes it really easy to write javascript and html together!

To be a little more specific, React is a User Interface (UI) library, which has a focal point on breaking down pages into components, that will react accordingly when the state of your application changes by re-rendering the affected components.

One of the main ideas that react uses is declarative rendering; meaning that opposed to extracting the exact element to edit imperatively, we just declare the outcome and let react figure out how to make the changes.

What is actually going on

Anytime we work with javascript, there arises a problem of wanting to keep our DOM and javascript in sync.

A naive and dumb way of ensuring this is to delete the whole DOM and re-render it entirely from scratch anytime something changes. However, it is too computationally expensive to do this since each re-render we are recalculating the positions of everything and then actually rendering the objects.

But we can make this ‘delete the whole DOM’ approach more efficient by only deleting and recreating the parts we actually need. So by keeping our own copy of the HTML hierarchy in js, we can make changes against it and use the differences to update minimal parts of the DOM. This technique is called the virtual DOM.


⚠️ Before you proceed with the exercises, make sure that you've installed nodeJs (use LTS).

🌱 Introduction to React ⚛︎


Authors: Nicole Chun

Content Summary

  1. Background and Resources
  2. Setup and Introduction
  3. Exercise 1 - Character Profile (Markup and JavaScript)
  4. Exercise 2 - Link's Cookbook (Components and Props)
  5. BONUS Exercise 3 - Cooler Spotify

Please note that the exercise solutions are contained within the exercise folder for this workshop

Setting up

Usually we create a react app using a react based framework. A framework is essentially a structure you can build your software on so you aren’t starting with an empty directory. For simplicity we will not start with one, and are instead going to use a tool called Vite.

First, create a Fork of this directory. Then in the terminal, git clone the forked repository and cd into it.

To run the application, first run npm i to install all the project dependencies, then npm run dev, and copy paste the link http://localhost:5173/ into your browser to view the app! Every time you make changes, the page will automatically refresh when you save so you don't need to manually reload the page every time :)

$ npm i
    ...
$ npm run dev

  VITE v5.0.11  ready in 833 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

Note that localhost means that we are running a local server, so your site will stop working after you have terminated the connection with ^C or ^D.

Directory Structure

Depending on the framework used for your project, your directory structure may look a little bit different, but will usually contain the following files or directories:

File/dirDescription
App.jsxYour project’s main hub! Usually will contain some routes to different pages.
index.cssAny global styling can be found here (basically css that will show up on all your pages)
types.tsDepending on the scope of your project, this might be a directory with a few files in it. But this contains any interfaces or types that you may need to use to pass data around.
assets/Any media you might use in your .tsx files!
components/ props/Reusable chunks of code + styling that you have broken your page down into. Props are literally just components that take in ‘properties’.
pages/The main pages that your ‘app’ has. Usually you would have a route in App.tsx to each page.

Note that since Vite is not a framework, some of these files/directories are missing, but you should put your code inside the src directory (and optionally make subdirectories to organise your exercises).

File anatomy

Open src/App.jsx, you should be greeted by some pre-written code; don't worry about what it does yet, but this can give you a general idea of how a component is laid out.

1-1-1

In React, you'll mainly be working with .jsx files, this stands for JavaScript XML. Basically, it allows you to combine markup and javascript together, rather than putting them in seperate files. We will go further into this later :)

🌟 [Exercise 1] Character Card 💙

  • Exercise directory: /src/exercises/1-character-card/
  • Display exercise: http://localhost:5173/exercise1
  • Sample answer: /src/answers/1-character-card
  • Display sample answer: http://localhost:5173/answers/exercise1

Writing markup

Plain markup is very similar to html, but wtih a couple more rules. Similar to html, we can also style markup elements with css by importing the file at the top of the page, and using the className or id fields to label.

html

<h1>Kirby's questlog</h1>
<img
  src="url/to_a_photo.png"
  alt="Kirby"
  class="photo"
>
<ul>
  <li>Invent new traffic lights
  <li>Rehearse a movie scene
  <li>Improve spectrum technology
</ul>

jsx

  • We must return a singular root div; it can be a regular div or an empty one like below called a fragment.
  • All brackets must now be closed; you can see so in the <img> and <li> elements.
<>
  <h1>Kirby's questlog</h1>
  <img
    src="url/to_a_photo.png"
    alt="Kirby"
    className="photo"
  />
  <ul>
    <li>Invent new traffic lights</li>
    <li>Rehearse a movie scene</li>
    <li>Improve spectrum technology</li>
  </ul>
</>

Adding JavaScript

For many years, web developers kept content in HTML, design in CSS, and logic in JavaScript—often in separate files! Content was marked up inside HTML while the page’s logic lived separately in JavaScript.

However, with .jsx files, we can now embed JavaScript within the markup!

Starting with a simple example, we can include any javascript by just putting any logic inside curly braces { }.

const MyComponent = () => {
	// Variables
	const name = "Micolash";

	// Expressions
	const sum = 1 + 2;

	return (
		<>
			<p>Hello, {name}!</p>
			<p>1 + 2 is {sum} </p>
			<p>This also works! {1 + 2}</p>
		</>
	);
}

We can also directly return elements from functions

const MyComponent = () => {
	// Function that doesn't take in anything, RETURNS a div
	const printMsg = () => {
		return <p>Ah, kos... or some say kosm...</p>;
	}

	// We can also pass in variables to our functions
	// `num` is a variable name, it can also be named anything we want
	const isThisOdd = (num) => {
		return (num % 2 == 0)
			? <p>{num} is even</p>
			: <p>{num} is odd</p>
	}

	// This does the same thing as isThisOdd(num). 
	// I just like ternary if statements skull
	const isThisOdd2 = (num) => {
		if (num % 2 == 0) {
			return <p>{num} is even</p>
		}
		return <p>{num} is odd</p>;
	}

	// If we don't use an arrow, we can also directly return a result
	const shoutNumTimes = (numTimes, msg) = Array(numTimes).fill().map((_, i) => <p key={i}>{msg}</p>)

	return (
		<>
			{printMsg()}
			{isThisOdd(num)}
			{printSus(13)}
			{shoutNumTimes(4, "yippee!!")}
		</>
	);
}

Styling our Markup

There are 3 main ways (that I can think of) that you can style your elements; different projects might prefer one method over another, but in the end they basically do the same thing. You can also mix and match!

Importing a css file

Similar to what you have done when writing plain css/html, and keeps your jsx file cleaner. Sometimes a bit overkill to apply 1 style to a singular component but it is what it is.

import './App.css'
const App = () => {
	return (
		<div className="text-container">
			<p className="main-text">Cool text<p>
			<p className="main-text">Cool text<p>
		</div>
	);
}
.text-cotainer {
	width: 30em;
	height: 30em;
	background-color: blue;
	border: 2px solid white;
}

.main-text {
	color: white;
	font-weight: bold;
}

Inline

Good for when you only have a few styling attributes, but falls a bit short when you intend to reuse some styling for different components. If the styles start to get long, its a good idea to put attributes on different lines.

const App = () => {
	return (
		<div style={{
			width: "30em", 
			height: "30em", 
			backgroundColor: "blue", 
			border:"2px solid white"}}>

			<p style={{color: "white", fontWeight: "bold"}}>Cool text<p>
			<p style={{color: "white", fontWeight: "bold"}}>Cool text<p>
		</div>

	);
}	

Inline with objects

Since the style field takes in an object, we can just pass in one rather than type it all inline and provides a good balance between using plain inline and external css files.

const App = () => {
	return(
		<div style={styles.mainContainer}>
			<p style={styles.mainText}>Cool text</p>
			<p style={styles.mainText}>Cool text</p>
		<div>
	);
}

const styles = {
	mainContainer: {
		width: "30em",
		height: "30em",
		backgroundCOlor: "blue",
		border: "2px solid white",
	},
	mainText: {
		color: "white",
		fontWeight: "bold",
	}
}

Task

You are given the character object inside CharacterCard.jsx. Your task is to use markup and javascript to recreate the following player profile card.

ex1

You may need to create and import your own css file in order to style some elements to make it match the result.

Don't worry if your styling isn't super on point (esp during the workshop, just at least display the data), though it would be a good idea to get some practice in!

Hint Whenever we want to group some divs/elements together, we can wrap them with a parent div! For example:
<div>
    <p>Wow I am a child!</p>
    <p>Wow I am a child!</p>
    <p>Wow I am a child!</p>
    <p>Wow I am a child!</p>
</div>

🥘 [Exercise 2] Link's Cookbook 🍎

  • Exercise directory: /src/exercises/2-links-cookbook/
  • Display exercise: http://localhost:5173/exercise2
  • Sample answer: /src/answers/2-links-cookbook
  • Display sample answer: http://localhost:5173/answers/exercise2

Components and Props

Components are kind of like the functions of React! They help you chunk your code into smaller, more managable elements. Similar to how functions work, sure you could just write all your code in main, but it makes your code much more readable and reusable :)

If you've done any object oriented programming, I would say that that Components/Props are a little more analagous to Objects, where they each have their own set of variables and functions.

Also in react, basically everything rendered is a component - you might have noticed it from the syntax of App.jsx but it is essentially a big component that contains many smaller components.

Components

To use a component you have created:

  1. import your child component at the top of your file
  2. use it in your markup with the syntax <ComponentName/>
import ChildComponent from './path-to/ChildComponent'
const ParentComponent = () => {
    return (
        <ChildComponent/>
    );
}

To create a component

  1. create a new file for it called ComponentName.jsx (pascal case), usually in the components/ directory - dw about doing it here in the exercises
  2. create a new function called ComponentName
  3. export default ComponentName; at the bottom of your file
// Usually good syntax practice to use arrow functions
const ChildComponent = () => {
    return ();
}

export default ChildComponent;

// But this is also fine
function ChildComponent() {
    return();
}

export default ChildComponent;

Props

Props are components that take in some properties!

// The 'number' and 'message' fields can be named anything you want!
// You can also pass in 0 or more fields to a prop
const ParentComponent = () => {
    return (
        <ChildProp1 number={4} message={"among us"}/>
        <ChildProp2 number={4} message={"among us"}/>
    );
}

const ChildProp1 = (props) => {
    // to access the 'number' and 'message' fields being passed in, 
    // we just do props.[FIELDNAME]
    const num = props.number;
    const msg = props.message;
    console.log(num + msg);
    ...
}

// We can also destructure our prop by using curly braces
const ChildProp2 = ({number, message}) => {
    console.log(number + message);
    ...
}

Task

You are given a list of recipes in recipeData.js that include data on a recipe's name, ingredients, and hearts restored. In CookBook.jsx, display each of the recipes as recipe cards to recreate the following page:

ex2

You will have to create your own components that may or may not use props.

For the heart icons, we've installed react-icons in this project, so you can just use:

import {BsFillSuitHeartFill} from "react-icons/bs";

You may need to create and import your own css file in order to style some elements to make it match the result, but once again, don't worry if your styling isn't super on point (esp during the workshop, just at least display the data).

Hint You will probably want to create a reusable component RecipeCard that takes in a recipeName, and list of recipeIngredients[] as its props.

[BONUS Exercise 3] The cooler spotify

hey remember that spotify figma from last week? yeah now recreate that in react B-)

(Unless you already know react, don't worry about adding any functionality - just attempt recreating it with your own dummy data)

orr you could just mess around and make something that seems interesting to you!

Other things that you could try to design/make could be:

  • Todo list
  • Recreate your personal profile with react

Styling

In this section we aim to cover the basics of realising your frontend design with CSS, whilst also giving pointers to popular approaches and libraries (as of 2024) for you to try.

Currently we have execises covering

DevWatch 📺

Focus: TailwindCSS, React

Authors: Dylan Huynh

Dylan frequently uses the website shown below to "legitmately" stream anime. Fearing a possible permanent service disruption in the near future he commissioned Kevin, another Software Engineer to recreate the website. However, Kevin has mysteriously disappeared, as such Dylan has tasked you to finish recreating the website.

image

Setup

Inside the reputable-anime-site directory

$ npm install
$ npm run dev

Part A - Setting up the layout

Let's start by setting up the layout. In App.jsx let's define a layout using flexbox where the VideoController takes up the majority of the screen with the information column will take up the rest of the horizontal space. Finally add the Navbar component to the top of the page.

Inside the video controller define sections for the episode controllers

  • Sidebar for selecting episodes
  • A section for selecting streaming sources
    • Subdivide this section in 3 parts as per the original website design shown above

For fill each section with a different background colour. We're looking to see if the layout is correct and will work on a variety of desktop screen sizes. To test this try resizing your browser window.

Click for Relevant Tailwind Documentation

At this stage your webpage should look similar to the image below.

layout

If you are so inclined you could also make the layout work for mobile by making the info panel (pink) either disappear on smaller screens or move below the video player. Breakpoints will be helpful.

Part B - Complete the Info Panel

Kevin already finished most of the info panel. His work can be found in components/SeriesInfo.jsx.

Your task is to insert the SeriesInfo component into the main page and finish the following functionality

  • Display the title and description
  • The description should be limited to 200 characters until the user presses +show more. Will revert back when -show less is pressed. The show text should be placed after the description.
  • Score card (optional), see design in the original website

For hints refer to the tailwind documenation especially the ones in the dropdown above.

Your page should look simialr to the image below.

layout

Part C - Adding Episode Controls

Before his disappearance Kevin was also working on VideoController.jsx, which will contain the video player itself and all the controls required to change episodes and streaming services. Unfortunetly he was unable to complete the controls.

Your task is to complete the following UI components

Episode Sidebar

  • Display all the episodes on the side of the VideoPlayer
  • Number all episodes
  • Alternate colours between episodes
  • When an episode is clicked on the left it will change the videosrc for the video player.
  • The selected episode will have a marker to indicate it has been selected. For simplicity make the marker an emoji of your choice. Make sure to align this correctly!

Streaming Service Controls

  • Display all subs and dubs streaming services. These have been hardcoded in VideoController.jsx
  • Display the correct episode name and streaming source
  • The appropiate icons have already been imported from React Icons. It may be easier to style these icons through using the React Icons API instead of Tailwind classes
  • Display a dotted line between the sub and dub sections

Your app should now look similar to the image below

layout

Part D - Background Blur (Optional)

Finally we're going to add some finishing touches, by adding the background blur effect. Let's make Kevin proud!

layout

As far as I'm aware there is no easy way of doing this through tailwind, so we're going back to regular CSS.

Inside index.css add styles that will help achieve the blurred background effect. Do not edit the index.html file and instead make all of your changes inside App.tsx.

The background image is provided in the public folder, you will be able to achieve this effect with purely css filters.

Storage

Most websites will end up requiring some kind of persistent storage. The following exercises will help get you started with integrating different types of storage with a React app.

Currently we have execises covering

6.1 - Setting Up the Database

6.2 - myGarregMach

6.1 - Setting Up the Database

Authors: Jayden Nguyen

For this exercise, there is a bit of setup required. It is recommended that you do this prior to the workshop as to save time on working the exercises!

This workshop exercise will make use of Firebase's Firestore as the database. Your trainee projects might make use of MongoDB or other alternatives, so whilst it may not exactly be the same, the skills are very much transferrable! :)

1. Sign into Firebase Console

Our first step will involve creating a new account for Firebase. Head over to https://console.firebase.google.com/, and if prompted to sign in, please do so!

2. Create A New Project

Head over to the Console, and create a new Project. If you are prompted for Google Analytics, it is optional — however, should you choose to do it, just select Default App on the screen after for your configuration.

new-project

3. Create a New Web App

Now, you'll be greeted with a home screen that looks like the following:

home-screen

Click the </> looking icon to create a Web App! This will be used for our configurations. Give it any name (preferably myGarregMach but it doesn't really matter).

After creating your app, your screen should give you something that looks like this (I blurred out the credentials on my screen):

copy-json

Keep this details opened, they will be important for the next step.

4. Loading Credentials

In your code editor, open the exercises/myGarregMach folder, and navigate to the server folder. Create a new file in this folder called fireBaseConfig.json. It is important the file is named exactly as described. (It should be at root level, not inside src).

Now, from the previous step, click the Config radio button, and copy and paste the object into fireBaseConfig.json.

That's half the work! Now, get rid of the const firebaseConfig = and the semicolon at the end. Then, add double quotation marks around each of the fields on the left.

The final result should look like this (minus the blur marks):

credentials

5. Setting up the Firestore

Go back to the Firebase Console, and under the sidebar, under "Build", click the Firestore Database option.

firestore-create

Then click the big 'Create database' button!

Set the location to australia-southeast (Sydney). (Unless you're on the other side of the world).

Afterwards, select "Start in test mode".

test-mode

6. Database rules

Your database should now be created! Now we just need to modify the database rules to ensure we can work with the data involved!

Head over to the 'Rules' tab of the firestore, and replace the request.time < timestamp.date(...) with true. The final result should look like this:

dbrules

Publish the changes.

7. Uploading the Data

For this exercise, I've already created data and a script to upload! All you need to do is to upload them. :)

cd into the server folder under myGarregMach.

Then, run

npm install

Once the download has completed, run

npm run upload

If you've done everything correctly, your console should look like this:

successUpload

If the upload was successful, you can look over to the database and see the following:

databasepopulated

...And that's it! The Set Up phase is completed!! Now onto the exercises :)

myGarregMach

Focus: localStorage, databases

Authors: Jayden Nguyen

ATTENTION!

The Church of Seiros is upgrading their existing medieval pen-and-paper student enrolment system to a new-and-improved online system for Garreg Mach Monastery. Unfortunately, the recent invasion of the Death Knight has scared off all the software engineers (cowards), leaving the conversion incomplete.

garreg-mach

In response, Professor Byleth, (a man of too many talents), has been comissioned by the Church to finish off the work left over by the previous engineers. Lucky for him, the frontend and most of the backend has already been completed.

Startup

To begin, first verify that both the frontend and backend work.

In your editor, initialise TWO terminal screens.

On one screen, run

cd client
npm install 
npm run dev

Navigate to the localhost link, and you should be greeted by the "Welcome Back!" Login page.

On the other screen, run

# you should have already installed the server node_modules when setting up already.
cd server
npm run start

If you need assistance, please ask one of the Leads or Directors for assistance!

Exercise 1 — Basic Local Storage

Your first task is to complete the login functionality. The frontend needs to store a user's gID and USER_TYPE inside localStorage.

Navigate over to client/src/pages/Login.tsx. In the handleSubmit function, there is a zone for you to finish off the existing code with guidance comments left by the previous engineers.

To login, you can use Professor Byleth's credentials:

gID: 5364821
password: pokerfaceprof

If you've done it correctly, the Login page should redirect you to the Home Page!

Exercise 2 — Simple localStorage Clear

Currently, the Logout button is incomplete - clicking it doesn't seem to do anything :/

Navigate over to client/src/components/Navbar/Navbar.tsx. Your next task is to clear all of localStorage to ensure a Logout redirects back to the Login page.

If your solution is correct, clicking Logout should redirect you back to the Home page.

Exercise 3 — A Basic Batabase Lookup

Hmm...the notice board is looking a bit empty - let's fix that!

For context, myGarregMach currently makes use of Firebase's Firestore to handle its database storage. Firestore is organised by two primary dataStorage types: collections and documents.

A Collection is a group of Documents. Documents are how we store one instance of data, and Collections is like a folder that wraps them up. To give a concrete example, in our case, a single Notice would be a Document, whereas all notices in the database would be stored under the 'notices' collection.

Like a computer, to find a specific file (or a set of files), you first have to access the folders (or Collections), before you can access the Documents. This can be done on Firestore by using

await getDocs(collection(databaseRef, collectionName)). 

Lucky for you, the databaseRef can be obtained using getDb(), a helper function written by the previous engineers located in server/src/utils/db.ts!

After calling getDocs(), it will return a QuerySnapshot, which is like a "tray" containing all the data from the Collection. A specific reference as to what QuerySnapshot is can be found on the official docs. You can access individual Documents by using forEach((doc) => {...}), and can obtain the actual data they contain using doc.data().

With all that info in mind, head over to server/src/funcs/notices.ts. You will notice (haha, get it?) that the function is a stub. Don't worry if you are unfamiliar with the code setup for now, there's a bunch of comments that will guide you on how to complete this function :)

Your task is to complete the stub, such that it will return an Object, with a field 'notices', which contains an array of Notices.

To get an idea of what a single Notice might look like, take a look over at server/db/dbData.json. But a quick reference is also found here:

{
    title: string,
    body: string
}

You won't have to restart the backend each time you save (it automatically does it). But you will need to refresh your web page each time you make a change on the backend.

If you are successful, the notices should appear!

notice-success

Exercise 4 — Pre-processing retrieved database data

It looks like we've gotten the notices to be fully functional!

However, if you navigate over to the Staff Profile page, and select View Students - you'll see there are no students! :(

Your task for this exericse is to complete the function in src/server/funcs/studentCards.ts.

Exercise 4 is just Exercise 3 but with a little bit of extra steps - so you can use similar code, or, you can look at similar funcs that have already been implemented.

You will probably need to login and logout over again to verify that your changes work (yes, I know it's annoying but I'm trying to save you from using your limited database READs). Lucky, nodemon makes it less annoying for backend modification.

If your code is correct, the sample screen should appear:

view-students-success

Exercise 5 — Retrieving data with a specific query

Now it seems we have something working on the Staff page - but the Student page needs a bit of working too!

Log out of Professor Byleth's account, and try logging into a student's account (don't worry, as a Professor, you are meant to have access to this private info 💀).

You can find a student to login by choosing your favourite from server/db/dbData.json. Or you can use the credentials of a student I've chosen for you :)

gID: 5424698
password: studiousmage

We've talked before about how to get all documents out of a collection, but how can we query for a single document based on some criteria? Luckily, Firestore offers just that!

Using the query() function, we can effectively compose a single query with multiple conditions.

An example piece of code to get the associated QuerySnapshot might be:

await getDocs(query(collection(databaseRef, collectionName), where(documentField, condition, value)));

In this piece of code, the where is akin to an SQL statement WHERE. So for example, if I want to find a staff member that has gID of '5364821', this is represented in SQL as, SELECT * FROM staff WHERE gID = '5364821'. We can modify this to Firestore's modules with this:

where('gID', '==', '5364821')

Using this information, your task is to go to server/src/funcs/studentDetails.ts and complete the stub. There is already existing information (and code from other functions) that might provide you a clue as to how to implement this!

Again, you will likely need to login and logout of the account to check if your server changes are indeed valid. If they are, the following screen should display (assuming you've used the login I chose for you):

success-student-details