Refact/project (#189)

* refactor: cleanup project entry point
* refactor: remove unused
* refactor: folder restructure
This commit is contained in:
Carlos Valente
2022-08-03 23:20:23 +02:00
committed by GitHub
parent 05be0c1e95
commit 9b5d536378
116 changed files with 352 additions and 942 deletions
+56
View File
@@ -0,0 +1,56 @@
import React, { createContext, useCallback, useEffect, useState } from 'react';
import { APP_SETTINGS } from '../api/apiConstants';
import { getSettings } from '../api/ontimeApi';
import { useFetch } from '../hooks/useFetch';
export const AppContext = createContext({
auth: false,
data: {
pinCode: null,
},
});
export const AppContextProvider = ({ children }) => {
const [auth, setAuth] = useState(true);
const { data } = useFetch(APP_SETTINGS, getSettings);
useEffect(() => {
if (data == null) return;
const previousEntry = sessionStorage.getItem('ontime-entry');
if (previousEntry) {
if (previousEntry === data?.pinCode) {
setAuth(true);
} else {
sessionStorage.removeItem('ontime-entry')
}
} else if (data?.pinCode == null || data?.pinCode === '') {
setAuth(true);
} else {
setAuth(false);
}
}, [data]);
/**
* Validates a pincode
* @return boolean - whether the pin is valid
*/
const validate = useCallback(
(pin) => {
let correct;
if (data?.pinCode == null || data?.pinCode === '') {
correct = true;
} else {
correct = pin === data?.pinCode;
}
if (correct) {
sessionStorage.setItem('ontime-entry', pin);
}
setAuth(correct);
return correct;
},
[data]
);
return <AppContext.Provider value={{ auth, validate }}>{children}</AppContext.Provider>;
};
@@ -0,0 +1,72 @@
import React, { createContext, useCallback } from 'react';
import { useLocalStorage } from '../hooks/useLocalStorage';
export const CollapseContext = createContext({
collapsed: {},
setCollapsed: () => undefined,
clearCollapsed: () => undefined,
isCollapsed: () => undefined,
});
export const CollapseProvider = ({ children }) => {
const [collapsed, saveCollapsed] = useLocalStorage('collapsed', {});
/**
* @description Sets collapsed state for a single id
* @param {string} - id
* @param {boolean} - collapsed / not collapsed
*/
const setCollapsed = useCallback(
(id, isCollapsed) => {
if (isCollapsed) {
saveCollapsed((prev) => ({ ...prev, [id]: true }));
} else {
saveCollapsed((prev) => {
const newObject = { ...prev };
delete newObject[id];
return { ...newObject };
});
}
},
[saveCollapsed]
);
/**
* @description Clears collapsed state in local-storage
*/
const collapseMultiple = useCallback(
(events) => {
const newOptions = {};
for (const event of events) {
newOptions[event.id] = true;
}
saveCollapsed(newOptions);
},
[saveCollapsed]
);
/**
* @description Clears collapsed state in local-storage
*/
const expandAll = useCallback(() => {
saveCollapsed({});
}, [saveCollapsed]);
/**
* @description Clears collapsed state in local-storage
* @return {boolean} - collapsed / not collapsed
*/
const isCollapsed = useCallback(
(id) => {
return id in collapsed;
},
[collapsed]
);
return (
<CollapseContext.Provider value={{ setCollapsed, collapseMultiple, expandAll, isCollapsed }}>
{children}
</CollapseContext.Provider>
);
};
@@ -0,0 +1,64 @@
import React, { createContext, useCallback, useMemo, useState } from 'react';
import { useLocalStorage } from '../hooks/useLocalStorage';
export const CursorContext = createContext({
cursor: 0,
isCursorLocked: false,
setCursor: () => undefined,
moveCursorUp: () => undefined,
moveCursorDown: () => undefined,
});
export const CursorProvider = ({ children }) => {
const [cursor, setCursor] = useState(0);
const [_cursorLocked, _setCursorLocked] = useLocalStorage('isCursorLocked', 'locked');
const isCursorLocked = useMemo(() => _cursorLocked === 'locked', [_cursorLocked]);
const cursorLockedOff = useCallback(() => _setCursorLocked('unlocked'), [_setCursorLocked]);
const cursorLockedOn = useCallback(() => _setCursorLocked('locked'), [_setCursorLocked]);
const moveCursorUp = useCallback(() => {
setCursor((prev) => Math.max(prev - 1, 0));
}, []);
const moveCursorDown = useCallback(() => {
setCursor((prev) => prev + 1);
}, []);
/**
* @param {boolean | undefined} newValue
*/
const toggleCursorLocked = useCallback(
(newValue = undefined) => {
if (typeof newValue === 'undefined') {
if (isCursorLocked) {
cursorLockedOff();
} else {
cursorLockedOn();
}
} else if (!newValue) {
cursorLockedOff();
} else if (newValue) {
cursorLockedOn();
}
},
[cursorLockedOff, cursorLockedOn, isCursorLocked]
);
return (
<CursorContext.Provider
value={{
cursor,
isCursorLocked,
toggleCursorLocked,
setCursor,
moveCursorUp,
moveCursorDown,
}}
>
{children}
</CursorContext.Provider>
);
};
@@ -0,0 +1,32 @@
import React, { createContext, useState } from 'react';
export const LocalEventSettingsContext = createContext({
showQuickEntry: false,
starTimeIsLastEnd: true,
defaultPublic: true,
setShowQuickEntry: () => undefined,
setStarTimeIsLastEnd: () => undefined,
setDefaultPublic: () => undefined,
});
export const LocalEventSettingsProvider = ({ children }) => {
const [showQuickEntry, setShowQuickEntry] = useState(false);
const [starTimeIsLastEnd, setStarTimeIsLastEnd] = useState(true);
const [defaultPublic, setDefaultPublic] = useState(false);
return (
<LocalEventSettingsContext.Provider
value={{
showQuickEntry,
setShowQuickEntry,
starTimeIsLastEnd,
setStarTimeIsLastEnd,
defaultPublic,
setDefaultPublic,
}}
>
{children}
</LocalEventSettingsContext.Provider>
);
};
@@ -0,0 +1,110 @@
import React, { createContext, useCallback, useEffect, useState } from 'react';
import { generateId } from '../utils/generate_id';
import { nowInMillis, stringFromMillis } from '../utils/time';
import { useSocket } from './socketContext';
export const LoggingContext = createContext({
logData: [],
emitInfo: () => undefined,
emitWarning: () => undefined,
emitError: () => undefined,
clearLog: () => undefined,
});
export const LoggingProvider = ({ children }) => {
const MAX_MESSAGES = 100;
const socket = useSocket();
const [logData, setLogData] = useState([]);
const origin = 'USER';
// handle incoming messages
useEffect(() => {
if (socket == null) return;
// Ask for log data
socket.emit('get-logger');
socket.on('logger', (data) => {
setLogData((l) => [data, ...l]);
});
// Clear listener
return () => {
socket.off('logger');
};
}, [socket]);
/**
* Utility function sends message over socket
* @param text
* @param level
* @private
*/
const _send = useCallback(
(text, level) => {
if (socket != null) {
const m = {
id: generateId(),
origin,
time: stringFromMillis(nowInMillis()),
level,
text,
};
setLogData((l) => [m, ...l]);
socket.emit('logger', m);
}
if (logData.length > MAX_MESSAGES) {
setLogData((l) => l.pop());
}
},
[logData, socket]
);
/**
* Sends a message with level INFO
* @param text
*/
const emitInfo = useCallback(
(text) => {
_send(text, 'INFO');
},
[_send]
);
/**
* Sends a message with level WARN
* @param text
*/
const emitWarning = useCallback(
(text) => {
_send(text, 'WARN');
},
[_send]
);
/**
* Sends a message with level ERROR
* @param text
*/
const emitError = useCallback(
(text) => {
_send(text, 'ERROR');
},
[_send]
);
/**
* Clears running log
*/
const clearLog = useCallback(() => {
setLogData([]);
}, []);
return (
<LoggingContext.Provider value={{ emitInfo, logData, emitWarning, emitError, clearLog }}>
{children}
</LoggingContext.Provider>
);
};
@@ -0,0 +1,79 @@
import React, { createContext, useCallback, useState } from 'react';
import { useLocalStorage } from '../hooks/useLocalStorage';
export const TableSettingsContext = createContext({
theme: '',
showSettings: false,
followSelected: false,
toggleSettings: () => undefined,
toggleTheme: () => undefined,
toggleFollow: () => undefined,
});
export const TableSettingsProvider = ({ children }) => {
const [theme, setTheme] = useLocalStorage('table-color-theme', 'dark');
const [followSelected, setFollowSelected] = useLocalStorage('table-follow-selected', false);
const [showSettings, setShowSettings] = useState(false);
/**
* @description Toggles the current value of dark mode
* @param {string} val - 'light' or 'dark'
*/
const toggleTheme = useCallback(
(val) => {
if (val === undefined) {
setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));
} else {
setTheme(val);
}
},
[setTheme]
);
/**
* @description Toggles visibility state for settings
* @param {boolean} val - whether the settings window is visible
*/
const toggleSettings = useCallback(
(val) => {
if (val === undefined) {
setShowSettings((prev) => !prev);
} else {
setShowSettings(val);
}
},
[setShowSettings]
);
/**
* @description Toggles follow option
* @param {boolean} val - whether the window follows selected event
*/
const toggleFollow = useCallback(
(val) => {
if (val === undefined) {
setFollowSelected((prev) => !prev);
} else {
setFollowSelected(val);
}
},
[setFollowSelected]
);
return (
<TableSettingsContext.Provider
value={{
theme,
showSettings,
followSelected,
toggleSettings,
toggleTheme,
toggleFollow,
}}
>
{children}
</TableSettingsContext.Provider>
);
};
@@ -0,0 +1,23 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
import { serverURL } from 'common/api/apiConstants';
import io from 'socket.io-client';
const SocketContext = createContext([[], () => {}]);
export const useSocket = () => {
return useContext(SocketContext);
};
function SocketProvider({ children }) {
const [socket, setSocket] = useState();
useEffect(() => {
const s = io(serverURL, { transports: ['websocket'] });
setSocket(s);
return () => s.disconnect();
}, []);
return <SocketContext.Provider value={socket}>{children}</SocketContext.Provider>;
}
export default SocketProvider;