Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 19 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,27 @@
# Final Project
*Due October 13th (final day of the term)*

For your final project, you'll implement a web application that exhibits understanding of the course materials.
This project should provide an opportunity to both be creative and to pursue individual research and learning goals.

## General description
Your project should consist of a complete Web application, exhibiting facets of the three main sections of the course material:

- Static web page content and design. You should have a project that is accessible, easily navigable, and features significant content.
- Dynamic behavior implemented with JavaScript (TypeScript is also allowed if your group wants to explore it).
- Server-side programming *using Node.js*. Typically this will take the form of some sort of persistent data (database), authentication, and possibly server-side computation.
- A video (less than five minutes) where each group member explains some aspect of the project. An easy way to produce this video is for you all the groups members to join a Zoom call that is recorded; each member can share their screen when they discuss the project or one member can "drive" the interface while other members narrate (this second option will probably work better.) The video should be posted on YouTube or some other accessible video hosting service. Make sure your video is less than five minutes, but long enough to successfully explain your project and show it in action. There is no minimum video length.

## Project ideation
Excellent projects typically serve someone/some group; for this assignment you need to define your users and stakeholders. I encourage you to identify projects that will have impact, either artistically, politically, or in terms of productivity.

### Deliverables

#### Form Team (due 9/25)
Students are will work in teams of 3-5 students for the project; teams of two can be approved with the permission of the instructor. Working in teams should help enable you to build a good project in a limited amount of time. Use the `#project-logistics` channel in Discord to pitch ideas for final projects and/or find fellow team members as needed.

Teams must be in place by end of day on Sunday, September 25th. If you have not identified a team at this point, you will be assigned a team. You will be given some class time on Monday to work on your proposal, but please plan on reserving additional time outside of class as needed.

#### Proposal (due 9/27)
Provide an outline of your project direction and the names of associated team members.
The outline should have enough detail so that staff can determine if it meets the minimum expectations, or if it goes too far to be reasonable by the deadline. Please include a general description of a project, and list of key technologies/libraries you plan on using (e.g. React, Three.js, Svelte, TypeScript etc.). Two to four paragraps should provide enough level of detail. Name the file proposal.md and submit a pull request by Tuesday, September 27th at 11:59 PM (end of day). Only one pull request is required per team.

There are no other scheduled checkpoints for your project.

#### Turning in Your Project
Submit a second PR on the final project repo to turn in your app and code. Again, only one pull request per team.

Deploy your app, in the form of a webpage, to Glitch/Heroku/Digital Ocean or some other service; it is critical that the application functions correctly wherever you post it.

The README for your second pull request doesn’t need to be a formal report, but it should contain:
README

1. A brief description of what you created, and a link to the project itself (two paragraphs of text)

Link: https://final-project-lnbsr.glitch.me/

Description: We created a website on which a user can login and view playlists of the top songs of various genres. They can also add songs to each genre, as well as upvote or downvote individual songs. Users can register, and the songs/votes data is persistent between sessions and users.

2. Any additional instructions that might be needed to fully use your project (login information etc.)

Additional Instructions: The project is rather user-friendly. To Register, click the register button to go to the register page, enter your new username and password, and click register again. To sign in, click Sign In, enter your username and password, and click Sign In again. Once signed in, you can view the playlists of songs, and can upvote/downvote songs, as well as click the Add Song button to add a new song to its respective playlist.

3. An outline of the technologies you used and how you used them.

We used MongoDB for a database, as well as bootstrap for CSS. We also used express for server-frontend communication. We also used Node.js for the server.

4. What challenges you faced in completing the project.
5. What each group member was responsible for designing / developing.
6. A link to your project video.

Think of 1,3, and 4 in particular in a similar vein to the design / tech achievements for A1—A4… make a case for why what you did was challenging and why your implementation deserves a grade of 100%.
Lexie and Benjamin ran into a number of errors redirecting from the login to the top page. Sidney and Nadiyah ran into some issues finding a good way of showing all the playlists on the same page, as well as showing the songs in tables rather than lists. Ryan ran into some issues getting server communication to work with her page.

## FAQs
5. What each group member was responsible for designing / developing.

Benjamin took the lead on creating the server side code and communication with the database. Lexie did the Login page. Sidney and Nadiyah made the Top Songs page. Ryan created the Add Songs page.

- **Can I use XYZ framework?** You can use any web-based frameworks or tools available, but for your server programming you need to use Node.js. Your client-side scripting language should be either JavaScript or TypeScript.
6. A link to your project video.

Video: https://youtu.be/-gz7nBQKlts
35 changes: 35 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "glitch-hello-node",
"version": "0.1.0",
"description": "A simple Node app built on fastify, instantly up and running. Built to be remixed on Glitch.com.",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"@fastify/formbody": "^7.0.1",
"@fastify/static": "^6.5.0",
"@fastify/view": "^7.1.0",
"cookie-parser": "^1.4.6",
"express": "^4.18.1",
"express-session": "^1.17.3",
"fastify": "^4.4.0",
"fs": "0.0.1-security",
"handlebars": "^4.7.7",
"mime": "^3.0.0",
"mongodb": "^4.10.0",
"morgan": "^1.10.0"
},
"engines": {
"node": "14.x"
},
"repository": {
"url": "https://glitch.com/edit/#!/glitch-hello-node"
},
"license": "MIT",
"keywords": [
"node",
"glitch",
"express"
]
}
121 changes: 121 additions & 0 deletions public/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// client-side js
// run by the browser each time your view template is loaded

