From 20ccb274666c34a10c03bc135f70904d1698538c Mon Sep 17 00:00:00 2001 From: bsourisse Date: Fri, 3 Mar 2023 16:11:38 +0100 Subject: [PATCH] feat: apprise notification switch + api --- .../AppriseAlertSettings.js | 105 ++++++++++++++++-- pages/api/account/getAppriseAlert.js | 63 +++++++++++ pages/api/account/updateAppriseAlert.js | 82 ++++++++++++++ 3 files changed, 240 insertions(+), 10 deletions(-) create mode 100644 pages/api/account/getAppriseAlert.js create mode 100644 pages/api/account/updateAppriseAlert.js diff --git a/Containers/UserSettings/AppriseAlertSettings/AppriseAlertSettings.js b/Containers/UserSettings/AppriseAlertSettings/AppriseAlertSettings.js index 0d0389e..76926b1 100644 --- a/Containers/UserSettings/AppriseAlertSettings/AppriseAlertSettings.js +++ b/Containers/UserSettings/AppriseAlertSettings/AppriseAlertSettings.js @@ -11,6 +11,79 @@ import Error from '../../../Components/UI/Error/Error'; import Switch from '../../../Components/UI/Switch/Switch'; export default function AppriseAlertSettings() { + //Var + const toastOptions = { + position: 'top-right', + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + //Callback > re-enabled button after notification. + onClose: () => setDisabled(false), + }; + + ////State + const [isLoading, setIsLoading] = useState(true); + const [testIsLoading, setTestIsLoading] = useState(false); + const [error, setError] = useState(); + const [disabled, setDisabled] = useState(false); + const [checked, setChecked] = useState(); + const [info, setInfo] = useState(false); + + ////LifeCycle + //Component did mount + useEffect(() => { + const dataFetch = async () => { + try { + const response = await fetch('/api/account/getAppriseAlert', { + method: 'GET', + headers: { + 'Content-type': 'application/json', + }, + }); + setChecked((await response.json()).appriseAlert); + setIsLoading(false); + } catch (error) { + console.log('Fetching Apprise alert setting failed.'); + } + }; + dataFetch(); + }, []); + + ////Functions + const onChangeSwitchHandler = async (data) => { + //Remove old error + setError(); + //Disabled button + setDisabled(true); + const response = await fetch('/api/account/updateAppriseAlert', { + method: 'PUT', + headers: { + 'Content-type': 'application/json', + }, + body: JSON.stringify(data), + }); + const result = await response.json(); + + if (!response.ok) { + setError(result.message); + setTimeout(() => { + setError(); + setDisabled(false); + }, 4000); + } else { + if (data.appriseAlert) { + setChecked(!checked); + toast.success('Apprise notifications enabled.', toastOptions); + } else { + setChecked(!checked); + toast.success('Apprise notifications disabled.', toastOptions); + } + } + }; + return ( <> {/* APPRISE ALERT */} @@ -20,15 +93,26 @@ export default function AppriseAlertSettings() {
- - // onChangeSwitchHandler({ emailAlert: e }) - // } - /> + {isLoading ? ( + + ) : ( + + onChangeSwitchHandler({ appriseAlert: e }) + } + /> + )} +
Apprise URLs
- +
Send a test notification + {error && }
diff --git a/pages/api/account/getAppriseAlert.js b/pages/api/account/getAppriseAlert.js new file mode 100644 index 0000000..dcd2a41 --- /dev/null +++ b/pages/api/account/getAppriseAlert.js @@ -0,0 +1,63 @@ +//Lib +import { promises as fs } from 'fs'; +import path from 'path'; +import { authOptions } from '../auth/[...nextauth]'; +import { unstable_getServerSession } from 'next-auth/next'; + +export default async function handler(req, res) { + if (req.method == 'GET') { + //Verify that the user is logged in. + const session = await unstable_getServerSession(req, res, authOptions); + if (!session) { + res.status(401).json({ message: 'You must be logged in.' }); + return; + } + try { + //Read the users file + //Find the absolute path of the json directory + const jsonDirectory = path.join(process.cwd(), '/config'); + let usersList = await fs.readFile( + jsonDirectory + '/users.json', + 'utf8' + ); + //Parse the usersList + usersList = JSON.parse(usersList); + + //Verify that the user of the session exists + const userIndex = usersList + .map((user) => user.username) + .indexOf(session.user.name); + if (userIndex === -1) { + res.status(400).json({ + message: + 'User is incorrect. Please, logout to update your session.', + }); + return; + } else { + //Send the appriseAlert bool + res.status(200).json({ + appriseAlert: usersList[userIndex].appriseAlert, + }); + return; + } + } catch (error) { + //Log for backend + console.log(error); + //Log for frontend + if (error.code == 'ENOENT') { + res.status(500).json({ + status: 500, + message: 'No such file or directory', + }); + } else { + res.status(500).json({ + status: 500, + message: 'API error, contact the administrator', + }); + } + return; + } + } else { + res.status(405).json({ message: 'Bad request on API' }); + } +} diff --git a/pages/api/account/updateAppriseAlert.js b/pages/api/account/updateAppriseAlert.js new file mode 100644 index 0000000..a3694f0 --- /dev/null +++ b/pages/api/account/updateAppriseAlert.js @@ -0,0 +1,82 @@ +//Lib +import { promises as fs } from 'fs'; +import path from 'path'; +import { authOptions } from '../auth/[...nextauth]'; +import { unstable_getServerSession } from 'next-auth/next'; + +export default async function handler(req, res) { + if (req.method == 'PUT') { + //Verify that the user is logged in. + const session = await unstable_getServerSession(req, res, authOptions); + if (!session) { + res.status(401).json({ message: 'You must be logged in.' }); + return; + } + + //The data we expect to receive + let { appriseAlert } = req.body; + + //Read the users file + //Find the absolute path of the json directory + const jsonDirectory = path.join(process.cwd(), '/config'); + let usersList = await fs.readFile( + jsonDirectory + '/users.json', + 'utf8' + ); + //Parse the usersList + usersList = JSON.parse(usersList); + + //1 : control the data + if (typeof appriseAlert != 'boolean') { + res.status(422).json({ message: 'Unexpected data' }); + return; + } + + //2 : Verify that the user of the session exists + const userIndex = usersList + .map((user) => user.username) + .indexOf(session.user.name); + if (userIndex === -1) { + res.status(400).json({ + message: + 'User is incorrect. Please, logout to update your session.', + }); + return; + } + + //3 : Change the appriseAlert settings + try { + //Modify the appriseAlert bool for the user + let newUsersList = usersList.map((user) => + user.username == session.user.name + ? { ...user, appriseAlert: appriseAlert } + : user + ); + //Stringify the new users list + newUsersList = JSON.stringify(newUsersList); + //Write the new JSON + fs.writeFile(jsonDirectory + '/users.json', newUsersList, (err) => { + if (err) console.log(err); + }); + res.status(200).json({ message: 'Successful API send' }); + } catch (error) { + //Log for backend + console.log(error); + //Log for frontend + if (error.code == 'ENOENT') { + res.status(500).json({ + status: 500, + message: 'No such file or directory', + }); + } else { + res.status(500).json({ + status: 500, + message: 'API error, contact the administrator', + }); + } + return; + } + } else { + res.status(405).json({ message: 'Bad request on API' }); + } +}