(
+const Chapters = (): ReactElement => (
Work in progress
diff --git a/client/src/pages/Home.jsx b/client/src/pages/Home.tsx
similarity index 84%
rename from client/src/pages/Home.jsx
rename to client/src/pages/Home.tsx
index 80eb0d7..3df76c4 100644
--- a/client/src/pages/Home.jsx
+++ b/client/src/pages/Home.tsx
@@ -1,6 +1,5 @@
// @flow
-import React, { useState, useEffect } from 'react';
-import type { Node } from 'react';
+import React, { useState, useEffect, ReactElement } from 'react';
import { useHistory } from 'react-router-dom';
import Page from '../components/layout/Page';
@@ -10,7 +9,7 @@ import { getMembers } from '../utils/apiWrapper';
import '../css/Home.css';
-const Home = (): Node => {
+const Home = (): ReactElement => {
const [members, setMembers] = useState([]);
const history = useHistory();
@@ -19,7 +18,7 @@ const Home = (): Node => {
const getAllMembers = async () => {
const allMembers = await getMembers();
if (allMembers.data) {
- const membersWithLinks = allMembers.data.result.map((member) => {
+ const membersWithLinks = allMembers.data.result.map((member: any) => {
const memberCopy = { ...member };
memberCopy.links = {
github: member.github,
@@ -38,7 +37,7 @@ const Home = (): Node => {
history.push(`/member/${e.data._id}`)}
+ onRowClick={(e: any) => history.push(`/member/${e.data._id}`)}
/>
);
diff --git a/client/src/pages/Login.jsx b/client/src/pages/Login.tsx
similarity index 94%
rename from client/src/pages/Login.jsx
rename to client/src/pages/Login.tsx
index cf1c184..cd3eee2 100644
--- a/client/src/pages/Login.jsx
+++ b/client/src/pages/Login.tsx
@@ -1,6 +1,5 @@
// @flow
-import React from 'react';
-import type { Node } from 'react';
+import React, { ReactElement } from 'react';
import { useLocation } from 'react-router-dom';
import { Button, Header, Icon, Image, Message } from 'semantic-ui-react';
@@ -22,7 +21,7 @@ function useQuery() {
/**
* Displays the login page over everything else
*/
-const Login = (): Node => {
+const Login = (): ReactElement => {
const didLoginFail = useQuery().get(LOGIN_FAILURE_QUERY_PARAM);
return (
@@ -44,7 +43,7 @@ const Login = (): Node => {
'auth/login',
FRONTEND_BASE_URL,
`${FRONTEND_BASE_URL}/login?${LOGIN_FAILURE_QUERY_PARAM}=1`,
- )}
+ ).toString()}
>
Sign in with Google
diff --git a/client/src/pages/NotFound.jsx b/client/src/pages/NotFound.jsx
deleted file mode 100644
index a875aa5..0000000
--- a/client/src/pages/NotFound.jsx
+++ /dev/null
@@ -1,9 +0,0 @@
-// @flow
-import React from 'react';
-import type { Node } from 'react';
-
-import Page from '../components/layout/Page';
-
-const NotFound = (): Node => ;
-
-export default NotFound;
diff --git a/client/src/pages/NotFound.tsx b/client/src/pages/NotFound.tsx
new file mode 100644
index 0000000..3db5351
--- /dev/null
+++ b/client/src/pages/NotFound.tsx
@@ -0,0 +1,8 @@
+// @flow
+import React, { ReactElement } from 'react';
+
+import Page from '../components/layout/Page';
+
+const NotFound = (): ReactElement => ;
+
+export default NotFound;
diff --git a/client/src/pages/Note.jsx b/client/src/pages/Note.tsx
similarity index 93%
rename from client/src/pages/Note.jsx
rename to client/src/pages/Note.tsx
index 85c002e..a73f1d4 100644
--- a/client/src/pages/Note.jsx
+++ b/client/src/pages/Note.tsx
@@ -1,6 +1,5 @@
// @flow
-import React, { useState, useEffect } from 'react';
-import type { Node } from 'react';
+import React, { useState, useEffect, ReactElement } from 'react';
import {
Editor,
EditorState,
@@ -94,7 +93,7 @@ type NoteProps = {
},
};
-const Note = ({ user }: NoteProps): Node => {
+const Note = ({ user }: NoteProps): ReactElement => {
const [noteState, setNoteState] = useState(NOTE_STATE.loading);
const [submitState, setSubmitState] = useState(SUBMIT_STATE.start);
@@ -102,17 +101,17 @@ const Note = ({ user }: NoteProps): Node => {
const [isEditable, setIsEditable] = useState(false);
// routing
- const { noteID } = useParams();
+ const { noteID } = useParams();
// form data
const [editorState, setEditorState] = useState(() =>
EditorState.createEmpty(),
);
- const [noteTitle, setNoteTitle] = useState(null);
- const [noteLabels, setNoteLabels] = useState([]);
- const [referencedMembers, setReferencedMembers] = useState([]);
- const [viewableBy, setViewableBy] = useState([]);
- const [editableBy, setEditableBy] = useState([]);
+ const [noteTitle, setNoteTitle] = useState('');
+ const [noteLabels, setNoteLabels] = useState([]);
+ const [referencedMembers, setReferencedMembers] = useState([]);
+ const [viewableBy, setViewableBy] = useState([]);
+ const [editableBy, setEditableBy] = useState([]);
const [encryptNote, setEncryptNote] = useState(true);
// TODO: Implement safety guards for leaving an edited form
@@ -158,14 +157,14 @@ const Note = ({ user }: NoteProps): Node => {
// TODO! Migrate to Form library for validation + modeling
setNoteTitle(title);
setNoteLabels(labels);
- setReferencedMembers(currentReferencedMembers.map((m) => m.memberId));
- setViewableBy(currentViewableBy.map((m) => m.memberId));
- setEditableBy(currentEditableBy.map((m) => m.memberId));
+ setReferencedMembers(currentReferencedMembers.map((m: any) => m.memberId));
+ setViewableBy(currentViewableBy.map((m: any) => m.memberId));
+ setEditableBy(currentEditableBy.map((m: any) => m.memberId));
setEncryptNote(encrypt);
// check if current user is in editor list
if (
- currentEditableBy.findIndex((m) => m.memberId === user._id) > -1
+ currentEditableBy.findIndex((m: any) => m.memberId === user._id) > -1
) {
setIsEditable(true);
}
@@ -213,7 +212,7 @@ const Note = ({ user }: NoteProps): Node => {
* @param {*} currentEditorState
* @returns {'handled' | 'not-handled'}
*/
- function handleKeyCommand(command, currentEditorState) {
+ function handleKeyCommand(command:any, currentEditorState: any) {
const newState = RichUtils.handleKeyCommand(currentEditorState, command);
if (newState) {
@@ -230,7 +229,7 @@ const Note = ({ user }: NoteProps): Node => {
* @param {*} currentEditorState
* @returns {boolean}
*/
- const validateEditorState = (currentEditorState) =>
+ const validateEditorState = (currentEditorState: any) =>
currentEditorState.getCurrentContent().hasText();
/**
@@ -291,7 +290,7 @@ const Note = ({ user }: NoteProps): Node => {
* Handles toggling the received rich inline style
* @param {string} richStyle
*/
- function handleRichStyle(richStyle) {
+ function handleRichStyle(richStyle: any) {
const newState = RichUtils.toggleInlineStyle(editorState, richStyle);
if (newState) setEditorState(newState);
}
@@ -300,7 +299,7 @@ const Note = ({ user }: NoteProps): Node => {
* Handles toggling the received block type
* @param {string} blockType
*/
- function handleBlockType(blockType) {
+ function handleBlockType(blockType: any) {
const newState = RichUtils.toggleBlockType(editorState, blockType);
if (newState) setEditorState(newState);
}
diff --git a/client/src/pages/Notes.jsx b/client/src/pages/Notes.tsx
similarity index 87%
rename from client/src/pages/Notes.jsx
rename to client/src/pages/Notes.tsx
index 37b527e..143c73d 100644
--- a/client/src/pages/Notes.jsx
+++ b/client/src/pages/Notes.tsx
@@ -1,5 +1,5 @@
// @flow
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, ReactElement } from 'react';
import { Link, useHistory } from 'react-router-dom';
import { Button, Icon } from 'semantic-ui-react';
import 'draft-js/dist/Draft.css';
@@ -10,7 +10,7 @@ import Loading from '../components/ui/Loading';
import Page from '../components/layout/Page';
import Table from '../components/table/Table';
-function Notes() {
+const Notes = (): ReactElement => {
const [notes, setNotes] = useState([]);
const [isLoading, setIsLoading] = useState(true);
@@ -48,7 +48,7 @@ function Notes() {
history.push(`/notes/${e.data._id}`)}
+ onRowClick={(e: any) => history.push(`/notes/${e.data._id}`)}
sizeToFit
/>
) : (
@@ -57,4 +57,5 @@ function Notes() {
);
}
+
export default Notes;
diff --git a/client/src/pages/Profile.jsx b/client/src/pages/Profile.tsx
similarity index 91%
rename from client/src/pages/Profile.jsx
rename to client/src/pages/Profile.tsx
index b1a7c53..88b8170 100644
--- a/client/src/pages/Profile.jsx
+++ b/client/src/pages/Profile.tsx
@@ -30,9 +30,9 @@ const SUCCESS_MESSAGE_POPUP_TIME_MS = 4000;
* Checks if the given API responses were successful
* @param {...any} responses Any amount of response objects
*/
-const areResponsesSuccessful = (...responses) => {
+const areResponsesSuccessful = (...responses: any) => {
let success = true;
- responses.forEach((response) => {
+ responses.forEach((response: any) => {
if (response == null || response.data == null || !response.data.success)
success = false;
});
@@ -41,15 +41,15 @@ const areResponsesSuccessful = (...responses) => {
};
const Profile = () => {
- const { memberID } = useParams();
+ const { memberID } = useParams();
const newUser = memberID === 'new';
const [newUserID, setNewUserID] = useState(false);
// Upstream user is the DB version. Local user captures local changes made to the user.
- const [upstreamUser, setUpstreamUser] = useState({});
+ const [upstreamUser, setUpstreamUser] = useState({firstName: '', lastName: '', _id: ''});
const [localUser, setLocalUser] = useState({});
- const [errorMessage, setErrorMessage] = useState(null);
- const [successMessage, setSuccessMessage] = useState(null);
+ const [errorMessage, setErrorMessage] = useState('');
+ const [successMessage, setSuccessMessage] = useState('');
const [enumOptions, setEnumOptions] = useState({});
const [schemaTypes, setSchemaTypes] = useState({});
const [userPermissions, setUserPermissions] = useState({
@@ -90,7 +90,7 @@ const Profile = () => {
setUserPermissions(memberPermissionResponse.data.result);
setSchemaTypes(memberSchemaResponse.data.result);
setEnumOptions(enumOptionsResponse.data.result);
- setErrorMessage(null);
+ setErrorMessage('');
}
getUserData();
@@ -98,13 +98,13 @@ const Profile = () => {
// Returns true if the member attribute is of the given type.
// Type is a string defined by mongoose. See https://mongoosejs.com/docs/schematypes.html
- const isOfType = (attribute, type) => {
- if (!schemaTypes || !type || !schemaTypes[type]) return false;
+ const isOfType = (attribute: any, type: any) => {
+ if (!schemaTypes || !type || !(schemaTypes as any)[type]) return false;
- return schemaTypes[type].includes(attribute);
+ return (schemaTypes as any)[type].includes(attribute);
};
- const onAttributeChange = (value, attributeLabel) => {
+ const onAttributeChange = (value: any, attributeLabel: any) => {
setLocalUser({
...localUser,
[attributeLabel]: value,
@@ -120,15 +120,15 @@ const Profile = () => {
return updatedUser;
};
- const setTemporarySuccessMessage = (contents) => {
+ const setTemporarySuccessMessage = (contents: string) => {
setSuccessMessage(contents);
- setTimeout(() => setSuccessMessage(null), SUCCESS_MESSAGE_POPUP_TIME_MS);
+ setTimeout(() => setSuccessMessage(''), SUCCESS_MESSAGE_POPUP_TIME_MS);
};
const submitChanges = async () => {
let missingFields = false;
requiredFields.forEach((field) => {
- if (!localUser[field]) {
+ if (!(localUser as any)[field]) {
missingFields = true;
}
});
@@ -148,10 +148,10 @@ const Profile = () => {
: '.'
}`,
);
- setSuccessMessage(null);
+ setSuccessMessage('');
} else {
setTemporarySuccessMessage(newUser ? 'User Created' : 'User updated');
- setErrorMessage(null);
+ setErrorMessage('');
setUpstreamUser(result.data.result);
if (newUser) setNewUserID(result.data.result._id);
}
@@ -221,7 +221,7 @@ const Profile = () => {
if (isOfType(attribute, 'Date')) {
return (
{
+const emptyProject = {
+ _id: '',
+ projectName: '',
+ chapter: '',
+ description: '',
+ status: '',
+ duration: { amount: 0, unit: ''},
+ teamMembersEmail: [] as any[],
+ github: '',
+ notion: ''
+}
+const Projects = (): ReactElement => {
const [projects, setProjects] = useState([]);
- const [teamMembers, setTeamMembers] = useState([]);
+ const [teamMembers, setTeamMembers] = useState([]);
const [visible, setVisible] = useState(false);
- const [currProj, setCurrProj] = useState({ projectName: '' });
+ const [currProj, setCurrProj] = useState(emptyProject);
const [unmodProj, setUnmodProj] = useState({});
const [editable, setEditable] = useState(false);
const [editMode, setEditMode] = useState(false);
@@ -42,9 +52,9 @@ const Projects = (): Node => {
const getAllMembers = async () => {
const allMembers = await getMembers();
if (allMembers.data) {
- const teamMemberList = [];
+ const teamMemberList: any[] = [];
let teamEmail = {};
- allMembers.data.result.forEach((e) => {
+ allMembers.data.result.forEach((e: any) => {
teamEmail = { ...teamEmail, [e.email]: e.firstName + e.lastName };
teamMemberList.push({
key: e.firstName + e.lastName,
@@ -69,7 +79,7 @@ const Projects = (): Node => {
getCurrMember();
}, []);
- const filterObj = (raw, allowed) => {
+ const filterObj = (raw: any, allowed: any): any[] => {
const filtered = Object.values(
Object.fromEntries(
Object.entries(raw).filter(([key]) => allowed.includes(key)),
@@ -150,8 +160,8 @@ const Projects = (): Node => {
selection
options={chapterOptions}
value={currProj.chapter}
- onChange={(e, { value }) => {
- setCurrProj({ ...currProj, chapter: value });
+ onChange={(_, { value }) => {
+ setCurrProj({ ...currProj, chapter: (value as string) });
}}
disabled={!editMode}
/>
@@ -160,8 +170,8 @@ const Projects = (): Node => {
placeholder="Write project description here"
defaultValue={currProj.description}
readOnly={!editMode}
- onChange={(e, { value }) => {
- setCurrProj({ ...currProj, description: value });
+ onChange={(_, { value }) => {
+ setCurrProj({ ...currProj, description: (value as string) });
}}
/>
{
selection
options={possibleStatuses}
value={currProj.status}
- onChange={(e, { value }) => {
- setCurrProj({ ...currProj, status: value });
+ onChange={(_, { value }) => {
+ setCurrProj({ ...currProj, status: (value as string)});
}}
disabled={!editMode}
/>
@@ -185,7 +195,7 @@ const Projects = (): Node => {
}
readOnly={!editMode}
onChange={(e, { value }) => {
- setCurrProj({ ...currProj, duration: value });
+ setCurrProj({ ...currProj, duration: (value as any)});
}}
/>
{
}
disabled={!editMode}
onChange={(_, { value }) => {
- const newTeam = [];
- value.forEach((e) =>
+ const newTeam: any[] = [];
+ (value as []).forEach((e: any) =>
newTeam.push(findKey(teamEmails, partial(isEqual, e))),
);
setCurrProj({ ...currProj, teamMembersEmail: newTeam });
@@ -242,8 +252,8 @@ const Projects = (): Node => {
history.push(`/projects/${e.data._id}`)}
- onRowDoubleClick={(e) => {
+ onRowClick={(e: any) => history.push(`/projects/${e.data._id}`)}
+ onRowDoubleClick={(e: any) => {
setCurrProj(e.data);
setVisible(true);
setUnmodProj(e.data);
diff --git a/client/src/routes.js b/client/src/routes.ts
similarity index 100%
rename from client/src/routes.js
rename to client/src/routes.ts
diff --git a/client/src/utils/apiHelpers.js b/client/src/utils/apiHelpers.ts
similarity index 86%
rename from client/src/utils/apiHelpers.js
rename to client/src/utils/apiHelpers.ts
index 0fe919f..ec405f9 100644
--- a/client/src/utils/apiHelpers.js
+++ b/client/src/utils/apiHelpers.ts
@@ -6,7 +6,7 @@ import { BACKEND_BASE_URL } from './apiUrls';
* @param {String} successRedirect URL to redirect to on successful requests
* @param {String} failureRedirect URL to redirect to on failed requests
*/
-const buildURI = (endpoint, successRedirect, failureRedirect = '/login') => {
+const buildURI = (endpoint: string, successRedirect: string, failureRedirect = '/login') => {
const uri = new URL(`${BACKEND_BASE_URL}/${endpoint}`);
switch (endpoint) {
diff --git a/client/src/utils/apiUrls.js b/client/src/utils/apiUrls.ts
similarity index 100%
rename from client/src/utils/apiUrls.js
rename to client/src/utils/apiUrls.ts
diff --git a/client/src/utils/apiWrapper.js b/client/src/utils/apiWrapper.js
deleted file mode 100644
index d07c45b..0000000
--- a/client/src/utils/apiWrapper.js
+++ /dev/null
@@ -1,245 +0,0 @@
-import axios from 'axios';
-
-import { BACKEND_BASE_URL } from './apiUrls';
-
-// Axios Configuration
-axios.defaults.withCredentials = true;
-
-// retrieves the session status of the current user
-export const getUserAuth = () => {
- const requestString = `${BACKEND_BASE_URL}/members/current`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_AUTH_FAIL',
- error,
- }));
-};
-
-// logs a user out
-export const endUserSession = () => {
- const requestString = `${BACKEND_BASE_URL}/auth/logout`;
- return axios
- .post(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_SESSION_END_FAIL',
- error,
- }));
-};
-
-// Retrieves a member from their mongo ID
-export const getMemberByID = (mongoID) => {
- const requestString = `${BACKEND_BASE_URL}/members/${mongoID}`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_MEMBER_BY_ID_FAIL',
- error,
- }));
-};
-
-// Retrieves a member's permissions from their mongo ID
-export const getMemberPermissionsByID = (mongoID) => {
- const requestString = `${BACKEND_BASE_URL}/members/${mongoID}/permissions`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_MEMBER_PERMISSIONS_BY_ID_FAIL',
- error,
- }));
-};
-
-// Retrieves a member's permissions from their mongo ID
-export const getMemberEnumOptions = () => {
- const requestString = `${BACKEND_BASE_URL}/members/options`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_MEMBER_ENUM_OPTIONS_FAIL',
- error,
- }));
-};
-
-// Retrieves a member's permissions from their mongo ID
-export const getMemberSchemaTypes = () => {
- const requestString = `${BACKEND_BASE_URL}/members/schema`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_MEMBER_SCHEMA_TYPES_FAIL',
- error,
- }));
-};
-
-// Retrieves all members
-export const getMembers = () => {
- const requestString = `${BACKEND_BASE_URL}/members`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_MEMBERS_FAIL',
- error,
- }));
-};
-
-// Retrieves a member's permissions from their mongo ID
-export const updateMember = (member, memberID) => {
- const requestString = `${BACKEND_BASE_URL}/members/${memberID}`;
- return axios
- .put(requestString, {
- ...member,
- })
- .catch((error) => ({
- type: 'UPDATE_MEMBER_FAIL',
- error,
- }));
-};
-
-// Retrieves a note by ID
-export const getNote = (noteID) => {
- const requestString = `${BACKEND_BASE_URL}/notes/${noteID}`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_NOTE_FAIL',
- error,
- }));
-};
-
-// Retrieves notes info
-export const getNotes = () => {
- const requestString = `${BACKEND_BASE_URL}/notes`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_NOTES_FAIL',
- error,
- }));
-};
-
-// Updates a note
-export const updateNote = (note, noteID) => {
- const requestString = `${BACKEND_BASE_URL}/notes/${noteID}`;
- return axios
- .put(requestString, {
- ...note,
- })
- .catch((error) => ({
- type: 'UPDATE_NOTE_FAIL',
- error,
- }));
-};
-
-// Deletes a note
-export const deleteNote = (noteID) => {
- const requestString = `${BACKEND_BASE_URL}/notes/${noteID}`;
- return axios.delete(requestString).catch((error) => ({
- type: 'UPDATE_NOTE_FAIL',
- error,
- }));
-};
-
-// Creates a new note
-export const createNote = (note) => {
- const requestString = `${BACKEND_BASE_URL}/notes`;
- return axios
- .post(requestString, {
- ...note,
- })
- .catch((error) => ({
- type: 'CREATE_NOTE_FAIL',
- error,
- }));
-};
-
-// Retrieves all note labels
-export const getNoteLabels = () => {
- const requestString = `${BACKEND_BASE_URL}/notes/labels`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_NOTES_LABELS_FAIL',
- error,
- }));
-};
-
-// Creates a new member
-export const createMember = (member) => {
- const requestString = `${BACKEND_BASE_URL}/members/`;
- return axios
- .post(requestString, {
- ...member,
- })
- .catch((error) => ({
- type: 'GET_MEMBER_SCHEMA_TYPES_FAIL',
- error,
- }));
-};
-
-// Retrieves all projects
-export const getProjects = () => {
- const requestString = `${BACKEND_BASE_URL}/projects`;
- return axios
- .get(requestString, {
- headers: {
- 'Content-Type': 'application/JSON',
- },
- })
- .catch((error) => ({
- type: 'GET_PROJECTS_FAIL',
- error,
- }));
-};
-
-// Updates a project
-export const updateProject = (project, projectID) => {
- const requestString = `${BACKEND_BASE_URL}/projects/${projectID}`;
- return axios
- .put(requestString, {
- ...project,
- })
- .catch((error) => ({
- type: 'UPDATE_PROJECT_FAIL',
- error,
- }));
-};
diff --git a/client/src/utils/apiWrapper.ts b/client/src/utils/apiWrapper.ts
new file mode 100644
index 0000000..bc297ad
--- /dev/null
+++ b/client/src/utils/apiWrapper.ts
@@ -0,0 +1,305 @@
+import axios from 'axios';
+
+import { BACKEND_BASE_URL } from './apiUrls';
+
+// Axios Configuration
+axios.defaults.withCredentials = true;
+
+type ApiResponse = {
+ data?: any;
+
+ // these are for errors
+ error?: any;
+ type?: string;
+}
+// retrieves the session status of the current user
+export const getUserAuth = async (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members/current`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_AUTH_FAIL',
+ error,
+ });
+ }
+};
+
+// logs a user out
+export const endUserSession = async (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/auth/logout`;
+ try {
+ return await axios
+ .post(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_SESSION_END_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves a member from their mongo ID
+export const getMemberByID = async (mongoID: string): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members/${mongoID}`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_MEMBER_BY_ID_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves a member's permissions from their mongo ID
+export const getMemberPermissionsByID = async (mongoID: string): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members/${mongoID}/permissions`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_MEMBER_PERMISSIONS_BY_ID_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves a member's permissions from their mongo ID
+export const getMemberEnumOptions = async (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members/options`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_MEMBER_ENUM_OPTIONS_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves a member's permissions from their mongo ID
+export const getMemberSchemaTypes = async (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members/schema`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_MEMBER_SCHEMA_TYPES_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves all members
+export const getMembers = (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members`;
+ try {
+ return axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ })
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_MEMBERS_FAIL',
+ error,
+ });
+ }
+
+};
+
+// Retrieves a member's permissions from their mongo ID
+export const updateMember = async (member: any, memberID: string): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members/${memberID}`;
+ try {
+ return await axios
+ .put(requestString, {
+ ...member,
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'UPDATE_MEMBER_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves a note by ID
+export const getNote = async (noteID: string): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/notes/${noteID}`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_NOTE_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves notes info
+export const getNotes = async (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/notes`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_NOTES_FAIL',
+ error,
+ });
+ }
+};
+
+// Updates a note
+export const updateNote = async (note: any, noteID: string): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/notes/${noteID}`;
+ try {
+ return await axios
+ .put(requestString, {
+ ...note,
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'UPDATE_NOTE_FAIL',
+ error,
+ });
+ }
+};
+
+// Deletes a note
+export const deleteNote = async (noteID: string): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/notes/${noteID}`;
+ try {
+ return await axios.delete(requestString);
+ } catch (error) {
+ return Promise.reject({
+ type: 'UPDATE_NOTE_FAIL',
+ error,
+ });
+ }
+};
+
+// Creates a new note
+export const createNote = async (note: any): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/notes`;
+ try {
+ return await axios
+ .post(requestString, {
+ ...note,
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'CREATE_NOTE_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves all note labels
+export const getNoteLabels = async (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/notes/labels`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_NOTES_LABELS_FAIL',
+ error,
+ });
+ }
+};
+
+// Creates a new member
+export const createMember = async (member: any): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/members/`;
+ try {
+ return await axios
+ .post(requestString, {
+ ...member,
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_MEMBER_SCHEMA_TYPES_FAIL',
+ error,
+ });
+ }
+};
+
+// Retrieves all projects
+export const getProjects = async (): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/projects`;
+ try {
+ return await axios
+ .get(requestString, {
+ headers: {
+ 'Content-Type': 'application/JSON',
+ },
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'GET_PROJECTS_FAIL',
+ error,
+ });
+ }
+};
+
+// Updates a project
+export const updateProject = async (project: any, projectID: string): Promise => {
+ const requestString = `${BACKEND_BASE_URL}/projects/${projectID}`;
+ try {
+ return await axios
+ .put(requestString, {
+ ...project,
+ });
+ } catch (error) {
+ return Promise.reject({
+ type: 'UPDATE_PROJECT_FAIL',
+ error,
+ });
+ }
+};
diff --git a/client/src/utils/consts.js b/client/src/utils/consts.ts
similarity index 100%
rename from client/src/utils/consts.js
rename to client/src/utils/consts.ts
diff --git a/client/src/utils/formatters.js b/client/src/utils/formatters.ts
similarity index 100%
rename from client/src/utils/formatters.js
rename to client/src/utils/formatters.ts
diff --git a/client/src/utils/mockMemberData.js b/client/src/utils/mockMemberData.ts
similarity index 100%
rename from client/src/utils/mockMemberData.js
rename to client/src/utils/mockMemberData.ts
diff --git a/client/src/utils/tableHelpers.js b/client/src/utils/tableHelpers.ts
similarity index 83%
rename from client/src/utils/tableHelpers.js
rename to client/src/utils/tableHelpers.ts
index 08fa2d3..7fd0efd 100644
--- a/client/src/utils/tableHelpers.js
+++ b/client/src/utils/tableHelpers.ts
@@ -1,6 +1,6 @@
import moment from 'moment';
-import LinkIcons, { link } from '../components/table/LinkIcons';
+import LinkIcons, { Link } from '../components/table/LinkIcons';
import { titleCaseFormatter } from './formatters';
@@ -21,21 +21,21 @@ const FieldVals = Object.freeze({
});
// Sort Birth Dates in ascending order (earlier dates first)
-const dateComparator = (value1, value2) => {
+const dateComparator = (value1: any, value2: any) => {
const date1 = moment(value1, BIRTH_DATE_FORMAT);
const date2 = moment(value2, BIRTH_DATE_FORMAT);
return date1.diff(date2);
};
// Sort Grad Year && Generation in ascending order (earlier cohorts first)
-const semesterComparator = (value1, value2) => {
+const semesterComparator = (value1: any, value2: any) => {
// parseInt uses base 10 when changing to an integer
const [sem1, year1] = value1
.split(' ')
- .map((val) => (parseInt(val, 10) ? Number(val) : val));
+ .map((val: any) => (parseInt(val, 10) ? Number(val) : val));
const [sem2, year2] = value2
.split(' ')
- .map((val) => (parseInt(val, 10) ? Number(val) : val));
+ .map((val: any) => (parseInt(val, 10) ? Number(val) : val));
if (year1 < year2) return -1;
if (year1 > year2) return 1;
if (sem1 === FieldVals.fall && sem2 === FieldVals.spring) return 1;
@@ -44,36 +44,36 @@ const semesterComparator = (value1, value2) => {
};
// Combine both Semester and Year into a single column
-const graduationGetter = ({ data }) => {
+const graduationGetter = ({ data }: any) => {
if (data.gradSemester === FieldVals.tbd) return data.gradSemester;
return `${data.gradSemester} ${data.gradYear}`;
};
// Get generation label from member data
-const generationGetter = ({ data }) => {
+const generationGetter = ({ data }: any) => {
if (data.generationSemester === FieldVals.tbd) return data.generationSemester;
return `${data.generationSemester} ${data.generationYear}`;
};
// Gets full name from member data
-const nameGetter = ({ data }) =>
+const nameGetter = ({ data }: any) =>
`${data.firstName ?? ''} ${data.lastName ?? ''}`;
// Gets birthday in format from member data
-const birthDateGetter = ({ data }) => {
+const birthDateGetter = ({ data }: any) => {
if (!data.birthdate) return 'Not Given';
const date = moment(data.birthdate).format(BIRTH_DATE_FORMAT);
return date;
};
// Formats table for title case
-const tableTitleCaseFormatter = ({ value }) => titleCaseFormatter(value);
+const tableTitleCaseFormatter = ({ value }: any) => titleCaseFormatter(value);
/**
* @constant
* @type {Array