//console.log("hello world :o");

// our default array of dreams

// define variables that reference elements on our page

const loginbtn = document.getElementById("loginbtn");
const registerbtn = document.getElementById("registerbtn");
const usernameInput = document.getElementById("username");
const passwordInput = document.getElementById("password");
const usernameRInput = document.getElementById("newusername");
const passwordRInput = document.getElementById("newpassword");
const loginDiv = document.getElementById("login");
const registerDiv = document.getElementById("register");
const loginTogglebtn = document.getElementById("loginTogglebtn");
const registerTogglebtn = document.getElementById("registerTogglebtn");
let user, pass


// a helper function that creates a list item for a given dream
//loginPage.setAttribute("hidden", "hidden");
//plannerPage.removeAttribute("hidden");



// iterate through every dream and add it to our page

// listen for the form to be submitted and add a new dream when it is
//Form.onsubmit = function (event) {

//};



const onClickLogin = function () {
user = usernameInput.value;
pass = passwordInput.value;

fetch("/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
username: user,
password: pass,
}),
})
.then((response) => response.json())
.then((login) => {
if (login) {
//loginPage.setAttribute("hidden", "hidden");
//plannerPage.removeAttribute("hidden");
//updateTable(user);
//warn.innerHTML = "";
window.location.href = 'top.html';
//TODO: set page (home page)
console.log("logged in");
} else {

console.log("not logged in")

//TODO: tell them wrong username or password


//warn.innerHTML = "incorrect username or password";
}
});

return false;
};

const onClickRegister = function () {
user = usernameRInput.value;
pass = passwordRInput.value;


fetch("/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
username: user,
password: pass,
}),
})
.then((response) => response.json())
.then((reg) => {
if (reg) {
console.log("registered")

usernameInput.value = user;
passwordInput.value = pass;
onClickLogin();
//warn.innerHTML = "registered";
} else {

console.log("not registered")
//warn.innerHTML = "username taken";
}
});

return false;
};

const loginVisible = function() {
loginDiv.removeAttribute("hidden");
registerDiv.setAttribute("hidden", "hidden");
return false;
}

const registerVisible = function() {
loginDiv.setAttribute("hidden", "hidden");
registerDiv.removeAttribute("hidden");
return false;
}

loginTogglebtn.onclick = loginVisible;
registerTogglebtn.onclick = registerVisible;
loginbtn.onclick = onClickLogin;
registerbtn.onclick = onClickRegister;
89 changes: 89 additions & 0 deletions public/create.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!--create/submit playlists page -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Submit</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>

<body class="bg-light">
<h1 class="text-primary ms-1">Submit a Song</h1>
<p>
Enter the song's genre ('Rap', 'Pop', 'R&B', 'Rock', or 'Country'), along
with the song's title and artist
</p>
<form>
<!--<input type="text" id="genre" value="enter a valid genre" />
<select id="genre" name="genre" size="3">
<option value="Rap">Rap</option>
<option value="saab">Saab</option>
<option value="fiat">Fiat</option>
'Pop', 'R&B', 'Rock', or 'Country
<option value="audi">Audi</option>
</select>-->
<select class="form-select form-select-sm" aria-label=".form-select-sm example" id="genre">
<option selected>Genre</option>
<option value="Rap">Rap</option>
<option value="R&B">R&B</option>
<option value="Rock">Rock</option>
<option value="Pop">Pop</option>
<option value="Country">Country</option>
</select>
<br>
<input type="text" id="title" value="enter song title" />
<br>
<input type="text" id="artist" value="enter song artist" />
<br>
<button>Submit Song</button>
</form>
<form>
<button type="backToTop" id="backToTop">
Back to Top Songs Playlists
</button>
</form>

</body>
</html>

<script>

const backBtn = document.getElementById('backToTop');

const submit = function (e) {
e.preventDefault();

const genre = document.getElementById("genre"),
title = document.getElementById("title"),
artist = document.getElementById("artist")
//json = { genre: genre.value, title: title.value, artist: artist.value },
//body = JSON.stringify(json);
//console.log(body)
if(genre.value != 'Genre'){
fetch("/submit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({genre: genre.value, title: title.value, artist: artist.value, vote: 1 }),
})
.then(function(response) {
return response.json();
})
.then(function(json) {
console.log(json);
});

window.location.href = 'top.html';
}
return false;
};

backBtn.onclick = () => {
window.location.href = 'top.html';
return false;
}

window.onload = function () {
const button = document.querySelector("button");
button.onclick = submit;
};
</script>
Loading