Skip to content

Commit

Permalink
Exercises/jayden/db (#19)
Browse files Browse the repository at this point in the history
* committed initial frontend work

* login page completed

* Very early demo page lol

* more fixes and changes to routing

* adding logout functionality

* did make sidebar stuff

* added basic sidebar, and mainblock component

* componentalised

* added react element typing

* got the basic home page done

* remove garbage

* fix importing

* finished temporary version of the student grid

* done basic view students

* Finished Staff Profile and New Student Page

* frontend pretty much complete

* did some frontend refactoring

* added basic db data

* added gitignore

* added some db data, halfway done

* completed more data

* added more data to the json

* added more db data

* added resources

* added firebaseconfig

* added git ignore

* added gitignore

* added upload

* added upload script and necessary libraries, as well as screenshots

* added more guide images

* updated the scripts to work with TS

* setup backend

* added config.json

* added server changes

* server changes only

* added frontend and backend code for login

* added frontend and backend code

* added studentDetails route

* add student and staff details route

* feat: integrated staffDetails and studentDetails routes with the frontend

* added studentCards route, fixed staffProfile and studentProfile

* Fixed bugs with student login

* completed server routes

* completed frontend and application, now writing

* setting up the exercise

* added solution, working exercise

* completed the exercise methinks

* added exercise in gitbook

* added these changes ig
  • Loading branch information
JeydinNewWon authored Jul 8, 2024
1 parent 7e83831 commit 6001622
Show file tree
Hide file tree
Showing 177 changed files with 19,269 additions and 4 deletions.
Binary file added .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion book/src/04_react-intro/workshop_01/1-character-card.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,4 @@ Don't worry if your styling isn't super on point (esp during the workshop, just
<p>Wow I am a child!</p>
</div>

</details>
</details>
2 changes: 1 addition & 1 deletion book/src/04_react-intro/workshop_01/3-cooler-spotify.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ 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
- Recreate your personal profile with react
Binary file added book/src/07_storage/img/copy-json-rules.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/create-firebase-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/create-firestore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/credentials.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/dbRules.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/filledDb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/garreg-mach.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/new-proj.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/notice-success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/test-mode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/uploadStatus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/src/07_storage/img/view-students-success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion book/src/07_storage/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ Most websites will end up requiring some kind of persistent storage. The followi

Currently we have execises covering
- [Local Storage]() [Under Construction]
- [Databases]() [Under Construction]
- [Databases]() [Under Construction]

# 6.1 - Setting Up the Database

# 6.2 - myGarregMach
149 changes: 149 additions & 0 deletions book/src/07_storage/myGarregMach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# 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](img/garreg-mach.jpg)

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
```bash
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
```bash
# 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

```js
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](https://firebase.google.com/docs/reference/js/firestore_.querysnapshot.md#querysnapshot_class). 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 `Notice`s.

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](./img/notice-success.png)

## 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](img/view-students-success.png)


## 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:

```js
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:

```js
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](img/success-student-details.png)

96 changes: 96 additions & 0 deletions book/src/07_storage/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# 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](img/new-proj.png)

## 3. Create a New Web App

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

![home-screen](img/create-firebase-app.png)

**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](img/copy-json-rules.png)

**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](img/credentials.png)

## 5. Setting up the Firestore

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

![firestore-create](img/create-firestore.png)

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](img/test-mode.png)

## 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](img/dbRules.png)

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](img/uploadStatus.png)

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

![databasepopulated](img/filledDb.png)

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


4 changes: 3 additions & 1 deletion book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
- [Cooler Spotify](04_react-intro/workshop_01/3-cooler-spotify.md)
- [Styling](06_styling/index.md)
- [DevWatch (TailwindCSS)](06_styling/devwatch.md)
- [Storage](07_storage/index.md)
- [Storage](07_storage/index.md)
- [Setup](07_storage/setup.md)
- [MyGarregMach (Databases)](07_storage/myGarregMach.md)
18 changes: 18 additions & 0 deletions exercise-solutions/myGarregMach/client/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
24 changes: 24 additions & 0 deletions exercise-solutions/myGarregMach/client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
30 changes: 30 additions & 0 deletions exercise-solutions/myGarregMach/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
export default {
// other rules...
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
}
```

- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
Loading

0 comments on commit 6001622

Please sign in to comment.