diff --git a/apps/backend/src/db.js b/apps/backend/src/db.js index d335840..c74ade6 100644 --- a/apps/backend/src/db.js +++ b/apps/backend/src/db.js @@ -10,8 +10,8 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); //const mongoUrl = `mongodb+srv://${uname}:${pw}@cluster0.oypxwnq.mongodb.net/?retryWrites=true&w=majority`; -//const mongoUrl = "mongodb://127.0.0.1:27017/counting"; -const mongoUrl = process.env.MONGODB_URL; +const mongoUrl = "mongodb://127.0.0.1:27017/counting"; +//const mongoUrl = process.env.MONGODB_URL; async function connectToDb(){ try { diff --git a/apps/frontend/jest.config.ts b/apps/frontend/jest.config.ts index 7ef67f7..2a8d9ca 100644 --- a/apps/frontend/jest.config.ts +++ b/apps/frontend/jest.config.ts @@ -6,5 +6,6 @@ export default { '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/react/babel'] }] }, moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: 'test-output/jest/coverage' + coverageDirectory: 'test-output/jest/coverage', + passWithNoTests: true // added this line to pass the CI test run }; diff --git a/apps/frontend/src/components/animationNoCircleDraw.jsx b/apps/frontend/src/components/animationNoCircleDraw.jsx index d3a89f6..61eff8b 100644 --- a/apps/frontend/src/components/animationNoCircleDraw.jsx +++ b/apps/frontend/src/components/animationNoCircleDraw.jsx @@ -4,7 +4,7 @@ import '../styles/animation.css'; // AnimationNoCircle component to handle animation logic without circleDraw function function AnimationNoCircle({ onAnimationFinish }) { const [percent, setPercent] = useState(0); // track progress - const [animationFinished, setAnimationFinished] = useState(false); // track if animation finished + //const [animationFinished, setAnimationFinished] = useState(false); // track if animation finished // useEffect hook to handle animation progress useEffect(() => { diff --git a/apps/frontend/src/components/circleDraw.jsx b/apps/frontend/src/components/circleDraw.jsx index 08ea549..a188efd 100644 --- a/apps/frontend/src/components/circleDraw.jsx +++ b/apps/frontend/src/components/circleDraw.jsx @@ -43,21 +43,45 @@ function Canvas({ onAnimationFinish }) { const isCircle = () => { - if (circlePath.length < 10) { + if (circlePath.length < 20) { console.log('Too few points to form a circle'); return false; // Not enough points to form a circle } - const start = circlePath[0]; + //const start = circlePath[0]; const end = circlePath[circlePath.length - 1]; - - // Check if the start and end points are close enough - const distance = Math.sqrt((start.x - end.x) ** 2 + (start.y - end.y) ** 2); - console.log('Start-End Distance:', distance); - if (distance > 20) { // Adjust the threshold as needed - console.log('Start and end points are too far apart'); - return false; + let isClosed = false; + + // Define how many of the initial points to check against. + // Let's check against the first 25% of the path, up to a max of 30 points. + const checkZoneLength = Math.min(40, Math.floor(circlePath.length * 0.5)); + + // Check if the path closes on itself + // Loop through the first few points of the path and see if the + // endpoint is close to any of them. + for (let i = 0; i < checkZoneLength; i++) { + const pointNearStart = circlePath[i]; + const distance = Math.sqrt((pointNearStart.x - end.x) ** 2 + (pointNearStart.y - end.y) ** 2); + + if (distance < 25) { // Threshold for considering the loop "closed" + isClosed = true; + console.log('Path is considered closed.'); + break; // Exit the loop once we find a close point + } + } + + if (!isClosed) { + console.log('Start and end points are too far apart'); + return false; } + + // // Check if the start and end points are close enough + // const distance = Math.sqrt((start.x - end.x) ** 2 + (start.y - end.y) ** 2); + // console.log('Start-End Distance:', distance); + // if (distance > 20) { // Adjust the threshold as needed + // console.log('Start and end points are too far apart'); + // return false; + // } // Calculate the center of the path const centerX = (Math.min(...circlePath.map((p) => p.x)) + Math.max(...circlePath.map((p) => p.x))) / 2; diff --git a/apps/frontend/src/components/profile.jsx b/apps/frontend/src/components/profile.jsx index b8e8872..61008cd 100644 --- a/apps/frontend/src/components/profile.jsx +++ b/apps/frontend/src/components/profile.jsx @@ -1,5 +1,5 @@ import React from "react"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import '../styles/profile.css'; import profileicon from '../assests/profileicon.png'; diff --git a/apps/frontend/src/data/practiceData.js b/apps/frontend/src/data/practiceData.js index ba9e789..e97caeb 100644 --- a/apps/frontend/src/data/practiceData.js +++ b/apps/frontend/src/data/practiceData.js @@ -327,7 +327,7 @@ animals: [ top: "70%", left: "5%", height: "150px" - },, + }, { id: 8, name:"horse8", @@ -402,7 +402,7 @@ animals: [ top: "60%", left: "35%", height: "150px" - },, + }, { id: 8, name:"hippo8", @@ -469,7 +469,7 @@ animals: [ top: "60%", left: "70%", height: "250px" - },, + }, { id: 8, name:"octopus8", diff --git a/apps/frontend/src/helpers/SaveAnswers.js b/apps/frontend/src/helpers/SaveAnswers.js index 8b228f0..7c57c18 100644 --- a/apps/frontend/src/helpers/SaveAnswers.js +++ b/apps/frontend/src/helpers/SaveAnswers.js @@ -3,7 +3,10 @@ export async function saveAnswers(pageType) { try { let answersKey; - let answersData; + const answersData = { + answers: [], + pageType: '' + }; switch (pageType) { case 'baselineTraining': @@ -44,10 +47,12 @@ export async function saveAnswers(pageType) { return; } - answersData = { - answers : answers, - pageType: answersKey - }; + // answersData = { + // answers : answers, + // pageType: answersKey + // }; + answersData.answers = answers; + answersData.pageType = answersKey; console.log("answerData:", answersData) diff --git a/apps/frontend/src/helpers/trayGenerators.js b/apps/frontend/src/helpers/trayGenerators.js index 0f2b4cd..674282e 100644 --- a/apps/frontend/src/helpers/trayGenerators.js +++ b/apps/frontend/src/helpers/trayGenerators.js @@ -84,7 +84,8 @@ const cookiePositions = { for (let i = 0; i < numCookies; i++) { let newCookie; - let tries = 0, maxTries = 100; + let tries = 0; + const maxTries = 100; while (tries < maxTries) { newCookie = { diff --git a/apps/frontend/src/pages/TouchTrainingPage.jsx b/apps/frontend/src/pages/TouchTrainingPage.jsx index 76e79e1..40e1b56 100644 --- a/apps/frontend/src/pages/TouchTrainingPage.jsx +++ b/apps/frontend/src/pages/TouchTrainingPage.jsx @@ -93,7 +93,7 @@ const TouchTrainingPage = () => { speakUtterance(); spokenRef.current = true; } - }, [currentPage]); + }, [currentPage, speakUtterance]); useEffect(() => { if(!once.current){ @@ -183,6 +183,10 @@ const TouchTrainingPage = () => { allCookies.forEach(cookie => { cookie.style.pointerEvents = 'auto'; }); + const instruction = `Great job! Now draw a circle with your finger by following the yellow line.`; + setTimeout(() => { + textToSpeech(instruction); + }, 3000); } } else { console.error("SpeechSynthesis API is not supported in this browser."); @@ -242,6 +246,22 @@ const TouchTrainingPage = () => { const handleTrayClick = (trayType) => { setSelectedTray(trayType); + // if the correct tray has been clicked + if (trayType === "greenTray" && sectionTrainData.pages[currentPage].greenTray[0].biscuits.length === sectionTrainData.pages[currentPage].cookies.length) { + textToSpeech("Green is correct, Good job!"); + } + else if (trayType === "purpleTray" && sectionTrainData.pages[currentPage].purpleTray[0].biscuits.length === sectionTrainData.pages[currentPage].cookies.length){ + textToSpeech("Purple is correct, Well done!"); + } + // if the wrong tray has been clicked + else if (trayType === "greenTray" && sectionTrainData.pages[currentPage].greenTray[0].biscuits.length !== sectionTrainData.pages[currentPage].cookies.length) { + const explanation = `No, ${trayType} has ${sectionTrainData.pages[currentPage].greenTray[0].biscuits.length} cookies. Try again!`; + textToSpeech(explanation); + } + else{ + const explanation = `Wrong answer, ${trayType} has ${sectionTrainData.pages[currentPage].purpleTray[0].biscuits.length} cookies. Try again!`; + textToSpeech(explanation); + } storeAnswer(currentPage, trayType); }; @@ -300,6 +320,7 @@ const TouchTrainingPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -331,6 +352,7 @@ const TouchTrainingPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, diff --git a/apps/frontend/src/pages/animationTrainingPage.jsx b/apps/frontend/src/pages/animationTrainingPage.jsx index d9357d9..956b91c 100644 --- a/apps/frontend/src/pages/animationTrainingPage.jsx +++ b/apps/frontend/src/pages/animationTrainingPage.jsx @@ -245,6 +245,7 @@ const AnimationTrainingPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -275,6 +276,7 @@ const AnimationTrainingPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, diff --git a/apps/frontend/src/pages/animationpage.jsx b/apps/frontend/src/pages/animationpage.jsx index 7b5cf0a..85bdf65 100644 --- a/apps/frontend/src/pages/animationpage.jsx +++ b/apps/frontend/src/pages/animationpage.jsx @@ -91,7 +91,7 @@ const AnimationPage = () => { speakUtterance(); spokenRef.current = true; } - }, [currentPage]); + }, [currentPage, speakUtterance]); useEffect(() => { if (!once.current) { @@ -235,6 +235,7 @@ const AnimationPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -265,6 +266,7 @@ const AnimationPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, diff --git a/apps/frontend/src/pages/basePage.jsx b/apps/frontend/src/pages/basePage.jsx index 615632b..ae5b349 100644 --- a/apps/frontend/src/pages/basePage.jsx +++ b/apps/frontend/src/pages/basePage.jsx @@ -17,7 +17,7 @@ import { textToSpeech } from '../helpers/textToSpeech'; import {handleInteraction, handleNextClickTouchData} from '../helpers/imageTouchData'; import { saveAnswers } from "../helpers/SaveAnswers"; -function basePage() { +function BasePage() { const { baseData, selectedOption } = useAppData(); const { page } = useParams(); const currentPage = parseInt(page); @@ -191,6 +191,7 @@ function basePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -221,6 +222,7 @@ function basePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -279,4 +281,4 @@ function basePage() { ); } -export default basePage; +export default BasePage; diff --git a/apps/frontend/src/pages/basePage2.jsx b/apps/frontend/src/pages/basePage2.jsx index add2d2a..aaa0c55 100644 --- a/apps/frontend/src/pages/basePage2.jsx +++ b/apps/frontend/src/pages/basePage2.jsx @@ -17,7 +17,7 @@ import { textToSpeech } from '../helpers/textToSpeech'; import { handleInteraction, handleNextClickTouchData } from '../helpers/imageTouchData'; import { saveAnswers } from "../helpers/SaveAnswers"; -function BasePage() { +function BasePage2() { const { baseData, selectedOption } = useAppData(); const { page } = useParams(); const currentPage = parseInt(page); @@ -165,6 +165,7 @@ function BasePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -195,6 +196,7 @@ function BasePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -246,4 +248,4 @@ function BasePage() { ); } -export default BasePage; +export default BasePage2; diff --git a/apps/frontend/src/pages/baseTraining.jsx b/apps/frontend/src/pages/baseTraining.jsx index e7e970a..2d0538f 100644 --- a/apps/frontend/src/pages/baseTraining.jsx +++ b/apps/frontend/src/pages/baseTraining.jsx @@ -17,7 +17,7 @@ import { textToSpeech } from '../helpers/textToSpeech'; import {handleInteraction, handleNextClickTraining} from '../helpers/imageTouchData'; import { saveAnswers } from "../helpers/SaveAnswers"; -function basePage() { +function BaseTrainingPage() { const { sectionTrainData, selectedOption } = useAppData(); const { page } = useParams(); const currentPage = parseInt(page); @@ -181,6 +181,7 @@ function basePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt={`Biscuit ${biscuit.id}`} style={{ position: "absolute", top: biscuit.top, @@ -211,6 +212,7 @@ function basePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -269,4 +271,4 @@ function basePage() { ); } -export default basePage; +export default BaseTrainingPage; diff --git a/apps/frontend/src/pages/baseTraining2.jsx b/apps/frontend/src/pages/baseTraining2.jsx index 711470d..8896ad6 100644 --- a/apps/frontend/src/pages/baseTraining2.jsx +++ b/apps/frontend/src/pages/baseTraining2.jsx @@ -17,7 +17,7 @@ import { textToSpeech } from '../helpers/textToSpeech'; import { handleInteraction, handleNextClickTraining } from '../helpers/imageTouchData'; import { saveAnswers } from "../helpers/SaveAnswers"; -function BasePage() { +function BaseTraining2() { const { sectionTrainData, selectedOption } = useAppData(); const { page } = useParams(); const currentPage = parseInt(page); @@ -165,6 +165,7 @@ function BasePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt={`Biscuit ${biscuit.id}`} style={{ position: "absolute", top: biscuit.top, @@ -195,6 +196,7 @@ function BasePage() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -250,4 +252,4 @@ function BasePage() { ); } -export default BasePage; +export default BaseTraining2; diff --git a/apps/frontend/src/pages/gamepage.jsx b/apps/frontend/src/pages/gamepage.jsx index 1d82152..8d4032e 100644 --- a/apps/frontend/src/pages/gamepage.jsx +++ b/apps/frontend/src/pages/gamepage.jsx @@ -19,7 +19,7 @@ import {handleInteraction, handleNextClickTouchData} from '../helpers/imageTouch import { saveAnswers } from "../helpers/SaveAnswers"; -const gamePage = () => { +const GamePage = () => { const { Data, audioData, selectedOption } = useAppData(); const { page } = useParams(); const currentPage = parseInt(page); @@ -54,7 +54,7 @@ const gamePage = () => { const clickedCookies = useRef(new Set()); // state to track mouse moevement - const [isDrawing, setIsDrawing] = useState(false); + //const [isDrawing, setIsDrawing] = useState(false); const handleAnimationFinish = () => { @@ -285,8 +285,7 @@ const gamePage = () => { setstartAnimation(true); const instruction = `Great job! Now draw a circle with your finger by following the yellow line.`; setTimeout(() => { - textToSpeech(instruction, () => { - }) + textToSpeech(instruction); }, 1000); } return newCount; @@ -354,6 +353,7 @@ const gamePage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -385,6 +385,7 @@ const gamePage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -414,4 +415,4 @@ const gamePage = () => { ); }; -export default gamePage; +export default GamePage; diff --git a/apps/frontend/src/pages/home.jsx b/apps/frontend/src/pages/home.jsx index 5f7c93e..deccc86 100644 --- a/apps/frontend/src/pages/home.jsx +++ b/apps/frontend/src/pages/home.jsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import axios from "axios"; import "../styles/home.css"; -import image3 from "../assests/image3.jpg"; +//import image3 from "../assests/image3.jpg"; import "bootstrap/dist/css/bootstrap.css"; import Profile from "../components/profile.jsx"; import AccountCircleIcon from "@mui/icons-material/AccountCircle"; @@ -29,7 +29,7 @@ function Home() { }); setuserData(response.data.data); console.log(response.data.data); - if (response.data.data == "token expired") { + if (response.data.data === "token expired") { // == was used here alert("Login again"); window.localStorage.clear(); window.location.href = "/"; diff --git a/apps/frontend/src/pages/prevGamePage 2.jsx b/apps/frontend/src/pages/prevGamePage 2.jsx index 72cdc4a..a32ec17 100644 --- a/apps/frontend/src/pages/prevGamePage 2.jsx +++ b/apps/frontend/src/pages/prevGamePage 2.jsx @@ -292,6 +292,7 @@ const PrevGamePage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -322,6 +323,7 @@ const PrevGamePage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, diff --git a/apps/frontend/src/pages/prevGamePage.jsx b/apps/frontend/src/pages/prevGamePage.jsx index 19c32d3..c4099c5 100644 --- a/apps/frontend/src/pages/prevGamePage.jsx +++ b/apps/frontend/src/pages/prevGamePage.jsx @@ -292,6 +292,7 @@ const PrevGamePage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -322,6 +323,7 @@ const PrevGamePage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, diff --git a/apps/frontend/src/pages/signupPage.jsx b/apps/frontend/src/pages/signupPage.jsx index 0d83524..0122cb8 100644 --- a/apps/frontend/src/pages/signupPage.jsx +++ b/apps/frontend/src/pages/signupPage.jsx @@ -16,7 +16,7 @@ function SignupPage() { const response = await axios.post(`/register`,{ name: name, }).then((res) =>{ - if(res.status == 200){ + if(res.status === 200){ // == was used here window.localStorage.setItem("token", res.data.data); window.localStorage.setItem("loggedIn", true); } diff --git a/apps/frontend/src/pages/trainPage.jsx b/apps/frontend/src/pages/trainPage.jsx index c51b906..ac4fece 100644 --- a/apps/frontend/src/pages/trainPage.jsx +++ b/apps/frontend/src/pages/trainPage.jsx @@ -12,7 +12,7 @@ import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'; import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; import DialogBox from "../components/dialogBox"; import HomeRoundedIcon from '@mui/icons-material/HomeRounded'; -import { useSound } from '../helpers/SoundContext'; +//import { useSound } from '../helpers/SoundContext'; import { textToSpeech } from '../helpers/textToSpeech'; import { handleInteraction, handleNextClickTraining } from '../helpers/imageTouchData'; import { saveAnswers } from "../helpers/SaveAnswers"; @@ -34,12 +34,12 @@ const TrainingPage = () => { const [showTray2, setShowTray2] = useState(false); const once = useRef(false); const spokenRef = useRef(false); - const { soundEnabled } = useSound(); + //const { soundEnabled } = useSound(); - const trayW = 300, trayH = 400; + //const trayW = 300, trayH = 400; const cookieW = 60, cookieH = 60; - const padding = 20; - const minGap = cookieW * 1.1; + // const padding = 20; + // const minGap = cookieW * 1.1; const navigate = useNavigate(); @@ -189,6 +189,7 @@ const TrainingPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -221,6 +222,7 @@ const TrainingPage = () => { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, diff --git a/apps/frontend/src/pages/training.jsx b/apps/frontend/src/pages/training.jsx index b9b5dd6..b45ce87 100644 --- a/apps/frontend/src/pages/training.jsx +++ b/apps/frontend/src/pages/training.jsx @@ -126,6 +126,7 @@ function Training() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, @@ -152,6 +153,7 @@ function Training() { src={biscuit.img} id={biscuit.id} className="biscuits" + alt="" style={{ position: "absolute", top: biscuit.top, diff --git a/apps/frontend/src/styles/gamePage.css b/apps/frontend/src/styles/gamePage.css index e9a7fe8..bd7b56e 100644 --- a/apps/frontend/src/styles/gamePage.css +++ b/apps/frontend/src/styles/gamePage.css @@ -61,8 +61,8 @@ .circle { border: 4px solid yellow; border-radius: 50%; - box-shadow: 0 0 10px 5px rgba(255, 255, 0, 0.5); - animation: glow 2s infinite alternate; + box-shadow: 0 0 10px 0px rgba(255, 255, 0, 0.9); + animation: border-glow 2s infinite alternate; animation-iteration-count: infinite; cursor: pointer; } diff --git a/deploy.sh b/deploy.sh index 3370284..a26c4cd 100755 --- a/deploy.sh +++ b/deploy.sh @@ -3,43 +3,52 @@ # Automated deployment script # This script builds, copies frontend to backend, cleans server, and deploys -SERVER_IP="count-new.cs.vt.edu" +SERVER_IP="128.173.237.58" SERVER_USER="sangwonlee" APP_DIR="counting-app" echo "๐Ÿš€ Starting automated deployment..." +echo "" # Build both frontend and backend echo "๐Ÿ“ฆ Building frontend and backend..." npx nx build frontend npx nx build backend +echo "" # Copy frontend build into backend dist echo "๐Ÿ“ Copying frontend build into backend dist..." cp -r dist/apps/frontend/* apps/backend/dist/ - echo "โœ… Build complete! Frontend files are now in backend dist folder." +echo "" # Clean server app directory echo "๐Ÿงน Cleaning server app directory..." ssh ${SERVER_USER}@${SERVER_IP} "rm -rf ${APP_DIR}/*" +echo "" # Copy new files to server echo "๐Ÿ“ค Copying new files to server..." scp -r apps/backend/dist/* ${SERVER_USER}@${SERVER_IP}:${APP_DIR}/ +echo "" # Install dependencies on server echo "๐Ÿ“ฆ Installing dependencies on server..." ssh ${SERVER_USER}@${SERVER_IP} "cd ${APP_DIR} && npm install --production && npm install node-fetch@2" +echo "" echo "โœ… Deployment complete!" echo "" -echo "๐Ÿ“ Next steps:" +echo "๐Ÿ“ Now go update the server:" echo " 1. SSH into server:" echo " ssh ${SERVER_USER}@${SERVER_IP}" echo " 2. Go to the app directory:" echo " cd ${APP_DIR}" -echo " 3. Start the server:" -echo " node main.js" -echo " 4. Go to the website:" -echo " http://${SERVER_IP}:8001" \ No newline at end of file +echo " 3. Find the process id of the server (do not forget the \" before node main.js and \" after it):" +echo " ps aux | grep \"node main.js\"" +echo " 4. Kill the process:" +echo " kill -9 " +echo " 5. Start new process:" +echo " nohup node main.js > app.log 2>&1 &" +echo " 6. Go to the website:" +echo " https://count.cs.vt.edu" \ No newline at end of file