Add system editing
This commit is contained in:
parent
d30136fba2
commit
e421222002
@ -1 +1 @@
|
||||
[{"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js":"1","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js":"2","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js":"3","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js":"4","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js":"5","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js":"6","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js":"7","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js":"8","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js":"9","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js":"10","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js":"11"},{"size":329,"mtime":1607554515255,"results":"12","hashOfConfig":"13"},{"size":87,"mtime":1607504507181,"results":"14","hashOfConfig":"13"},{"size":3584,"mtime":1607633174709,"results":"15","hashOfConfig":"13"},{"size":297,"mtime":1607504507172,"results":"16","hashOfConfig":"13"},{"size":73,"mtime":1607504507180,"results":"17","hashOfConfig":"13"},{"size":231,"mtime":1607504507174,"results":"18","hashOfConfig":"13"},{"size":1184,"mtime":1607611170429,"results":"19","hashOfConfig":"13"},{"size":1745,"mtime":1607611132497,"results":"20","hashOfConfig":"13"},{"size":2160,"mtime":1607534877891,"results":"21","hashOfConfig":"13"},{"size":11973,"mtime":1607644188505,"results":"22","hashOfConfig":"13"},{"size":10382,"mtime":1607549930730,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"1uc84gl",{"filePath":"27","messages":"28","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"31","messages":"32","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"33","messages":"34","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"35","messages":"36","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"37","messages":"38","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"39","messages":"40","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"41","messages":"42","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"43","messages":"44","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"45","messages":"46","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js",[],["47","48"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js",["49","50"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js",[],{"ruleId":"51","replacedBy":"52"},{"ruleId":"53","replacedBy":"54"},{"ruleId":"55","severity":1,"message":"56","line":7,"column":8,"nodeType":"57","messageId":"58","endLine":7,"endColumn":15},{"ruleId":"55","severity":1,"message":"59","line":15,"column":37,"nodeType":"57","messageId":"58","endLine":15,"endColumn":43},"no-native-reassign",["60"],"no-negated-in-lhs",["61"],"no-unused-vars","'Loading' is defined but never used.","Identifier","unusedVar","'errors' is assigned a value but never used.","no-global-assign","no-unsafe-negation"]
|
||||
[{"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js":"1","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js":"2","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js":"3","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js":"4","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js":"5","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js":"6","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js":"7","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js":"8","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js":"9","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js":"10","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js":"11"},{"size":329,"mtime":1607554515255,"results":"12","hashOfConfig":"13"},{"size":87,"mtime":1607504507181,"results":"14","hashOfConfig":"13"},{"size":3538,"mtime":1607700904518,"results":"15","hashOfConfig":"13"},{"size":243,"mtime":1607696817140,"results":"16","hashOfConfig":"13"},{"size":73,"mtime":1607504507180,"results":"17","hashOfConfig":"13"},{"size":231,"mtime":1607504507174,"results":"18","hashOfConfig":"13"},{"size":1217,"mtime":1607697726792,"results":"19","hashOfConfig":"13"},{"size":9718,"mtime":1607700749075,"results":"20","hashOfConfig":"13"},{"size":2165,"mtime":1607696817853,"results":"21","hashOfConfig":"13"},{"size":12296,"mtime":1607700619400,"results":"22","hashOfConfig":"13"},{"size":10382,"mtime":1607549930730,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1uc84gl",{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"30","messages":"31","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"34","messages":"35","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"38","messages":"39","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"40","messages":"41","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"44"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\History.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\App.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Dash.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Constants\\constants.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Loading.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Navigation.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\System.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js",[],["47","48"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js",[],{"ruleId":"49","replacedBy":"50"},{"ruleId":"51","replacedBy":"52"},"no-native-reassign",["53"],"no-negated-in-lhs",["54"],"no-global-assign","no-unsafe-negation"]
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -9719,6 +9719,14 @@
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
},
|
||||
"moment-timezone": {
|
||||
"version": "0.5.32",
|
||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.32.tgz",
|
||||
"integrity": "sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==",
|
||||
"requires": {
|
||||
"moment": ">= 2.9.0"
|
||||
}
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
|
@ -12,6 +12,7 @@
|
||||
"bootstrap": "^4.5.3",
|
||||
"discord-markdown": "^2.4.1",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.32",
|
||||
"node-fetch": "^2.6.1",
|
||||
"node-sass": "^4.14.1",
|
||||
"react": "^17.0.1",
|
||||
|
@ -6,9 +6,14 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="A web interface for pluralkit."
|
||||
content="(This is still a work in progress)"
|
||||
name="application-name"
|
||||
content="pk-webs"
|
||||
/>
|
||||
<meta
|
||||
name="description"
|
||||
content="A web interface for pluralkit. (This is still a work in progress)"
|
||||
/>
|
||||
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
|
@ -61,11 +61,11 @@ export default function App() {
|
||||
|
||||
return (
|
||||
<Router history={history} basename="/pk-webs">
|
||||
<Navigation isSubmit={isSubmit} setIsSubmit={setIsSubmit} />
|
||||
<Navigation/>
|
||||
<BS.Container>
|
||||
<Switch>
|
||||
<Route path="/pk-webs/dash" >
|
||||
{ !localStorage.getItem('token') || isInvalid ? <Redirect to="/pk-webs"/> : <Dash/>
|
||||
{ !localStorage.getItem('token') || isInvalid ? <Redirect to="/pk-webs"/> : <Dash />
|
||||
}
|
||||
</Route>
|
||||
<Route exact path="/pk-webs">
|
||||
|
@ -6,7 +6,7 @@ import Memberlist from './Memberlist.js'
|
||||
export default function Dash(props) {
|
||||
|
||||
return (<>
|
||||
<System user submit={props.submit} setSubmit={props.setSubmit}/>
|
||||
<System />
|
||||
<Memberlist />
|
||||
</>
|
||||
);
|
||||
|
@ -4,7 +4,6 @@ import { useForm, Controller } from "react-hook-form";
|
||||
import autosize from 'autosize';
|
||||
import moment from 'moment';
|
||||
|
||||
import Loading from "./Loading.js";
|
||||
import API_URL from "../Constants/constants.js";
|
||||
|
||||
import defaultAvatar from '../default_discord_avatar.png'
|
||||
@ -12,7 +11,7 @@ import { FaUser } from "react-icons/fa";
|
||||
|
||||
export default function MemberCard(props) {
|
||||
|
||||
const { register, handleSubmit, errors, control } = useForm();
|
||||
const { register, handleSubmit, control } = useForm();
|
||||
|
||||
const [member, setMember] = useState(props.member);
|
||||
|
||||
@ -28,6 +27,8 @@ export default function MemberCard(props) {
|
||||
const [ editMode, setEditMode ] = useState(false);
|
||||
const [ privacyMode, setPrivacyMode ] = useState(false);
|
||||
const [ privacyView, setPrivacyView ] = useState(false);
|
||||
|
||||
const [ errorAlert, setErrorAlert ] = useState(false);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
@ -41,10 +42,10 @@ export default function MemberCard(props) {
|
||||
setBirthdate(member.birthday)
|
||||
if (member.birthday.startsWith('0004-')) {
|
||||
var bday = member.birthday.replace('0004-','');
|
||||
var bdaymoment = moment(bday, 'MM DD').format('MMM D');
|
||||
var bdaymoment = moment(bday, 'MM-DD').format('MMM D');
|
||||
setBirthday(bdaymoment);
|
||||
} else {
|
||||
var birthdaymoment = moment(bday, 'YYYY MM DD').format('MMM D, YYYY');
|
||||
var birthdaymoment = moment(member.birthday, 'YYYY-MM-DD').format('MMM D, YYYY');
|
||||
setBirthday(birthdaymoment);
|
||||
}
|
||||
} else { setBirthday('');
|
||||
@ -61,8 +62,7 @@ export default function MemberCard(props) {
|
||||
|
||||
if (member.color) {
|
||||
setColor(member.color);
|
||||
} else { setColor('');
|
||||
}
|
||||
} else setColor('');
|
||||
|
||||
if (member.description) {
|
||||
setDesc(toHTML(member.description));
|
||||
@ -78,7 +78,6 @@ export default function MemberCard(props) {
|
||||
})
|
||||
|
||||
const submitEdit = data => {
|
||||
|
||||
fetch(`${API_URL}m/${member.id}`,{
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
@ -86,14 +85,14 @@ export default function MemberCard(props) {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': JSON.stringify(localStorage.getItem("token")).slice(1, -1)
|
||||
}}).then (res => res.json()
|
||||
).then (data => setMember(data), setEditMode(false)
|
||||
).catch (error => {
|
||||
console.error(error);
|
||||
})
|
||||
).then (data => { setMember(prevState => {return {...prevState, ...data}}); setEditMode(false)}
|
||||
).catch (error => {
|
||||
console.error(error);
|
||||
setErrorAlert(true);
|
||||
});
|
||||
}
|
||||
|
||||
const submitPrivacy = data => {
|
||||
|
||||
fetch(`${API_URL}m/${member.id}`,{
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
@ -101,49 +100,50 @@ export default function MemberCard(props) {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': JSON.stringify(localStorage.getItem("token")).slice(1, -1)
|
||||
}}).then (res => res.json()
|
||||
).then (data => setMember(data),
|
||||
setPrivacyMode(false)
|
||||
).catch (error => {
|
||||
console.error(error);
|
||||
})
|
||||
).then (data => { setMember(prevState => {return {...prevState, ...data}}); setPrivacyMode(false)}
|
||||
).catch (error => {
|
||||
console.error(error);
|
||||
setErrorAlert(true);
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BS.Accordion.Toggle className="d-flex align-items-center justify-content-between" as={BS.Card.Header} eventKey={member.id}>
|
||||
<BS.Card.Title className="float-left"><FaUser className="mr-4" /> <b>{member.name}</b> ({member.id})</BS.Card.Title>
|
||||
<>
|
||||
<BS.Card.Header className="d-flex align-items-center justify-content-between">
|
||||
<BS.Accordion.Toggle as={BS.Button} variant="link" eventKey={member.id} className="float-left"><FaUser className="mr-4" /> <b>{member.name}</b> ({member.id})</BS.Accordion.Toggle>
|
||||
{ member.avatar_url ? <BS.Image src={`${member.avatar_url}`} style={{width: 50, height: 50}} className="float-right" roundedCircle /> :
|
||||
<BS.Image src={defaultAvatar} style={{width: 50, height: 50}} className="float-right" roundedCircle />}
|
||||
</BS.Accordion.Toggle>
|
||||
<BS.Image src={defaultAvatar} style={{width: 50, height: 50}} className="float-right" roundedCircle />}
|
||||
</BS.Card.Header>
|
||||
<BS.Accordion.Collapse eventKey={member.id}>
|
||||
<BS.Card.Body style={{borderLeft: `5px solid #${color}` }}>
|
||||
{ errorAlert ? <BS.Alert variant="danger">Something went wrong, please try logging in and out again.</BS.Alert> : "" }
|
||||
{ editMode ?
|
||||
<BS.Form onSubmit={handleSubmit(submitEdit)}>
|
||||
<BS.Form.Row>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Name:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control placeholder={member.name}/>} name="name" control={control}/>
|
||||
<Controller as={<BS.Form.Control />} name="name" control={control} defaultValue={member.name} />
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>AKA: </BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control placeholder={displayName}/>} name="display_name" control={control}/>
|
||||
<Controller as={<BS.Form.Control />} name="display_name" control={control} defaultValue={displayName} />
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Birthday:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control placeholder={birthdate} pattern="/^\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/g"/>} name="birthday" control={control}/>
|
||||
<Controller as={<BS.Form.Control pattern="^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$"/>} name="birthday" control={control} defaultValue={birthdate}/>
|
||||
<BS.Form.Text>(YYYY-MM-DD)</BS.Form.Text>
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Pronouns:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control placeholder={pronouns}/>} name="pronouns" control={control}/>
|
||||
<Controller as={<BS.Form.Control/>} name="pronouns" control={control} defaultValue={pronouns} />
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Avatar url:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control type="url" placeholder={avatar}/>} name="avatar_url" control={control} />
|
||||
<Controller as={<BS.Form.Control type="url"/>} name="avatar_url" control={control} defaultValue={avatar} />
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Color:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control placeholder={color} pattern="/[A-Fa-f0-9]{6}$/g"/>} name="color" control={control}/>
|
||||
<Controller as={<BS.Form.Control pattern="[A-Fa-f0-9]{6}"/>} name="color" control={control} defaultValue={color} />
|
||||
<BS.Form.Text>(hexcode)</BS.Form.Text>
|
||||
</BS.Col>
|
||||
</BS.Form.Row>
|
||||
@ -203,7 +203,7 @@ export default function MemberCard(props) {
|
||||
<option>private</option>
|
||||
</BS.Form.Control>
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Col className="mb-3" xs={12} lg={3}>
|
||||
<BS.Form.Label>Meta:</BS.Form.Label>
|
||||
<BS.Form.Control name="metadata_privacy" as="select" ref={register}>
|
||||
<option>public</option>
|
||||
@ -221,9 +221,9 @@ export default function MemberCard(props) {
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Description:</b> {member.description_privacy}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Birthday:</b> {member.birthday_privacy}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Pronouns:</b> {member.pronoun_privacy}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Meta:</b> {member.metadata_privacy}</BS.Col>
|
||||
<BS.Col className="mb-3" xs={12} lg={3}><b>Meta:</b> {member.metadata_privacy}</BS.Col>
|
||||
</BS.Row>
|
||||
<BS.Button variant="light" onClick={() => setPrivacyView(false)}>Cancel</BS.Button> <BS.Button variant="primary" onClick={() => setPrivacyMode(true)}>Edit</BS.Button>
|
||||
<BS.Button variant="light" onClick={() => setPrivacyView(false)}>Exit</BS.Button> <BS.Button variant="primary" onClick={() => setPrivacyMode(true)}>Edit</BS.Button>
|
||||
<hr/></> : "" }
|
||||
<p><b>Description:</b></p>
|
||||
<p dangerouslySetInnerHTML={{__html: desc}}></p>
|
||||
|
@ -5,7 +5,7 @@ import MemberCard from './MemberCard.js'
|
||||
import Loading from "./Loading.js";
|
||||
import API_URL from "../Constants/constants.js";
|
||||
|
||||
export default function Memberlist() {
|
||||
export default function Memberlist(props) {
|
||||
|
||||
const user = JSON.parse(localStorage.getItem('user'));
|
||||
const userId = user.id;
|
||||
@ -44,8 +44,8 @@ export default function Memberlist() {
|
||||
}
|
||||
return false;
|
||||
}).sort((a, b) => a.name.localeCompare(b.name)).map((member) => <BS.Card key={member.id}>
|
||||
<MemberCard
|
||||
member={member}
|
||||
<MemberCard
|
||||
member={member}
|
||||
/>
|
||||
</BS.Card>
|
||||
);
|
||||
|
@ -4,15 +4,16 @@ import Toggle from 'react-toggle'
|
||||
import { FaSun, FaMoon } from "react-icons/fa";
|
||||
|
||||
import "react-toggle/style.css"
|
||||
import history from "../History.js";
|
||||
|
||||
export default function Navigation(props) {
|
||||
export default function Navigation() {
|
||||
|
||||
const darkMode = useDarkMode(false);
|
||||
|
||||
function logOut() {
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("user");
|
||||
props.setIsSubmit(false);
|
||||
history.push('/pk-webs');
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,21 +1,98 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import * as BS from 'react-bootstrap'
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import autosize from 'autosize';
|
||||
import moment from 'moment';
|
||||
import 'moment-timezone';
|
||||
|
||||
import API_URL from "../Constants/constants.js";
|
||||
|
||||
import { FaAddressCard } from "react-icons/fa";
|
||||
import defaultAvatar from '../default_discord_avatar.png'
|
||||
import { FaAddressCard } from "react-icons/fa";
|
||||
|
||||
export default function System(props) {
|
||||
|
||||
const { register, handleSubmit,control } = useForm();
|
||||
|
||||
const [ user, setUser ] = useState(JSON.parse(localStorage.getItem('user')));
|
||||
|
||||
const [ tag, setTag ] = useState("");
|
||||
const [ timezone, setTimezone ] = useState("");
|
||||
const [ avatar, setAvatar ] = useState("");
|
||||
const [ desc, setDesc ] = useState("");
|
||||
const user = JSON.parse(localStorage.getItem("user"));
|
||||
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');
|
||||
|
||||
if (user.tag) {
|
||||
setTag(user.tag);
|
||||
} else setTag('');
|
||||
|
||||
if (user.tz) {
|
||||
setTimezone(user.tz);
|
||||
} else setTimezone('');
|
||||
|
||||
if (user.avatar_url) {
|
||||
setAvatar(user.avatar_url)
|
||||
} else setAvatar('')
|
||||
|
||||
if (user.description) {
|
||||
setDesc(toHTML(user.description));
|
||||
} else setDesc("(no description)");
|
||||
}, [user.description]);
|
||||
setEditDesc(user.description);
|
||||
} else { setDesc("(no description)");
|
||||
setEditDesc("");
|
||||
}}, [user.description, user.tag, user.avatar_url, user.tz]);
|
||||
|
||||
useEffect(() => {
|
||||
autosize(document.querySelector('textarea'));
|
||||
})
|
||||
|
||||
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 ( data => { setUser(prevState => {return {...prevState, ...data}}); localStorage.setItem('user', JSON.stringify(user)); setEditMode(false)}
|
||||
).catch (error => {
|
||||
console.error(error);
|
||||
setErrorAlert(true);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<BS.Card className="mb-3 mt-3 w-100" >
|
||||
@ -25,13 +102,89 @@ export default function System(props) {
|
||||
<BS.Image src={defaultAvatar} style={{width: 50, height: 50}} className="float-right" roundedCircle />}
|
||||
</BS.Card.Header>
|
||||
<BS.Card.Body>
|
||||
<BS.Row>
|
||||
{ errorAlert ? <BS.Alert variant="danger">Something went wrong, please try logging in and out again.</BS.Alert> : "" }
|
||||
{ editMode ?
|
||||
<BS.Form onSubmit={handleSubmit(submitEdit)}>
|
||||
{/* <BS.Form.Text className='mb-4'>Note: changes here may take a while to be reflected on the bot. This is due to the bot caching data.<br/> Try editing a member after to make the changes show up.</BS.Form.Text> */}
|
||||
<BS.Form.Row>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Name:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control/>} name="name" control={control} defaultValue={user.name}/>
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Tag:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control/>} name="y" control={control} defaultValue={tag}/>
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Timezone:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control/>} name="tz" control={control} defaultValue={timezone}/>
|
||||
{ invalidTimezone ? <BS.Form.Text>Please enter a valid <a href='https://xske.github.io/tz/' rel="noreferrer" target="_blank">timezone</a></BS.Form.Text> : "" }
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Avatar url:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control/>} name="avatar_url" control={control} defaultValue={avatar}/>
|
||||
</BS.Col>
|
||||
</BS.Form.Row>
|
||||
<BS.Form.Group className="mt-3">
|
||||
<BS.Form.Label>Description:</BS.Form.Label>
|
||||
<Controller as={<BS.Form.Control maxLength="1000" as="textarea" />} name="description" control={control} defaultValue={editDesc}/>
|
||||
</BS.Form.Group>
|
||||
<BS.Button variant="light" onClick={() => setEditMode(false)}>Cancel</BS.Button> <BS.Button variant="primary" type="submit">Submit</BS.Button>
|
||||
</BS.Form> :
|
||||
<><BS.Row>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>ID:</b> {user.id}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Tag:</b> {user.tag}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Timezone:</b> {user.tz}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Tag:</b> {tag}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Timezone:</b> {timezone}</BS.Col>
|
||||
{ privacyView ? "" : <BS.Col className="mb-lg-3" xs={12} lg={3}><b>Privacy:</b> <BS.Button variant="light" size="sm" onClick={() => setPrivacyView(true)}>View</BS.Button></BS.Col> }
|
||||
</BS.Row>
|
||||
{ privacyMode ? <BS.Form onSubmit={handleSubmit(submitPrivacy)}>
|
||||
<hr/>
|
||||
<h5>Editing privacy settings</h5>
|
||||
<BS.Form.Row>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Description:</BS.Form.Label>
|
||||
<BS.Form.Control name="description_privacy" as="select" ref={register}>
|
||||
<option>public</option>
|
||||
<option>private</option>
|
||||
</BS.Form.Control>
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Member list:</BS.Form.Label>
|
||||
<BS.Form.Control name="member_list_privacy" as="select" ref={register}>
|
||||
<option>public</option>
|
||||
<option>private</option>
|
||||
</BS.Form.Control>
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Front:</BS.Form.Label>
|
||||
<BS.Form.Control name="front_privacy" as="select" ref={register}>
|
||||
<option>public</option>
|
||||
<option>private</option>
|
||||
</BS.Form.Control>
|
||||
</BS.Col>
|
||||
<BS.Col className="mb-lg-2" xs={12} lg={3}>
|
||||
<BS.Form.Label>Front history:</BS.Form.Label>
|
||||
<BS.Form.Control name="front_history_privacy" as="select" ref={register}>
|
||||
<option>public</option>
|
||||
<option>private</option>
|
||||
</BS.Form.Control>
|
||||
</BS.Col>
|
||||
</BS.Form.Row>
|
||||
<BS.Button variant="light" onClick={() => setPrivacyMode(false)}>Cancel</BS.Button> <BS.Button variant="primary" type="submit">Submit</BS.Button>
|
||||
<hr/>
|
||||
</BS.Form> : privacyView ? <><hr/>
|
||||
<h5>Viewing privacy settings</h5>
|
||||
<BS.Row>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Description:</b> {user.description_privacy}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Member list: </b>{user.member_list_privacy}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Front:</b> {user.front_privacy}</BS.Col>
|
||||
<BS.Col className="mb-lg-3" xs={12} lg={3}><b>Front history:</b> {user.front_history_privacy}</BS.Col>
|
||||
</BS.Row>
|
||||
<BS.Button variant="light" onClick={() => setPrivacyView(false)}>Exit</BS.Button> <BS.Button variant="primary" onClick={() => setPrivacyMode(true)}>Edit</BS.Button>
|
||||
<hr/></> : "" }
|
||||
<p><b>Description:</b></p>
|
||||
<p dangerouslySetInnerHTML={{__html: desc}}></p>
|
||||
{ privacyMode ? "" : privacyView ? "" : <BS.Button variant="light" onClick={() => setEditMode(true)}>Edit</BS.Button>}</> }
|
||||
</BS.Card.Body>
|
||||
</BS.Card>
|
||||
)
|
||||
|
@ -69,6 +69,40 @@
|
||||
color: $gray-100;
|
||||
}
|
||||
|
||||
.card-header .btn-link {
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
.card-header .btn-link:focus {
|
||||
color: $gray-900;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card-header .btn-link:hover {
|
||||
color: $gray-900;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
.card-header .btn-link {
|
||||
font-size: 1.25rem !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.dark-mode .btn-link {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.dark-mode .btn-link:focus {
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.dark-mode .btn-link:hover {
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.dark-mode .alert-danger {
|
||||
color: $white;
|
||||
background-color: $danger;
|
||||
|
Loading…
x
Reference in New Issue
Block a user