diff --git a/backend/Dockerfile b/backend/Dockerfile index 300acaa..7085901 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -5,7 +5,7 @@ RUN python -m venv venv COPY ./requirements.txt /code/requirements.txt RUN . venv/bin/activate RUN python -m pip install -r /code/requirements.txt -COPY venv /code/venv +RUN cp -r venv /code/venv WORKDIR /code COPY app app diff --git a/backend/main.py b/backend/main.py index 8a8832d..df2e211 100644 --- a/backend/main.py +++ b/backend/main.py @@ -7,7 +7,11 @@ from app.models import Assignment, Course, User from flask_cors import CORS app = create_app() -CORS(app, supports_credentials=True, resources={r"/.*": {"origins": r".*localhost.*"}}) +CORS( + app, + supports_credentials=True, + resources={r"/.*": {"origins": [r".*localhost.*", r".*jagrajaulakh.com.*"]}}, +) @app.shell_context_processor diff --git a/docker-compose.yml b/docker-compose.yml index e158f1c..e632dc8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,12 +3,31 @@ services: frontend: image: comp2707-frontend build: frontend/ + depends_on: + - backend container_name: comp2707-frontend ports: - 8080:8080 backend: image: comp2707-backend build: backend/ + depends_on: + - db container_name: comp2707-backend + environment: + - DATABASE_URL=mysql://root:mama@db/2707 ports: - - 5000:5000 + - 5001:5000 + db: + image: mariadb:latest + environment: + - MARIADB_ROOT_PASSWORD=mama + - MARIADB_DATABASE=2707 + volumes: + - db-volume:/var/lib/mysql + ports: + - 3406:3306 + +volumes: + db-volume: + driver: local diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..1a931bb --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,2 @@ +.env.local +node_modules/ diff --git a/frontend/.env b/frontend/.env new file mode 100644 index 0000000..30ee813 --- /dev/null +++ b/frontend/.env @@ -0,0 +1 @@ +REACT_APP_BACKEND_URL=http://localhost:5000 diff --git a/frontend/.env.production b/frontend/.env.production new file mode 100644 index 0000000..c0561c8 --- /dev/null +++ b/frontend/.env.production @@ -0,0 +1 @@ +REACT_APP_BACKEND_URL=http://be.2707.jagrajaulakh.com:5001 diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 8b97a70..5c555e8 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -8,6 +8,7 @@ RUN mkdir /code && cp -a /tmp/node_modules /code/ # Copy all the source code WORKDIR /code COPY ./ /code +COPY .env.production .env # Build the project RUN ["npm", "run", "build"] diff --git a/frontend/package-lock.json b/frontend/package-lock.json index fe8ee65..690446a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,6 +12,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "bootstrap": "^5.2.3", + "dotenv": "^16.0.3", "react": "^18.2.0", "react-bootstrap": "^2.7.2", "react-dom": "^18.2.0", @@ -6868,11 +6869,11 @@ } }, "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/dotenv-expand": { @@ -14577,6 +14578,14 @@ } } }, + "node_modules/react-scripts/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -22349,9 +22358,9 @@ } }, "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" }, "dotenv-expand": { "version": "5.1.0", @@ -27743,6 +27752,13 @@ "webpack-dev-server": "^4.6.0", "webpack-manifest-plugin": "^4.0.2", "workbox-webpack-plugin": "^6.4.1" + }, + "dependencies": { + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + } } }, "react-transition-group": { diff --git a/frontend/package.json b/frontend/package.json index 3b61be1..e2a3301 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,6 +7,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "bootstrap": "^5.2.3", + "dotenv": "^16.0.3", "react": "^18.2.0", "react-bootstrap": "^2.7.2", "react-dom": "^18.2.0", diff --git a/frontend/serve.js b/frontend/serve.js index e0feec6..1843314 100644 --- a/frontend/serve.js +++ b/frontend/serve.js @@ -1,6 +1,9 @@ const express = require("express"); const path = require("path"); const app = express(); +const dotenv = require('dotenv'); +dotenv.config() +console.log(process.env); app.use("/*", (req, res, next) => { now = new Date(); diff --git a/frontend/src/components/CoursesWidget.jsx b/frontend/src/components/CoursesWidget.jsx index 02fa5d2..02e0524 100644 --- a/frontend/src/components/CoursesWidget.jsx +++ b/frontend/src/components/CoursesWidget.jsx @@ -12,7 +12,7 @@ const CoursesWidget = ({ className = "" }) => { if (!currentUser.id) { return; } - makeRequest({ url: `http://localhost:5000/user/${currentUser.id}/courses` }) + makeRequest({ endpoint: `user/${currentUser.id}/courses` }) .then((resp) => resp.json()) .then((data) => { setCourseData(data.courses); diff --git a/frontend/src/pages/CoursePage.jsx b/frontend/src/pages/CoursePage.jsx index ac62920..4615e30 100644 --- a/frontend/src/pages/CoursePage.jsx +++ b/frontend/src/pages/CoursePage.jsx @@ -7,7 +7,7 @@ const CoursePage = ({ id }) => { const [courseData, setCourseData] = useState({}); useEffect(() => { - makeRequest({ url: `http://localhost:5000/course/${id}` }) + makeRequest({ endpoint: `course/${id}` }) .then((resp) => resp.json()) .then((data) => { setCourseData(data); diff --git a/frontend/src/pages/ManagePage.jsx b/frontend/src/pages/ManagePage.jsx index 469458b..4ee573b 100644 --- a/frontend/src/pages/ManagePage.jsx +++ b/frontend/src/pages/ManagePage.jsx @@ -11,7 +11,7 @@ const ManagePage = () => { useEffect(() => { makeRequest({ - url: `http://localhost:5000/user/${currentUser.id}/courses`, + endpoint: `user/${currentUser.id}/courses`, method: "GET", }) .then((req) => req.json()) diff --git a/frontend/src/pages/ManageStudentsPage.jsx b/frontend/src/pages/ManageStudentsPage.jsx index 2da86f2..11fec09 100644 --- a/frontend/src/pages/ManageStudentsPage.jsx +++ b/frontend/src/pages/ManageStudentsPage.jsx @@ -9,7 +9,7 @@ const ManageStutentsPage = ({ cid }) => { const submitStudentForm = async (username) => { await makeRequest({ - url: `http://localhost:5000/user/${username}/enroll/${cid}`, + endpoint: `user/${username}/enroll/${cid}`, method: "POST", }); window.location.reload(); @@ -48,7 +48,7 @@ const ManageStutentsPage = ({ cid }) => { }; useEffect(() => { makeRequest({ - url: `http://localhost:5000/course/${cid}/students`, + endpoint: `course/${cid}/students`, method: "GET", }) .then((req) => req.json()) @@ -62,7 +62,7 @@ const ManageStutentsPage = ({ cid }) => { const sendUnenrollRequest = (uid) => { makeRequest({ - url: `http://localhost:5000/user/${uid}/enroll/${cid}`, + endpoint: `user/${uid}/enroll/${cid}`, method: "DELETE", }).then((resp) => { window.location.reload(); diff --git a/frontend/src/pages/RegisterPage.jsx b/frontend/src/pages/RegisterPage.jsx index 83cec48..af2ca48 100644 --- a/frontend/src/pages/RegisterPage.jsx +++ b/frontend/src/pages/RegisterPage.jsx @@ -17,7 +17,7 @@ const RegisterPage = () => { const sendRegisterRequest = (e) => { e?.preventDefault(); makeRequest({ - url: "http://localhost:5000/register", + endpoint: "register", method: "POST", body: { role, diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts index a8d050e..58e5906 100644 --- a/frontend/src/utils.ts +++ b/frontend/src/utils.ts @@ -1,4 +1,6 @@ -const makeRequest = ({ url, method, body = null }): Promise => { +const { REACT_APP_BACKEND_URL } = process.env; + +const makeRequest = ({ endpoint, method, body = null }): Promise => { const req: RequestInit = { method: method, credentials: "include", @@ -8,7 +10,7 @@ const makeRequest = ({ url, method, body = null }): Promise => { if (body) { req["body"] = JSON.stringify(body); } - return fetch(url, req); + return fetch(`${REACT_APP_BACKEND_URL}/${endpoint}`, req); }; const sendLoginRequest = async ( @@ -17,7 +19,7 @@ const sendLoginRequest = async ( ): Promise => { const p: Promise = new Promise(async (res) => { await makeRequest({ - url: "http://localhost:5000/login", + endpoint: "login", method: "POST", body: { username, password }, }) @@ -36,7 +38,7 @@ const sendLoginRequest = async ( const sendLogoutRequest = async (): Promise => { const p: Promise = new Promise(async (res) => { await makeRequest({ - url: "http://localhost:5000/logout", + endpoint: "logout", method: "POST", }) .then((resp) => resp.json())