diff --git a/src/Components/Private/Edit/EditSystem.js b/src/Components/Private/Edit/EditSystem.js new file mode 100644 index 00000000..b50429b0 --- /dev/null +++ b/src/Components/Private/Edit/EditSystem.js @@ -0,0 +1,135 @@ +import React, { useState } from "react"; + +import { useForm } from "react-hook-form"; +import * as BS from "react-bootstrap"; +import moment from "moment"; +import "moment-timezone"; + +import API_URL from "../../../Constants/constants.js"; + +const EditSystem = ({ + name, + tag, + timezone, + avatar, + editDesc, + setEditMode, + setErrorAlert, + setUser, + user, +}) => { + const [invalidTimezone, setInvalidTimezone] = useState(false); + + const { register: registerEdit, handleSubmit: handleSubmitEdit } = useForm(); + + const submitEdit = (data) => { + if (data.tz) { + if (!moment.tz.zone(data.tz)) { + setInvalidTimezone(true); + return; + } + } + fetch(`${API_URL}s`, { + method: "PATCH", + body: JSON.stringify(data), + headers: { + "Content-Type": "application/json", + Authorization: JSON.stringify(localStorage.getItem("token")).slice( + 1, + -1 + ), + }, + }) + .then((res) => res.json()) + .then(() => { + setUser((prevState) => { + return { ...prevState, ...data }; + }); + localStorage.setItem("user", JSON.stringify(user)); + setEditMode(false); + }) + .catch((error) => { + console.error(error); + setErrorAlert(true); + }); + }; + + return ( + + + Note: if you refresh the page, the old data might show up again, + this is due to the bot caching data. +
+ Try editing a member to clear the cache, or wait a few minutes before + refreshing. +
+ + + Name: + + + + Tag: + + + + Timezone: + + {invalidTimezone ? ( + + Please enter a valid + + timezone + + + ) : ( + "" + )} + + + Avatar url: + + + + + Description: + + + setEditMode(false)}> + Cancel + {" "} + + Submit + +
+ ); +}; + +export default EditSystem; diff --git a/src/Components/Private/Edit/EditSystemPrivacy.js b/src/Components/Private/Edit/EditSystemPrivacy.js new file mode 100644 index 00000000..3c2718fc --- /dev/null +++ b/src/Components/Private/Edit/EditSystemPrivacy.js @@ -0,0 +1,109 @@ +import React from "react"; + +import { useForm } from "react-hook-form"; +import * as BS from "react-bootstrap"; + +import API_URL from "../../../Constants/constants.js"; + +const EditSystemPrivacy = ({ + setErrorAlert, + setUser, + user, + setPrivacyEdit, +}) => { + const { register: registerPrivacy, handleSubmit: handleSubmitPrivacy } = + useForm(); + + // submit privacy stuffs + const submitPrivacy = (data) => { + fetch(`${API_URL}s`, { + method: "PATCH", + body: JSON.stringify(data), + headers: { + "Content-Type": "application/json", + Authorization: JSON.stringify(localStorage.getItem("token")).slice( + 1, + -1 + ), + }, + }) + .then((res) => res.json()) + .then((data) => { + setUser((prevState) => { + return { ...prevState, ...data }; + }); + localStorage.setItem("user", JSON.stringify(user)); + setPrivacyEdit(false); + }) + .catch((error) => { + console.error(error); + setErrorAlert(true); + }); + }; + + return ( + +
+
Editing privacy settings
+ + + Description: + + + + + + + Member list: + + + + + + + Front: + + + + + + + Front history: + + + + + + + setPrivacyEdit(false)}> + Cancel + {" "} + + Submit + +
+
+ ); +}; + +export default EditSystemPrivacy; diff --git a/src/Components/Private/System.js b/src/Components/Private/System.js index b32e043a..90b66d4a 100644 --- a/src/Components/Private/System.js +++ b/src/Components/Private/System.js @@ -1,225 +1,244 @@ -import React, { useState, useEffect } from 'react'; -import * as BS from 'react-bootstrap' +import React, { useState, useEffect } from "react"; +import * as BS from "react-bootstrap"; import { useRouteMatch } from "react-router-dom"; -import { useForm } from "react-hook-form"; -import autosize from 'autosize'; -import moment from 'moment'; -import 'moment-timezone'; -import Popup from 'reactjs-popup'; -import Twemoji from 'react-twemoji'; - -import API_URL from "../../Constants/constants.js"; +import autosize from "autosize"; +import "moment-timezone"; +import Popup from "reactjs-popup"; +import Twemoji from "react-twemoji"; import history from "../../History.js"; -import defaultAvatar from '../../default_discord_avatar.png' +import defaultAvatar from "../../default_discord_avatar.png"; import { FaAddressCard } from "react-icons/fa"; +import EditSystem from "./Edit/EditSystem.js"; +import EditSystemPrivacy from "./Edit/EditSystemPrivacy.js"; export default function System(props) { + // match the url, if there's a member ID there, don't render this component at all + const match = useRouteMatch("/pk-webs/dash/:memberID"); - const match = useRouteMatch("/pk-webs/dash/:memberID"); + // get the user from the localstorage + const [user, setUser] = useState(JSON.parse(localStorage.getItem("user"))); - const { - register: registerEdit, - handleSubmit: handleSubmitEdit - } = useForm(); + // bunch of useState stuff, used in the useEffect() hook below + const [name, setName] = useState(""); + const [tag, setTag] = useState(""); + const [timezone, setTimezone] = useState(""); + const [avatar, setAvatar] = useState(""); + const [desc, setDesc] = useState(""); + const [editDesc, setEditDesc] = useState(""); + // more useState, this time to actually handle state + // TODO: name them something more intuitive maybe? + const [editMode, setEditMode] = useState(false); + const [privacyEdit, setPrivacyEdit] = useState(false); + const [privacyView, setPrivacyView] = useState(false); - const { - register: registerPrivacy, - handleSubmit: handleSubmitPrivacy - } = useForm(); + const [errorAlert, setErrorAlert] = useState(false); - const [ user, setUser ] = useState(JSON.parse(localStorage.getItem('user'))); + // this useEffect does a couple of things after the user is gotten from localstorage + useEffect(() => { + // first require the discord markdown parser + const { toHTML } = require("../../Functions/discord-parser.js"); - const [ name, setName ] = useState(""); - const [ tag, setTag ] = useState(""); - const [ timezone, setTimezone ] = useState(""); - const [ avatar, setAvatar ] = useState(""); - const [ desc, setDesc ] = useState(""); - const [ editDesc, setEditDesc ] = useState(""); - - const [ editMode, setEditMode ] = useState(false); - const [ privacyMode, setPrivacyMode ] = useState(false); - const [ privacyView, setPrivacyView ] = useState(false); - - const [ invalidTimezone, setInvalidTimezone ] = useState(false); - const [ errorAlert, setErrorAlert ] = useState(false); - - - useEffect(() => { - const { toHTML } = require('../../Functions/discord-parser.js'); - + // check if there's a name object in user, if it's null, set name to a blank string, otherwise set name to user.name if (user.name) { - setName(user.name); - } else setName(''); + setName(user.name); + } else setName(""); + // same as above, but with the user tag instead if (user.tag) { - setTag(user.tag); - } else setTag(''); + setTag(user.tag); + } else setTag(""); + // same as above but with timezone if (user.tz) { - setTimezone(user.tz); - } else setTimezone(''); + setTimezone(user.tz); + } else setTimezone(""); + // also trims the avatar url so that 1. pngs won't be converted to jpegs and 2. won't be resized to 256x256 if (user.avatar_url) { - var avatarsmall = user.avatar_url.replace('&format=jpeg', ''); - setAvatar(avatarsmall.replace('?width=256&height=256', '')) - } else setAvatar('') + var avatarsmall = user.avatar_url.replace("&format=jpeg", ""); + setAvatar(avatarsmall.replace("?width=256&height=256", "")); + } else setAvatar(""); + // same as above, but with descriptions + // two description variables! one is just the plain description, the other is parsed and converted to html if (user.description) { - setDesc(toHTML(user.description)); - setEditDesc(user.description); - } else { setDesc("(no description)"); - setEditDesc(""); -}}, [user.description, user.tag, user.avatar_url, user.tz, user.name]); - -useEffect(() => { - autosize(document.querySelector('textarea')); -}) - -const submitEdit = data => { - if (data.tz) { - if (!moment.tz.zone(data.tz)) { - setInvalidTimezone(true); - return; - } + setDesc(toHTML(user.description)); + setEditDesc(user.description); + } else { + setDesc("(no description)"); + setEditDesc(""); } + }, [user.description, user.tag, user.avatar_url, user.tz, user.name]); - fetch(`${API_URL}s`,{ - method: 'PATCH', - body: JSON.stringify(data), - headers: { - 'Content-Type': 'application/json', - 'Authorization': JSON.stringify(localStorage.getItem("token")).slice(1, -1) - }}).then (res => res.json() - ).then ( () => { setUser(prevState => {return {...prevState, ...data}}); localStorage.setItem('user', JSON.stringify(user)); setEditMode(false)} - ).catch (error => { - console.error(error); - setErrorAlert(true); - }) + // this just resizes the textarea when filled with larger amounts of text + useEffect(() => { + autosize(document.querySelector("textarea")); + }); - } + if (match) return null; -const submitPrivacy = data => { - fetch(`${API_URL}s`,{ - method: 'PATCH', - body: JSON.stringify(data), - headers: { - 'Content-Type': 'application/json', - 'Authorization': JSON.stringify(localStorage.getItem("token")).slice(1, -1) - }}).then (res => res.json() - ).then (data => { setUser(prevState => {return {...prevState, ...data}}); localStorage.setItem('user', JSON.stringify(user)); setPrivacyMode(false)} - ).catch (error => { - console.error(error); - setErrorAlert(true); - }) -} - - if (match) return null; - - return ( - - - {name} ({user.id}) - { user.avatar_url ? } className="avatar" modal> - {close => ( -
close()}> - -
- )} -
: - } -
- - { errorAlert ? Something went wrong, please try logging in and out again. : "" } - { editMode ? - - Note: if you refresh the page, the old data might show up again, this is due to the bot caching data.
- Try editing a member to clear the cache, or wait a few minutes before refreshing.
- - - Name: - - - - Tag: - - - - Timezone: - - { invalidTimezone ? Please enter a valid timezone : "" } - - - Avatar url: - - - - - Description: - - - setEditMode(false)}>Cancel Submit -
: - <> - ID: {user.id} - Tag: {tag} - Timezone: {timezone} - { privacyView ? "" : Privacy: setPrivacyView(true)}>View } - - { privacyMode ? -
-
Editing privacy settings
- - - Description: - - - - - - - Member list: - - - - - - - Front: - - - - - - - Front history: - - - - - - - setPrivacyMode(false)}>Cancel Submit -
-
: privacyView ? <>
-
Viewing privacy settings
+ return ( + + + + {name} ({user.id}) + + {user.avatar_url ? ( + + } + className="avatar" + modal + > + {(close) => ( +
close()}> + +
+ )} +
+ ) : ( + + )} +
+ + {errorAlert ? ( + + Something went wrong, please try logging in and out again. + + ) : ( + "" + )} + {editMode ? ( + + ) : ( + <> - Description: {user.description_privacy} - Member list: {user.member_list_privacy} - Front: {user.front_privacy} - Front history: {user.front_history_privacy} + + ID: {user.id} + + + Tag: {tag} + + + Timezone: {timezone} + + {privacyView ? ( + "" + ) : ( + + Privacy:{" "} + setPrivacyView(true)} + > + View + + + )} - setPrivacyView(false)}>Exit setPrivacyMode(true)}>Edit -
: "" } -

Description:

- { localStorage.getItem('twemoji') ?

:

} - { privacyMode ? "" : privacyView ? "" : <> setEditMode(true)}>Edit history.push(`/pk-webs/profile/${user.id}`)}>Profile} } -
-
- ) + {privacyEdit ? ( + + ) : privacyView ? ( + <> +
+
Viewing privacy settings
+ + + Description: {user.description_privacy} + + + Member list: + {user.member_list_privacy} + + + Front: {user.front_privacy} + + + Front history: {user.front_history_privacy} + + + setPrivacyView(false)} + > + Exit + {" "} + setPrivacyEdit(true)} + > + Edit + +
+ + ) : ( + "" + )} +

+ Description: +

+ {localStorage.getItem("twemoji") ? ( + +

+
+ ) : ( +

+ )} + {privacyEdit ? ( + "" + ) : privacyView ? ( + "" + ) : ( + <> + setEditMode(true)}> + Edit + + history.push(`/pk-webs/profile/${user.id}`)} + > + Profile + + + )} + + )} +
+
+ ); } - - - - \ No newline at end of file