- 112-1-hack1
-
VSCoddit—VSCode & Reddit Mock App
Introducing VSCoddit, a unique and innovative fusion of two tech-centric worlds: Visual Studio Code and Reddit. VSCoddit brings together coding enthusiasts, developers, and tech aficionados in a vibrant online community where they can freely share and discuss their code snippets.
At VSCoddit, users can create, share, and discover code snippets, just like you would post and engage with content on Reddit. Whether it's a brilliant solution to a programming problem, a clever code trick, or simply a fun project, VSCoddit provides a platform to showcase your coding skills and learn from others.
One of the standout features of VSCoddit is the upvoting and downvoting system, allowing the community to recognize and promote high-quality code snippets while filtering out the less valuable ones. This system not only encourages contributors to provide meaningful and well-structured code but also helps users quickly identify the best content in the sea of submissions.
Happy hacking!
-
Download Hack1 Folder.
cd /path/to/same/level/with/wp1121 git clone ...
-
Remove
.git
Folder and Move The Folder towp1121
.rm -rf ./hack1/.git mv ./hack1 ./wp1121
-
Read README!
-
Start Coding.
-
(Optional) Local Testing with Playwright.
-
(Optional) Failed Tests? Debug.
-
Done? Zip and Submit to Gradescope
This project utilizes Yarn as its package manager and comprises both frontend and backend sub-projects. It also makes use of the concurrently
package to execute multiple commands simultaneously. Below are the steps to run the project:
node -v # Ensure it's 18.18.0 (recommended) or compatible (18.x.x)
yarn -v # Ensure it's 1.22.19 (recommended) or compatible (1.x.x)
Open your terminal and clone the project using the following command:
cd wp1121 # Enter the wp1121 directory
git clone https://github.com/ntuee-web-programming/112-1-hack1-test.git hack1 # Clone the project
rm -rf hack1/.git # Remove the .git directory
To install dependencies for both the frontend and backend sub-projects, use:
yarn
This will concurrently execute the install:frontend
and install:backend
scripts.
If preferred, you can also install the dependencies for each sub-project separately.
The default port for the frontend is 5173
, while the default port for the backend is 6969
. If you wish to change these ports, you can see .env.example
for more details. Note that the PORT
of backend must match the port in VITE_API_URL
of frontend. You must set the MONGO_URL
of backend before running the project.
To run the frontend and backend concurrently from the project's root directory, enter:
yarn dev
This will concurrently execute the dev:frontend
and dev:backend
scripts.
If preferred, you can also launch the frontend and backend individually.
By adhering to these steps, you should successfully run the project on your local machine.
We utilize Playwright for testing our project. To run the tests, execute:
yarn playwright install chromium # Install Chromium (if not already installed)
yarn playwright install-deps chromium # Install Chromium dependencies (if not already installed)
yarn test
You should run the test in a separate terminal from the terminal you run your service. Ensure you have launched the project (refer to step 3) before initiating the tests!
Other useful commands for testing include:
yarn test public-1 # Test tests/public-1.spec.ts only
yarn test --reporter=list # Only show the list of tests
yarn test --headed # Run the tests in a visible browser
yarn test --debug # Shortcut for "--timeout=0 --max-failures=1 --headed --workers=1"
To ensure you receive full credit for your work, it's essential to submit your project to both Gradescope and GitHub.
🚨 **!!!IMPORTANT!!!** Not pushing your code to GitHub or failing to sign in will result in a 5% deduction from the total score.To submit the project, here is the recommended workflow:
git add .
git commit -m "Your commit message"
git archive -o hack1.zip HEAD:hack1 # Create a zip file of your project
git push # Push your code to GitHub
Then, upload hack1.zip
to Gradescope.
Gradescope Link: https://www.gradescope.com/courses/605052/assignments/3512234
- DO NOT modify the
className
of any element in the HTML files. This is strictly for styling purposes. No points will be deducted for modifying theclassName
attribute, but it's not recommended. - DO NOT modify the
data-testid
attribute of any element in the HTML files. This is solely for testing purposes. If you modify this attribute, your tests may fail. - You should NOT modify files that aren't mentioned in the TODO list. Any modifications to these files will be ignored during grading.
- Even though Gradescope may have graded your code during the test, you must still push your code to the main branch of your GitHub repo
wp1211/hack1
before Hack#1 concludes. If necessary, we will review your code. Failing to push the code before the deadline will result in a 5% deduction from the total score. - If you're wondering where the TODOs are located, utilize the search function in your editor. The TODOs are labeled as
TODO #.#
. For instance,TODO 1.1
pertains to the first subtask of task 1. If you're using VSCode, the shortcutCtrl+Shift+F
(Windows) orCmd+Shift+F
(Mac) will help you search for these TODOs. To see all TODOs, use regexTODO \d\.\d:
. You can also search all warnings by searching forWarning:
, which you should do before submitting your code.
├── backend
│ ├── src
│ │ ├── controllers # Controllers for handling requests
│ │ │ ├── auth.ts # Controller for login and registration
│ │ │ ├── post.ts # Controller for post-related requests
│ │ │ └── user.ts # Controller for user-related requests
│ │ ├── models # Models for database
│ │ │ ├── post.ts
│ │ │ └── user.ts
│ │ ├── routes # Routes for handling requests
│ │ │ ├── auth.ts # Routes for login and registration
│ │ │ ├── init.ts # Route for initializing database
│ │ │ ├── post.ts
│ │ │ └── user.ts
│ │ ├── errors.ts # Error handling
│ │ ├── index.ts # Entry point
│ │ └── utils.ts # Utility functions
│ ├── .env.example
│ └── package.json
├── frontend
│ ├── public
│ │ └── vscoddit.svg # Vscoddit logo
│ ├── src
│ │ ├── components
│ │ │ ├── ui # UI components. You don't need to modify these.
│ │ │ │ └── ...
│ │ │ ├── PostCard.tsx # Post card component for view page
│ │ │ └── ViewFooter.tsx # Footer component for view page
│ │ ├── contexts
│ │ │ ├── PostContext.tsx # Context for view page
│ │ │ └── UserContext.tsx # Context for user information
│ │ ├── routes
│ │ │ ├── auth
│ │ │ │ ├── Layout.tsx # Layout for login and register pages
│ │ │ │ ├── Login.tsx # Login page: `/login`
│ │ │ │ └── Register.tsx # Register page: `/register`
│ │ │ ├── settings
│ │ │ │ ├── FAQ.tsx # FAQ page: `/settings/faq`
│ │ │ │ ├── Layout.tsx # Layout for settings pages
│ │ │ │ └── Profile.tsx # Profile page: `/settings/profile`
│ │ │ ├── Create.tsx # Create page: `/create`
│ │ │ ├── Layout.tsx # Layout for create and view pages
│ │ │ └── View.tsx # View page: `/view`
│ │ ├── services
│ │ │ ├── postService.ts # Service for post-related requests
│ │ │ └── userService.ts # Service for user-related requests
│ │ ├── App.tsx # Main app component
│ │ ├── globals.css # Global CSS
│ │ ├── main.tsx # Entry point
│ │ └── RootLayout.tsx # Root layout
│ ├── .env.example
│ ├── index.html # Base HTML file
│ └── package.json
├── shared
│ └── types.ts # Shared types
├── tests # Tests using Playwright
│ ├── public-1.spec.ts # Test for public-1
│ ├── public-2.spec.ts # Test for public-2
│ ├── public-3.spec.ts # Test for public-3
│ └── public-4.spec.ts # Test for public-4
├── package.json
└── README.md
If you're not interested in the project's layout, skip to the TODOs section.
-
Login Page:
The login page features both login and register panels with a shared layout found in
Layout.tsx
. Tabs at the top change based on the path name. The layout includes fields for username, password, and confirm password. The confirm password field is hidden in the login panel, so you should remove itsrequired
attribute. At the page's bottom is a submit button. Depending on the active panel, there's a link to switch between login and registration. -
View Page:
The view page displays a post with its title, content, author, and timestamp. Navigation buttons allow users to move between posts. Additionally, there are buttons for upvoting and downvoting. If a user has already upvoted, pressing the downvote button will reverse the upvote and then downvote the post. The page should also support keyboard navigation: the left arrow key takes the user to the previous post, while the right arrow key leads to the next one.
-
Create Page:
The create page allows users to draft a new post. There's a title field, which is mandatory, and a content field that's optional.
-
Settings Page:
The settings page provides users with options to personalize their profile. Upon loading, the current user settings are displayed. Here, users can update their username, bio, gender, and profile picture. As selections are made, the user interface reflects these changes in real-time. Notably, when a new profile picture is uploaded, it immediately replaces the current display. If no image is chosen, the existing profile picture remains. If the user never set a picture, the space stays blank.
- The backend structure closely resembles that of the Trello clone app. If you're familiar with its backend code, this should be straightforward. The
models
folder manages both users and posts, while thecontrollers
folder handles requests from the frontend. An additionalauth
controller specifically manages login and registration. Theroutes
folder oversees all routing, including a uniqueinit
route to initialize the database during tests.
We've laid out four main tasks for you, each containing a series of subtasks. The main tasks are independent of each other. Therefore, if you find yourself stuck on a particular task, feel free to jump to the next. However, some subtasks may rely on the completion of previous ones. For instance, finishing subtask 1.4 is a prerequisite for 1.5. We've indicated which files you'll need to modify for each subtask, arranged in the recommended order of completion. To locate relevant tasks in your editor, simply search for TODO #.#
.
-
1.1 Title and Login Page Title (5%)
-
1.2 Redirect to Login Page (5%)
-
1.3 Route Configuration for Login and Register Pages (8%)
-
1.4 Login Fails for Unregistered Users (8%)
-
1.5 Ensure User Registration Functions Properly (8%)
Requirements
- Render author
- Render posted date
- Render title
- Render content
Hints
- 2.1.1: Pass correct arguments to
PostCard
component c.f.PostContext
- 2.1.2: Arguments
post
should be modified
Requirements
- Navigate to next post when “Next Button” is clicked.
- Navigate to previous post when “Prev Button” is clicked.
- Navigate to the first post when “Next Button” is clicked at the last post.
- Navigate to the last post when “Prev Button” is clicked at the first post.
Hints
- 2.2.1: Link page index to React state
- 2.2.2: Pass correct arguments to
ViewFooter
component - 2.2.3: Arguments
nextClickHandler
andprevClickHandler
should be modified - 2.2.4: Finish next and prev click handler
- 2.2.5: Refer to
PostContext
for more clue
Requirements
- Navigate to next post when “Right Arrow Key” is pressed.
- Navigate to previous post when “Left Arrow Key” is pressed.
- Navigate to the first post when “Right Arrow Key” is pressed at the last post.
- Navigate to the last post when “Left Arrow Key” is pressed at the first post.
Requirements
- Vote icon will be filled once clicked.
Hints
- 2.4.1: Determine if the current user has upvoted or downvoted the selected post
- 2.4.2: Refer to the schema of
Post
for more clue - 2.4.3: Call some exported function from
PostContext
- 2.4.4: Pass correct arguments to
ViewFooter
component - 2.4.5: Arguments
downvoteClickHandler
,upvoteClickHandler
,hasUpvoted
,hasDownvoted
andtotalVotes
should be Modified
Requirements
- React state
title
reflects changes in the filename input field. - React state
code
reflects changes in the editor. - Post will be created and stored in database once the “Post Button” is clicked.
Hints
- 3.1.1: Argument
onChange
andvalue
ofInput
component should be modified - 3.1.2: Argument
onChange
ofEditor
component should be modified
Requirements
- Render a list of posts that the logged in user has posted.
- Navigate to corresponding post once any file tab is clicked.
Hints
- 3.2.1: Use
getPostIndicesByUserId
fromPostContext
to fetch logged in user's post indices - 3.2.2: Get post data with
getPostByIndex
fromPostContext
- 3.2.3: Display post title here
Requirements
- Navigate to corresponding post and allow edit once any file tab is clicked.
- Changes will be saved once the “Post Button” is clicked.
Hints
- 3.3.1: Use the correct API from
PostService
to update DB - 3.3.2: Use React hook to update frontend
Hint: If tasks 1.4 and 1.5 fail but succeeded previously, consider clearing your database and restarting your backend server.
-
4.1 Render User Information - bio (4%)
-
4.2 Render User Information - gender (8%)
-
4.3 Render User Information - profile picture 1 (6%)
-
4.4 Update User Information (6%)
-
4.5 Render User Information - profile picture 2 (5%)
-
💡 **ChatGPT Lesson**
Playwright is an open-source automation framework for web browsers like Chrome, Firefox, and WebKit. It allows developers to automate interactions with web pages, such as filling out forms, clicking buttons, and navigating between pages. Playwright provides a simple and powerful API for browser automation and is often used for web testing, web scraping, and other web automation tasks. It supports multiple programming languages and offers cross-browser compatibility.
Here's a basic example of using Playwright in JavaScript to open a webpage, fill out a form, and capture a screenshot:
const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch(); const page = await browser.newPage(); await page.goto('<https://example.com>'); // Fill out a form await page.fill('input[name="username"]', 'yourusername'); await page.fill('input[name="password"]', 'yourpassword'); await page.click('input[type="submit"]'); // Capture a screenshot await page.screenshot({ path: 'example.png' }); await browser.close(); })();
In this example, Playwright is used to open a Chromium browser, navigate to "https://example.com", fill out a username and password field, submit the form, and then capture a screenshot of the resulting page.
-
💡 **ChatGPT Lesson**
Template literals in JavaScript are a way to create strings that can include variables and expressions within them, using backticks (``) as delimiters. They allow for more readable and convenient string formatting. Here's a brief example:
const name = "John"; const age = 30; const message = `My name is ${name} and I am ${age} years old.`; console.log(message);
In this example, the
${}
syntax within the backticks allows you to insert the values ofname
andage
variables into the string, creating a dynamic message. -
💡 **ChatGPT Lesson**
React Router DOM is a JavaScript library for handling routing in React applications. It allows you to create and manage navigation within your single-page React web application (SPA). You can define different routes and render components based on the URL, enabling a seamless user experience. React Router DOM provides components like
BrowserRouter
,Route
, andLink
for routing functionality. -
💡 **ChatGPT Lesson**[useForm
Hook](https://react-hook-form.com/docs/useform)The
useForm
hook is not a standard React hook, but it might refer to a custom hook or library like "react-hook-form" or "Formik" used for managing forms in React. These libraries simplify form handling by providing hooks and utilities to manage form state, validation, and submission. They make it easier to interact with form elements, capture user input, and manage the form's state in a more organized and efficient manner.