Skip to content
Snippets Groups Projects
Commit 198d8065 authored by danieldeng2's avatar danieldeng2
Browse files

Merge branch 'master' of gitlab.doc.ic.ac.uk:edtech/scientia

parents 935ca41c af2f9908
No related branches found
No related tags found
No related merge requests found
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts ## Setup
First, run `yarn install` to install the node modules used for the frontend.
In order for the API links to work, the following repository branches need to be cloned and run separately:
### 1. materials@scientia-integration
```shell
# Clone the repository and checkout to the relevant branch
git clone https://gitlab.doc.ic.ac.uk/edtech/materials.git
git checkout scientia-integration
# Setup and run the development server on port 5000
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip && pip install -r requirements.txt
export FLASK_ENV=development
export FLASK_APP=materials
flask create_all
flask populate -r materials/mocks/resources.json
flask run
```
## To run
In the project directory, you can run: In the project directory, you can run:
......
...@@ -29,7 +29,7 @@ const ModuleList: React.FC = () => { ...@@ -29,7 +29,7 @@ const ModuleList: React.FC = () => {
}, },
{ {
title: "Discrete Mathematics", title: "Discrete Mathematics",
code: "CO142", code: "142",
image: discreteIllustration, image: discreteIllustration,
terms: [Term.AUTUMN], terms: [Term.AUTUMN],
progressStatus: ProgressStatus.IN_PROGRESS, progressStatus: ProgressStatus.IN_PROGRESS,
......
import React from "react"; import React, { useEffect, useState } from "react";
import styles from "./style.module.scss"; import styles from "./style.module.scss";
import classNames from "classnames";
import { request } from "../../../utils/api"
import { api } from "../../../constants/routes"
import MyBreadcrumbs from "components/atoms/MyBreadcrumbs"; import MyBreadcrumbs from "components/atoms/MyBreadcrumbs";
import InputGroup from "react-bootstrap/InputGroup"; import InputGroup from "react-bootstrap/InputGroup";
......
...@@ -51,4 +51,4 @@ ...@@ -51,4 +51,4 @@
font-weight: 500 !important; font-weight: 500 !important;
color: $white !important; color: $white !important;
border-color: $black; border-color: $black;
} }
\ No newline at end of file
...@@ -70,9 +70,7 @@ const StandardView: React.FC<StandardViewProps> = ({ ...@@ -70,9 +70,7 @@ const StandardView: React.FC<StandardViewProps> = ({
<ModuleResources /> <ModuleResources />
</Route> </Route>
<Route path="/modules/:id/feedback"> <Route path="/modules/:id/feedback" component={ModuleFeedback} />
<ModuleFeedback />
</Route>
<Route path="/timeline"> <Route path="/timeline">
<ExamplePage name="Timeline" /> <ExamplePage name="Timeline" />
......
const authConstants = {
ACCESS_TOKEN_HEADER: () => `Bearer ${sessionStorage.getItem("currentUser")}`,
ACCESS_TOKEN: "currentUser",
USER_INFO: "userInfo"
};
export default authConstants;
\ No newline at end of file
const dev = {
MATERIALS_URL: "http://localhost:5000"
}
const prod = {
MATERIALS_URL: "https://materials.doc.ic.ac.uk",
}
const config = process.env.NODE_ENV === "development" ? dev : prod;
export const api = {
MATERIALS_LOGIN: config.MATERIALS_URL + "/auth/login",
MATERIALS_COURSES: config.MATERIALS_URL + "/courses/1819",
MATERIALS_RESOURCES: config.MATERIALS_URL + "/resources"
}
\ No newline at end of file
import authConstants from "../constants/auth";
import authenticationService from "../utils/auth";
import { api } from "../constants/routes"
interface RequestOptions {
[key: string]: any
}
// API calling interface. onSuccess and onError are functions that take in data
// and error parameters respectively. Body is process as query parameters if
// method is GET
// Note: will trigger CORS OPTIONS preflight due to the Authorization header
export async function request(url: string, method: string, onSuccess: any, onError: any, body?: any) {
if (!authenticationService.userIsLoggedIn()) {
// TODO: Credentials should be handled elsewhere
// TODO: Specific endpoint login route should be passed in
await authenticationService.login("abc123", "a", api.MATERIALS_LOGIN);
}
var options: RequestOptions = {
method: method,
mode: "cors",
headers: {
"Authorization": authConstants.ACCESS_TOKEN_HEADER(),
"Access-Control-Allow-Origin": "*",
},
};
if (method === "GET") {
url = url + "?" + new URLSearchParams(body);
} else {
options.body = JSON.stringify(body);
}
return fetch(url, options)
.then((result) => {
onSuccess(result);
}, (error) => {
onError(error);
})
}
import authConstants from "../constants/auth";
function storeDataInStorage(data: { access_token: string; user_info: any; }) {
sessionStorage.setItem(authConstants.ACCESS_TOKEN, data.access_token);
sessionStorage.setItem(
authConstants.USER_INFO,
JSON.stringify(data.user_info)
);
}
function removeDataFromStorage() {
sessionStorage.removeItem(authConstants.ACCESS_TOKEN);
sessionStorage.removeItem(authConstants.USER_INFO);
}
function getUserInfo() {
const info = sessionStorage.getItem(authConstants.USER_INFO)
if (info) {
return JSON.parse(info)
}
return {}
}
async function login(username: string, password: string, login_url: string) {
const response = await fetch(login_url, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: JSON.stringify({ username, password })
});
if (response.ok) {
const data = await response.json();
storeDataInStorage(data);
return true;
}
return false;
}
const logout = () => removeDataFromStorage();
const userIsLoggedIn = () => {
return sessionStorage.getItem(authConstants.ACCESS_TOKEN) !== null;
};
export default {
login,
logout,
userIsLoggedIn,
getUserInfo
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment