From 3c82738025cda59cb4f827e1666edc91ba8102a4 Mon Sep 17 00:00:00 2001 From: Spectralitree Date: Wed, 6 Jan 2021 00:05:23 +0100 Subject: [PATCH] add individual member pages --- .eslintcache | 2 +- src/Components/MemberCard.js | 16 +- src/Components/MemberPage.js | 395 +++++++++++++++++++++++++++++++++ src/Components/MemberPages.js | 15 ++ src/Components/Memberlist.js | 23 +- src/Components/Profile.js | 7 +- src/Components/ProfileCard.js | 12 +- src/Components/ProfileList.js | 17 +- src/Components/ProfilePage.js | 112 ++++++++++ src/Components/ProfilePages.js | 15 ++ src/Components/System.js | 5 + src/Custom.scss | 49 +++- 12 files changed, 644 insertions(+), 24 deletions(-) create mode 100644 src/Components/MemberPage.js create mode 100644 src/Components/MemberPages.js create mode 100644 src/Components/ProfilePage.js create mode 100644 src/Components/ProfilePages.js diff --git a/.eslintcache b/.eslintcache index 2e11b89e..d9f0a068 100644 --- a/.eslintcache +++ b/.eslintcache @@ -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\\System.js":"7","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js":"8","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js":"9","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js":"10","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Footer.js":"11","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Profile.js":"12","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Public.js":"13","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileList.js":"14","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileCard.js":"15"},{"size":329,"mtime":1607895960007,"results":"16","hashOfConfig":"17"},{"size":87,"mtime":1607504507181,"results":"18","hashOfConfig":"17"},{"size":8418,"mtime":1607984579751,"results":"19","hashOfConfig":"17"},{"size":243,"mtime":1607696817140,"results":"20","hashOfConfig":"17"},{"size":73,"mtime":1607504507180,"results":"21","hashOfConfig":"17"},{"size":231,"mtime":1607504507174,"results":"22","hashOfConfig":"17"},{"size":11009,"mtime":1608047298479,"results":"23","hashOfConfig":"17"},{"size":17663,"mtime":1609808956867,"results":"24","hashOfConfig":"17"},{"size":20797,"mtime":1609808618083,"results":"25","hashOfConfig":"17"},{"size":10382,"mtime":1607549930730,"results":"26","hashOfConfig":"17"},{"size":741,"mtime":1607964943027,"results":"27","hashOfConfig":"17"},{"size":3953,"mtime":1608044855021,"results":"28","hashOfConfig":"17"},{"size":1636,"mtime":1607976735762,"results":"29","hashOfConfig":"17"},{"size":8206,"mtime":1609808971716,"results":"30","hashOfConfig":"17"},{"size":5518,"mtime":1609808743974,"results":"31","hashOfConfig":"17"},{"filePath":"32","messages":"33","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},"1uc84gl",{"filePath":"35","messages":"36","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"37","messages":"38","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"39","messages":"40","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"41","messages":"42","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"43","messages":"44","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"47","messages":"48","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"49","usedDeprecatedRules":"34"},{"filePath":"50","messages":"51","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"52","messages":"53","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"54","messages":"55","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"56","messages":"57","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"58","messages":"59","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"34"},{"filePath":"60","messages":"61","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"62","usedDeprecatedRules":"34"},{"filePath":"63","messages":"64","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\index.js",[],["65","66"],"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\\System.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js",["67"],"import React, { useEffect, useState, useCallback } from 'react';\r\nimport * as BS from 'react-bootstrap'\r\nimport Popup from 'reactjs-popup';\r\nimport 'reactjs-popup/dist/index.css';\r\nimport { useForm } from \"react-hook-form\";\r\n\r\nimport MemberCard from './MemberCard.js'\r\nimport Loading from \"./Loading.js\";\r\nimport API_URL from \"../Constants/constants.js\";\r\n\r\nimport { FaPlus } from \"react-icons/fa\";\r\n\r\nexport default function Memberlist(props) {\r\n \r\n const user = JSON.parse(localStorage.getItem('user'));\r\n const userId = user.id;\r\n\r\n const [isLoading, setIsLoading ] = useState(false);\r\n const [isError, setIsError ] = useState(false);\r\n const [errorAlert, setErrorAlert ] = useState(false);\r\n\r\n const [proxyView, setProxyView] = useState(false);\r\n const [privacyView, setPrivacyView] = useState(false);\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [membersPerPage, setMembersPerPage] = useState(25);\r\n\r\n const [open, setOpen] = useState(false);\r\n const closeModal = () => setOpen(false);\r\n\r\n const [members, setMembers ] = useState([]);\r\n const [memberData, setMemberData ] = useState([]);\r\n const [filteredMembers, setFilteredMembers ] = useState([]);\r\n const [sortedMembers, setSortedMembers ] = useState([]);\r\n\r\n const [searchBy, setSearchBy] = useState('name')\r\n const [sortBy, setSortBy] = useState('name')\r\n\r\n const [value, setValue] = useState('');\r\n const [proxyTags, setProxyTags] = useState([{\r\n prefix: \"\", suffix: \"\"\r\n }]);\r\n\r\n const {register, handleSubmit} = useForm();\r\n\r\n const fetchMembers = useCallback( () => {\r\n setIsLoading(true);\r\n setIsError(false);\r\n setMembersPerPage(25);\r\n\r\n fetch(`${API_URL}s/${userId}/members`,{\r\n method: 'GET',\r\n headers: {\r\n 'Authorization': JSON.stringify(localStorage.getItem(\"token\")).slice(1, -1)\r\n }}).then ( res => res.json()\r\n ).then (data => { \r\n setMembers(data)\r\n setIsLoading(false);\r\n })\r\n .catch (error => { \r\n console.log(error);\r\n setIsError(true);\r\n setIsLoading(false);\r\n })\r\n }, [userId])\r\n\r\n useEffect(() => {\r\n fetchMembers();\r\n }, [fetchMembers])\r\n\r\n useEffect(() => {\r\n let Members = members.map(member => {\r\n if (member.display_name) {\r\n return {...member, displayName: member.display_name}\r\n } return {...member, displayName: member.name}\r\n }) \r\n let Members1 = Members.map(member => {\r\n if (member.description) {\r\n return {...member, desc: member.description}\r\n } return {...member, desc: \"(no description)\"}\r\n })\r\n setMemberData(Members1);\r\n }, [members])\r\n\r\n function addProxyField() {\r\n setProxyTags(oldTags => [...oldTags, {prefix: '', suffix: ''}] )\r\n }\r\n\r\n const submitMember = data => {\r\n setIsLoading(true);\r\n\r\n const newdata = data.proxy_tags ? {...data, proxy_tags: data.proxy_tags.filter(tag => !(tag.prefix === \"\" && tag.suffix === \"\"))} : data\r\n\r\n fetch(`${API_URL}m/`,{\r\n method: 'POST',\r\n body: JSON.stringify(newdata),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': JSON.stringify(localStorage.getItem(\"token\")).slice(1, -1)\r\n }}).then (res => res.json()\r\n ).then (data => { \r\n setErrorAlert(false);\r\n closeModal();\r\n }\r\n ).catch (error => {\r\n console.error(error);\r\n setErrorAlert(true);\r\n });\r\n }\r\n\r\n const indexOfLastMember = currentPage * membersPerPage;\r\n const indexOfFirstMember = indexOfLastMember - membersPerPage;\r\n \r\n useEffect(() => {\r\n searchMembers();\r\n }, [value, memberData, searchBy])\r\n\r\n function searchMembers() {\r\n const currentMembers = memberData.filter(member => {\r\n if (!value) return true;\r\n \r\n if (searchBy === 'name') {\r\n if (member.name.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false;\r\n } else if (searchBy === 'display name') {\r\n if (member.displayName.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false\r\n } else if (searchBy === 'description') {\r\n if (member.desc.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false;\r\n } else if (searchBy === 'ID') {\r\n if (member.id.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n return false;\r\n })\r\n setFilteredMembers(currentMembers);\r\n }\r\n\r\n useEffect (() => { \r\n if (sortBy === 'name') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.name.localeCompare(b.name)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n } else if (sortBy === 'display name') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.displayName.localeCompare(b.displayName)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n } else if (sortBy === 'ID') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.id.localeCompare(b.id)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n } else if (sortBy === 'date created') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.created.localeCompare(b.created)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n }\r\n }, [sortBy, filteredMembers, indexOfFirstMember, indexOfLastMember])\r\n \r\n\r\n\r\n const active = currentPage;\r\n const pageAmount = Math.ceil(filteredMembers.length / membersPerPage);\r\n \r\n const memberList = sortedMembers.map((member) => \r\n \r\n \r\n );\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n {\r\n setMembersPerPage(e.target.value);\r\n setCurrentPage(1);\r\n }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n setSearchBy(e.target.value)\r\n }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n setSortBy(e.target.value)\r\n }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {setValue(e.target.value); setCurrentPage(1);}} placeholder={`Search by ${searchBy}`}/>\r\n \r\n \r\n \r\n fetchMembers()}>Refresh\r\n \r\n \r\n \r\n \r\n { currentPage === 1 ? : setCurrentPage(currentPage - 1)} />}\r\n { currentPage < 3 ? \"\" : setCurrentPage(1)} active={1 === active}>{1}}\r\n { currentPage < 4 ? \"\" :}\r\n { currentPage > 1 ? setCurrentPage(currentPage - 1)}>{currentPage - 1} : \"\" }\r\n setCurrentPage(currentPage)} active={currentPage === active}>{currentPage}\r\n { currentPage < pageAmount ? setCurrentPage(currentPage + 1)}>{currentPage + 1} : \"\" }\r\n { currentPage > pageAmount - 3 ? \"\" : }\r\n { currentPage > pageAmount - 2 ? \"\" : setCurrentPage(pageAmount)} active={pageAmount === active}>{pageAmount}}\r\n { currentPage === pageAmount ? : setCurrentPage(currentPage + 1)} />}\r\n \r\n \r\n { isLoading ? : isError ? \r\n Error fetching members. :\r\n <>\r\n \r\n \r\n setOpen(o => !o)}>Add Member \r\n \r\n \r\n \r\n \r\n
Add member
\r\n
\r\n \r\n { errorAlert ? Something went wrong, please try logging in and out again. : \"\" }\r\n \r\n \r\n \r\n \r\n \r\n Name:\r\n \r\n \r\n \r\n Display name: \r\n \r\n \r\n \r\n Birthday:\r\n \r\n (YYYY-MM-DD)\r\n \r\n \r\n Pronouns:\r\n \r\n \r\n \r\n Avatar url: \r\n \r\n \r\n \r\n Color: \r\n \r\n (hexcode)\r\n \r\n \r\n Proxy tags: \r\n setProxyView(view => !view)}> { proxyView ? \"Hide\" : \"Show\" }\r\n \r\n \r\n Privacy settings: \r\n setPrivacyView(view => !view)}> { privacyView ? \"Hide\" : \"Show\" }\r\n \r\n \r\n
\r\n { proxyView ? <>\r\n
Proxy Tags
\r\n \r\n { proxyTags.map((item, index) => (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n ))} addProxyField()}>Add new\r\n \r\n
: \"\" }\r\n { privacyView ? <>
privacy settings
\r\n \r\n \r\n Visibility:\r\n \r\n \r\n \r\n \r\n \r\n \r\n Name:\r\n \r\n \r\n \r\n \r\n \r\n \r\n Description:\r\n \r\n \r\n \r\n \r\n \r\n \r\n Birthday:\r\n \r\n \r\n \r\n \r\n \r\n \r\n Pronouns:\r\n \r\n \r\n \r\n \r\n \r\n \r\n Meta:\r\n \r\n \r\n \r\n \r\n \r\n \r\n
: \"\" }\r\n \r\n Description:\r\n \r\n \r\n Submit Cancel\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n {memberList}\r\n \r\n \r\n }\r\n \r\n )\r\n}","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Footer.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Profile.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Public.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileList.js",["68"],"import React, { useEffect, useState, useCallback } from 'react';\r\nimport * as BS from 'react-bootstrap'\r\nimport 'reactjs-popup/dist/index.css';\r\n\r\nimport ProfileCard from './ProfileCard.js'\r\nimport Loading from \"./Loading.js\";\r\nimport API_URL from \"../Constants/constants.js\";\r\n\r\nexport default function Memberlist(props) {\r\n \r\n const sysID = props.sysID;\r\n\r\n const [isLoading, setIsLoading ] = useState(false);\r\n const [isError, setIsError ] = useState(false);\r\n\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [membersPerPage, setMembersPerPage] = useState(25);\r\n\r\n const [members, setMembers ] = useState([]);\r\n const [memberData, setMemberData ] = useState([]);\r\n const [filteredMembers, setFilteredMembers ] = useState([]);\r\n const [sortedMembers, setSortedMembers ] = useState([]);\r\n\r\n const [searchBy, setSearchBy] = useState('name')\r\n const [sortBy, setSortBy] = useState('name')\r\n\r\n const [value, setValue] = useState('');\r\n\r\n const fetchMembers = useCallback( () => {\r\n setIsLoading(true);\r\n setIsError(false);\r\n setMembersPerPage(25);\r\n\r\n fetch(`${API_URL}s/${sysID}/members`,{\r\n method: 'GET',\r\n }).then ( res => res.json()\r\n ).then (data => { \r\n setMembers(data)\r\n setIsLoading(false);\r\n })\r\n .catch (error => { \r\n console.log(error);\r\n setIsError(true);\r\n setIsLoading(false);\r\n })\r\n }, [sysID])\r\n\r\n useEffect(() => {\r\n fetchMembers();\r\n }, [fetchMembers])\r\n\r\n useEffect(() => {\r\n let Members = members.map(member => {\r\n if (member.display_name) {\r\n return {...member, displayName: member.display_name}\r\n } return {...member, displayName: member.name}\r\n }) \r\n let Members1 = Members.map(member => {\r\n if (member.description) {\r\n return {...member, desc: member.description}\r\n } return {...member, desc: \"(no description)\"}\r\n })\r\n setMemberData(Members1);\r\n }, [members])\r\n\r\n const indexOfLastMember = currentPage * membersPerPage;\r\n const indexOfFirstMember = indexOfLastMember - membersPerPage;\r\n\r\n useEffect(() => {\r\n searchMembers();\r\n }, [value, memberData, searchBy])\r\n\r\n function searchMembers() {\r\n const currentMembers = memberData.filter(member => {\r\n if (!value) return true;\r\n \r\n if (searchBy === 'name') {\r\n if (member.name.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false;\r\n } else if (searchBy === 'display name') {\r\n if (member.displayName.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false\r\n } else if (searchBy === 'description') {\r\n if (member.desc.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false;\r\n } else if (searchBy === 'ID') {\r\n if (member.id.toLowerCase().includes(value.toLowerCase())) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n return false;\r\n })\r\n setFilteredMembers(currentMembers);\r\n }\r\n\r\n useEffect (() => { \r\n if (sortBy === 'name') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.name.localeCompare(b.name)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n } else if (sortBy === 'display name') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.displayName.localeCompare(b.displayName)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n } else if (sortBy === 'ID') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.id.localeCompare(b.id)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n } else if (sortBy === 'date created') {\r\n const sortMembers = filteredMembers.sort((a, b) => a.created.localeCompare(b.created)).slice(indexOfFirstMember, indexOfLastMember);\r\n setSortedMembers(sortMembers);\r\n }\r\n }, [sortBy, filteredMembers, indexOfFirstMember, indexOfLastMember])\r\n \r\n\r\n const active = currentPage;\r\n const pageAmount = Math.ceil(filteredMembers.length / membersPerPage);\r\n \r\n const memberList = sortedMembers.map((member) => \r\n \r\n \r\n );\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n {\r\n setMembersPerPage(e.target.value);\r\n setCurrentPage(1);\r\n }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n setSearchBy(e.target.value)\r\n }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n setSortBy(e.target.value)\r\n }}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {setValue(e.target.value); setCurrentPage(1);}} placeholder={`Search by ${searchBy}`}/>\r\n \r\n \r\n \r\n fetchMembers()}>Refresh\r\n \r\n \r\n \r\n \r\n { currentPage === 1 ? : setCurrentPage(currentPage - 1)} />}\r\n { currentPage < 3 ? \"\" : setCurrentPage(1)} active={1 === active}>{1}}\r\n { currentPage < 4 ? \"\" :}\r\n { currentPage > 1 ? setCurrentPage(currentPage - 1)}>{currentPage - 1} : \"\" }\r\n setCurrentPage(currentPage)} active={currentPage === active}>{currentPage}\r\n { currentPage < pageAmount ? setCurrentPage(currentPage + 1)}>{currentPage + 1} : \"\" }\r\n { currentPage > pageAmount - 3 ? \"\" : }\r\n { currentPage > pageAmount - 2 ? \"\" : setCurrentPage(pageAmount)} active={pageAmount === active}>{pageAmount}}\r\n { currentPage === pageAmount ? : setCurrentPage(currentPage + 1)} />}\r\n \r\n \r\n { isLoading ? : isError ? \r\n Error fetching members. :\r\n <>\r\n \r\n {memberList}\r\n \r\n \r\n }\r\n \r\n )\r\n}","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileCard.js",[],{"ruleId":"69","replacedBy":"70"},{"ruleId":"71","replacedBy":"72"},{"ruleId":"73","severity":1,"message":"74","line":115,"column":8,"nodeType":"75","endLine":115,"endColumn":37,"suggestions":"76"},{"ruleId":"73","severity":1,"message":"74","line":71,"column":8,"nodeType":"75","endLine":71,"endColumn":37,"suggestions":"77"},"no-native-reassign",["78"],"no-negated-in-lhs",["79"],"react-hooks/exhaustive-deps","React Hook useEffect has a missing dependency: 'searchMembers'. Either include it or remove the dependency array.","ArrayExpression",["80"],["81"],"no-global-assign","no-unsafe-negation",{"desc":"82","fix":"83"},{"desc":"82","fix":"84"},"Update the dependencies array to be: [value, memberData, searchBy, searchMembers]",{"range":"85","text":"86"},{"range":"87","text":"86"},[3668,3697],"[value, memberData, searchBy, searchMembers]",[2142,2171]] \ No newline at end of file +[{"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\\System.js":"7","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js":"8","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js":"9","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js":"10","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Footer.js":"11","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Profile.js":"12","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Public.js":"13","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileList.js":"14","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileCard.js":"15","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberPage.js":"16","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberPages.js":"17","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfilePages.js":"18","C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfilePage.js":"19"},{"size":329,"mtime":1607895960007,"results":"20","hashOfConfig":"21"},{"size":87,"mtime":1607504507181,"results":"22","hashOfConfig":"21"},{"size":9908,"mtime":1609883106322,"results":"23","hashOfConfig":"21"},{"size":243,"mtime":1609881413764,"results":"24","hashOfConfig":"21"},{"size":73,"mtime":1607504507180,"results":"25","hashOfConfig":"21"},{"size":231,"mtime":1607504507174,"results":"26","hashOfConfig":"21"},{"size":11158,"mtime":1609872701157,"results":"27","hashOfConfig":"21"},{"size":18085,"mtime":1609879377949,"results":"28","hashOfConfig":"21"},{"size":21382,"mtime":1609887806969,"results":"29","hashOfConfig":"21"},{"size":10382,"mtime":1607549930730,"results":"30","hashOfConfig":"21"},{"size":741,"mtime":1607964943027,"results":"31","hashOfConfig":"21"},{"size":4119,"mtime":1609885506592,"results":"32","hashOfConfig":"21"},{"size":1636,"mtime":1607976735762,"results":"33","hashOfConfig":"21"},{"size":8629,"mtime":1609885291967,"results":"34","hashOfConfig":"21"},{"size":6190,"mtime":1609887826406,"results":"35","hashOfConfig":"21"},{"size":21537,"mtime":1609887327569,"results":"36","hashOfConfig":"21"},{"size":429,"mtime":1609876638951,"results":"37","hashOfConfig":"21"},{"size":432,"mtime":1609887849474,"results":"38","hashOfConfig":"21"},{"size":6160,"mtime":1609887364850,"results":"39","hashOfConfig":"21"},{"filePath":"40","messages":"41","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1uc84gl",{"filePath":"42","messages":"43","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"44","messages":"45","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"46","messages":"47","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"48","messages":"49","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"50","messages":"51","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"52","messages":"53","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"54","messages":"55","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"56","messages":"57","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"58","messages":"59","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"60","messages":"61","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"62","messages":"63","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"64","messages":"65","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"66","messages":"67","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"68","messages":"69","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"70","messages":"71","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"72","messages":"73","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"74","messages":"75","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"76","messages":"77","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\\System.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Memberlist.js",["78"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberCard.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Functions\\discord-parser.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Footer.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Profile.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\Public.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileList.js",["79"],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfileCard.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberPage.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\MemberPages.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfilePages.js",[],"C:\\Users\\Fleur\\Desktop\\website projects etc\\pk-web\\src\\Components\\ProfilePage.js",[],{"ruleId":"80","severity":1,"message":"81","line":120,"column":8,"nodeType":"82","endLine":120,"endColumn":37,"suggestions":"83"},{"ruleId":"80","severity":1,"message":"81","line":74,"column":8,"nodeType":"82","endLine":74,"endColumn":37,"suggestions":"84"},"react-hooks/exhaustive-deps","React Hook useEffect has a missing dependency: 'searchMembers'. Either include it or remove the dependency array.","ArrayExpression",["85"],["86"],{"desc":"87","fix":"88"},{"desc":"87","fix":"89"},"Update the dependencies array to be: [value, memberData, searchBy, searchMembers]",{"range":"90","text":"91"},{"range":"92","text":"91"},[3866,3895],"[value, memberData, searchBy, searchMembers]",[2299,2328]] \ No newline at end of file diff --git a/src/Components/MemberCard.js b/src/Components/MemberCard.js index 130b3192..fb67c11f 100644 --- a/src/Components/MemberCard.js +++ b/src/Components/MemberCard.js @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +import { Link } from "react-router-dom"; import * as BS from 'react-bootstrap' import { useForm } from "react-hook-form"; import moment from 'moment'; @@ -203,7 +204,9 @@ export default function MemberCard(props) { memberDeleted ? Member Deleted : - {member.name} ({member.id}) + { localStorage.getItem('pagesonly') ? + {member.name} ({member.id}) + : {member.name} ({member.id})} { member.avatar_url ? } className="avatar" modal> {close => (
close()}> @@ -275,10 +278,11 @@ export default function MemberCard(props) { <> ID: {member.id} - { member.display_name ? Display name: {displayName} : "" } + { member.display_name ? localStorage.getItem('twemoji') ? Display name: {displayName} : + Display name: {displayName} : "" } { member.birthday ? Birthday: {birthday} : "" } { member.pronouns ? localStorage.getItem('twemoji') ? Pronouns: : - Pronouns: : "" } + Pronouns: : "" } { member.color ? Color: {color} : "" } { privacyView ? "" : proxyView ? "" : Privacy: setPrivacyView(true)}>View } { privacyView ? "" : proxyView ? "" : Proxy tags: setProxyView(true)}>View } @@ -359,7 +363,7 @@ export default function MemberCard(props) { { proxyTags.map((item, index) => ( - + @@ -375,13 +379,13 @@ export default function MemberCard(props) { <>
Viewing proxy tags
- { proxyTags.length === 0 ? No proxy tags set. : proxyTags.map((proxytag) => {proxytag.prefix}text{proxytag.suffix} )} + { proxyTags.length === 0 ? No proxy tags set. : proxyTags.map((proxytag, index) => {proxytag.prefix}text{proxytag.suffix} )} setProxyView(false)}>Exit setProxyMode(true)}>Edit
: "" }

Description:

{ localStorage.getItem('twemoji') ?

:

} - { proxyView ? "" : privacyMode ? "" : privacyView ? "" : setEditMode(true)}>Edit} + { proxyView ? "" : privacyMode ? "" : privacyView ? "" : <> setEditMode(true)}>Edit View page } } diff --git a/src/Components/MemberPage.js b/src/Components/MemberPage.js new file mode 100644 index 00000000..1f18be98 --- /dev/null +++ b/src/Components/MemberPage.js @@ -0,0 +1,395 @@ +import React, { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import * as BS from 'react-bootstrap' +import { useForm } from "react-hook-form"; +import moment from 'moment'; +import Popup from 'reactjs-popup'; +import 'reactjs-popup/dist/index.css'; +import autosize from 'autosize'; +import Twemoji from 'react-twemoji'; + +import API_URL from "../Constants/constants.js"; +import history from "../History.js"; + +import defaultAvatar from '../default_discord_avatar.png' +import { FaUser, FaTrashAlt } from "react-icons/fa"; + +export default function MemberPage(props) { + + const [ member, setMember] = useState(props.member); + + const [ displayName, setDisplayName ] = useState(""); + const [ birthday, setBirthday ] = useState(""); + const [ birthdate, setBirthdate ] = useState(""); + const [ pronouns, setPronouns ] = useState(""); + const [ editPronouns, setEditPronouns ] = useState(""); + const [ avatar, setAvatar ] = useState(""); + const [ color, setColor ] = useState(""); + const [ desc, setDesc ] = useState(""); + const [ editDesc, setEditDesc ] = useState(""); + const [ proxyTags, setProxyTags ] = useState(member.proxy_tags); + + const [ editMode, setEditMode ] = useState(false); + const [ privacyMode, setPrivacyMode ] = useState(false); + const [ privacyView, setPrivacyView ] = useState(false); + const [ proxyView, setProxyView ] = useState(false); + const [ proxyMode, setProxyMode ] = useState(false); + + const [open, setOpen] = useState(false); + const closeModal = () => setOpen(false); + + const [ errorAlert, setErrorAlert ] = useState(false); + const [ wrongID, setWrongID ] = useState(false); + const [ memberDeleted, setMemberDeleted ] = useState(false); + + const { + register: registerEdit, + handleSubmit: handleSubmitEdit + } = useForm(); + + const { + register: registerPrivacy, + handleSubmit: handleSubmitPrivacy + } = useForm(); + + const { + register: registerDelete, + handleSubmit: handleSubmitDelete + } = useForm(); + + const { + register: registerProxy, + handleSubmit: handleSubmitProxy, + } = useForm(); + + useEffect(() => { + autosize(document.querySelector('textarea')); + }) + + useEffect(() => { + const { toHTML } = require('../Functions/discord-parser.js'); + + if (member.display_name) { + setDisplayName(member.display_name) + } else setDisplayName('') + + if (member.birthday) { + setBirthdate(member.birthday) + if (member.birthday.startsWith('0004-')) { + var bday = member.birthday.replace('0004-',''); + var bdaymoment = moment(bday, 'MM-DD').format('MMM D'); + setBirthday(bdaymoment); + } else { + var birthdaymoment = moment(member.birthday, 'YYYY-MM-DD').format('MMM D, YYYY'); + setBirthday(birthdaymoment); + } + } else { setBirthday(''); + setBirthdate(''); + } + + if (member.pronouns) { + setPronouns(toHTML(member.pronouns)); + setEditPronouns(member.pronouns); + } else { setPronouns(''); + setEditPronouns(''); + } + + if (member.avatar_url) { + var avatarsmall = member.avatar_url.replace('&format=jpeg', ''); + setAvatar(avatarsmall.replace('?width=256&height=256', '')) + } else setAvatar('') + + if (member.color) { + setColor(member.color); + } else setColor(''); + + if (member.description) { + setDesc(toHTML(member.description)); + setEditDesc(member.description); + } else { setDesc("(no description)"); + setEditDesc(""); + } + }, [member.description, member.color, member.birthday, member.display_name, member.pronouns, member.avatar_url, member.proxy_tags]); + + const submitEdit = data => { + fetch(`${API_URL}m/${member.id}`,{ + 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 => { + setMember(prevState => {return {...prevState, ...data}}); + setErrorAlert(false); + setEditMode(false); + } + ).catch (error => { + console.error(error); + setErrorAlert(true); + }); + } + + const submitPrivacy = data => { + fetch(`${API_URL}m/${member.id}`,{ + 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 => { + setMember(prevState => {return {...prevState, ...data}}); + setErrorAlert(false); + setPrivacyMode(false) + } + ).catch (error => { + console.error(error); + setErrorAlert(true); + }) + } + + const deleteMember = data => { + if (data.memberID !== member.id) { + setWrongID(true); + } else { + fetch(`${API_URL}m/${member.id}`,{ + method: 'DELETE', + headers: { + 'Authorization': JSON.stringify(localStorage.getItem("token")).slice(1, -1) + }}).then (() => { + setErrorAlert(false); + setMemberDeleted(true); + }) + .catch (error => { + console.error(error); + setErrorAlert(true); + }) + } + } + + function addProxyField() { + setProxyTags(oldTags => [...oldTags, {prefix: '', suffix: ''}] ) + } + + function resetProxyFields() { + setProxyMode(false); + setProxyTags(member.proxy_tags); + } + + const submitProxy = data => { + + const newdata = {proxy_tags: data.proxy_tags.filter(tag => !(tag.prefix === "" && tag.suffix === ""))} + + fetch(`${API_URL}m/${member.id}`,{ + method: 'PATCH', + body: JSON.stringify(newdata), + headers: { + 'Content-Type': 'application/json', + 'Authorization': JSON.stringify(localStorage.getItem("token")).slice(1, -1) + }}).then (res => res.json() + ).then (data => { + setMember(prevState => {return {...prevState, ...data}}); + setProxyTags(data.proxy_tags); + setErrorAlert(false) + setProxyMode(false); + } + ).catch (error => { + console.error(error); + setErrorAlert(true); + }); + } + + return ( + memberDeleted ? Member Deleted + + Member successfully deleted, click the button below to go back to the dash. + history.push("/pk-webs/dash/reload")}>Back + : + <> + { localStorage.getItem('colorbg') ? "" : member.color ? <>
+
: "" } + + + {member.name} ({member.id}) + { member.avatar_url ? } className="avatar" modal> + {close => ( +
close()}> + +
+ )} +
: + } +
+ + { errorAlert ? Something went wrong, please try logging in and out again. : "" } + { editMode ? + <> + + + + Name: + + + + Display name: + + + + Birthday: + + (YYYY-MM-DD) + + + Pronouns: + + + + Avatar url: + + + + Color: + + (hexcode) + + + + Description: + + + setEditMode(false)}>Cancel Submit setOpen(o => !o)}>Delete + + + + + +
Are you sure you want to delete {member.name}?
+
+ + { wrongID ? Incorrect ID, please check the spelling. : "" } +

If you're sure you want to delete this member, please enter the member ID ({member.id}) below.

+ + Member ID: + + Delete Cancel + +
+
+
+
+ : + <> + + ID: {member.id} + { member.display_name ? localStorage.getItem('twemoji') ? Display name: {displayName} : + Display name: {displayName} : "" } + { member.birthday ? Birthday: {birthday} : "" } + { member.pronouns ? localStorage.getItem('twemoji') ? Pronouns: : + Pronouns: : "" } + { member.color ? Color: {color} : "" } + { privacyView ? "" : proxyView ? "" : Privacy: setPrivacyView(true)}>View } + { privacyView ? "" : proxyView ? "" : Proxy tags: setProxyView(true)}>View } + + + { privacyMode ? +
+
Editing privacy settings
+ + + Visibility: + + + + + + + Name: + + + + + + + Description: + + + + + + + Avatar: + + + + + + + Birthday: + + + + + + + Pronouns: + + + + + + + Meta: + + + + + + + setPrivacyMode(false)}>Cancel Submit +
+
: privacyView ? <>
+
Viewing privacy settings
+ + Visibility: {member.visibility} + Name: {member.name_privacy} + Description: {member.description_privacy} + Avatar: {member.avatar_privacy} + Birthday: {member.birthday_privacy} + Pronouns: {member.pronoun_privacy} + Meta: {member.metadata_privacy} + + setPrivacyView(false)}>Exit setPrivacyMode(true)}>Edit +
: "" } + { proxyMode ? + <>
+
Editing proxy tags
+ + + { proxyTags.map((item, index) => ( + + + + + + + + + + ))} addProxyField()}>Add new + + resetProxyFields()}>Exit Submit +
: proxyView ? + <>
+
Viewing proxy tags
+ + { proxyTags.length === 0 ? No proxy tags set. : proxyTags.map((proxytag, index) => {proxytag.prefix}text{proxytag.suffix} )} + + setProxyView(false)}>Exit setProxyMode(true)}>Edit +
: "" } +

Description:

+ { localStorage.getItem('twemoji') ?

:

} + { proxyView ? "" : privacyMode ? "" : privacyView ? "" : <> setEditMode(true)}>Edit Back} + }
+ ) +} diff --git a/src/Components/MemberPages.js b/src/Components/MemberPages.js new file mode 100644 index 00000000..028f88df --- /dev/null +++ b/src/Components/MemberPages.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { useParams } from "react-router-dom"; +import MemberPage from './MemberPage.js' + +export default function MemberPages(props) { + const { memberID } = useParams(); + + const memberpage = props.members.filter((member) => member.id === memberID).map((member) => ) + + return ( + <> + {memberpage} + + ) +} \ No newline at end of file diff --git a/src/Components/Memberlist.js b/src/Components/Memberlist.js index d1257bc6..e786b7dc 100644 --- a/src/Components/Memberlist.js +++ b/src/Components/Memberlist.js @@ -1,16 +1,20 @@ -import React, { useEffect, useState, useCallback } from 'react'; +import React, { useEffect, useLayoutEffect, useState, useCallback } from 'react'; +import { useRouteMatch, Switch, Route } from "react-router-dom"; import * as BS from 'react-bootstrap' import Popup from 'reactjs-popup'; import 'reactjs-popup/dist/index.css'; import { useForm } from "react-hook-form"; import MemberCard from './MemberCard.js' +import MemberPages from './MemberPages.js' import Loading from "./Loading.js"; import API_URL from "../Constants/constants.js"; import { FaPlus } from "react-icons/fa"; -export default function Memberlist(props) { +export default function Memberlist() { + + const { path } = useRouteMatch(); const user = JSON.parse(localStorage.getItem('user')); const userId = user.id; @@ -63,7 +67,7 @@ export default function Memberlist(props) { }) }, [userId]) - useEffect(() => { + useLayoutEffect(() => { fetchMembers(); }, [fetchMembers]) @@ -100,6 +104,7 @@ export default function Memberlist(props) { ).then (data => { setErrorAlert(false); closeModal(); + fetchMembers(); } ).catch (error => { console.error(error); @@ -159,13 +164,11 @@ export default function Memberlist(props) { setSortedMembers(sortMembers); } }, [sortBy, filteredMembers, indexOfFirstMember, indexOfLastMember]) - - const active = currentPage; const pageAmount = Math.ceil(filteredMembers.length / membersPerPage); - const memberList = sortedMembers.map((member) => + const memberList = sortedMembers.map((member) => @@ -173,6 +176,8 @@ export default function Memberlist(props) { ); return ( + + <> @@ -380,5 +385,11 @@ export default function Memberlist(props) { } + + + { isLoading ? : + } + + ) } \ No newline at end of file diff --git a/src/Components/Profile.js b/src/Components/Profile.js index 6f9ad9ad..d7472cd3 100644 --- a/src/Components/Profile.js +++ b/src/Components/Profile.js @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +import { useRouteMatch } from 'react-router-dom'; import { useParams } from 'react-router-dom'; import * as BS from 'react-bootstrap'; import Popup from 'reactjs-popup'; @@ -12,6 +13,8 @@ import ProfileList from "./ProfileList.js"; export default function Profile () { + const match = useRouteMatch("/pk-webs/profile/:sysID/:memberID"); + const { sysID } = useParams(); const [ system, setSystem ] = useState(''); const [ name, setName ] = useState(''); @@ -63,8 +66,8 @@ export default function Profile () { } else setDesc("(no description)"); }, [system.description, system.tag, system.avatar_url, system.tz, system.name]); - - return (<>{ isLoading ? : isError ? Something went wrong, either the system doesn't exist, or there was an error fetching data. : + return (match ? : + <>{ isLoading ? : isError ? Something went wrong, either the system doesn't exist, or there was an error fetching data. : <>You are currently viewing a system. diff --git a/src/Components/ProfileCard.js b/src/Components/ProfileCard.js index d9accbd6..bb7096bb 100644 --- a/src/Components/ProfileCard.js +++ b/src/Components/ProfileCard.js @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +import { useParams, Link } from 'react-router-dom'; import * as BS from 'react-bootstrap' import moment from 'moment'; import Popup from 'reactjs-popup'; @@ -11,7 +12,7 @@ import defaultAvatar from '../default_discord_avatar.png' import { FaUser } from "react-icons/fa"; export default function MemberCard(props) { - + const { sysID } = useParams(); const member = props.member; const [ avatar, setAvatar ] = useState('') @@ -68,7 +69,9 @@ export default function MemberCard(props) { return ( - {member.name} ({member.id}) + { localStorage.getItem('pagesonly') ? + {member.name} ({member.id}) + : {member.name} ({member.id})} { member.avatar_url ? } className="avatar" modal> {close => (
close()}> @@ -82,7 +85,8 @@ export default function MemberCard(props) { ID: {member.id} - { member.display_name ? Display name: {displayName} : "" } + { member.display_name ? localStorage.getItem('twemoji') ? Display name: {displayName} : + Display name: {displayName} : "" } { member.birthday ? Birthday: {birthday} : "" } { member.pronouns ? localStorage.getItem('twemoji') ? Pronouns: : Pronouns: : "" } @@ -99,7 +103,7 @@ export default function MemberCard(props) {
: "" }

Description:

{ localStorage.getItem('twemoji') ?

:

} -
+ View page diff --git a/src/Components/ProfileList.js b/src/Components/ProfileList.js index 4bc3a90a..4f16d50f 100644 --- a/src/Components/ProfileList.js +++ b/src/Components/ProfileList.js @@ -1,14 +1,17 @@ import React, { useEffect, useState, useCallback } from 'react'; +import { Switch, Route, useParams, useRouteMatch } from 'react-router-dom'; import * as BS from 'react-bootstrap' import 'reactjs-popup/dist/index.css'; import ProfileCard from './ProfileCard.js' +import ProfilePages from './ProfilePages.js' import Loading from "./Loading.js"; import API_URL from "../Constants/constants.js"; -export default function Memberlist(props) { - - const sysID = props.sysID; +export default function Memberlist() { + + const { path } = useRouteMatch(); + const { sysID } = useParams(); const [isLoading, setIsLoading ] = useState(false); const [isError, setIsError ] = useState(false); @@ -128,6 +131,8 @@ export default function Memberlist(props) { ); return ( + + <> @@ -209,5 +214,11 @@ export default function Memberlist(props) { } + + + { isLoading ? : + } + + ) } \ No newline at end of file diff --git a/src/Components/ProfilePage.js b/src/Components/ProfilePage.js new file mode 100644 index 00000000..474e3a36 --- /dev/null +++ b/src/Components/ProfilePage.js @@ -0,0 +1,112 @@ +import React, { useEffect, useState } from 'react'; +import { Link, useLocation } from 'react-router-dom'; +import * as BS from 'react-bootstrap' +import moment from 'moment'; +import Popup from 'reactjs-popup'; +import 'reactjs-popup/dist/index.css'; +import autosize from 'autosize'; +import Twemoji from 'react-twemoji'; + +import defaultAvatar from '../default_discord_avatar.png' +import { FaUser } from "react-icons/fa"; + +export default function ProfilePage(props) { + + const location = useLocation(); + const member = props.member; + + const [ avatar, setAvatar ] = useState('') + const [ displayName, setDisplayName ] = useState(""); + const [ birthday, setBirthday ] = useState(""); + const [ pronouns, setPronouns ] = useState(""); + const [ color, setColor ] = useState(""); + const [ desc, setDesc ] = useState(""); + const proxyTags = member.proxy_tags; + + const [ proxyView, setProxyView ] = useState(false); + + useEffect(() => { + autosize(document.querySelector('textarea')); + }) + + useEffect(() => { + const { toHTML } = require('../Functions/discord-parser.js'); + + if (member.display_name) { + setDisplayName(member.display_name) + } else setDisplayName('') + + if (member.birthday) { + if (member.birthday.startsWith('0004-')) { + var bday = member.birthday.replace('0004-',''); + var bdaymoment = moment(bday, 'MM-DD').format('MMM D'); + setBirthday(bdaymoment); + } else { + var birthdaymoment = moment(member.birthday, 'YYYY-MM-DD').format('MMM D, YYYY'); + setBirthday(birthdaymoment); + } + } else { setBirthday(''); + } + + if (member.avatar_url) { + var avatarsmall = member.avatar_url.replace('&format=jpeg', ''); + setAvatar(avatarsmall.replace('?width=256&height=256', '')) + } else setAvatar('') + + if (member.pronouns) { + setPronouns(toHTML(member.pronouns)) + } else setPronouns('') + + if (member.color) { + setColor(member.color); + } else setColor(''); + + if (member.description) { + setDesc(toHTML(member.description)); + } else setDesc("(no description)"); + }, [member.description, member.color, member.birthday, member.display_name, member.pronouns, member.avatar_url, member.proxy_tags]); + + return ( + <> + { localStorage.getItem('colorbg') ? "" : member.color ? <>
+
: "" } + You are currently viewing a member. + + + {member.name} ({member.id}) + { member.avatar_url ? } className="avatar" modal> + {close => ( +
close()}> + +
+ )} +
: + } +
+ + + ID: {member.id} + { member.display_name ? localStorage.getItem('twemoji') ? Display name: {displayName} : + Display name: {displayName} : "" } + { member.birthday ? Birthday: {birthday} : "" } + { member.pronouns ? localStorage.getItem('twemoji') ? Pronouns: : + Pronouns: : "" } + { member.color ? Color: {color} : "" } + { proxyView ? "" : Proxy tags: setProxyView(true)}>View } + + + { proxyView ? <>
+
Viewing proxy tags
+ + { proxyTags.length === 0 ? No proxy tags set. : proxyTags.map((proxytag) => {proxytag.prefix}text{proxytag.suffix} )} + + setProxyView(false)}>Exit +
: "" } +

Description:

+ { localStorage.getItem('twemoji') ?

:

} + Back +
+
+ + ) +} diff --git a/src/Components/ProfilePages.js b/src/Components/ProfilePages.js new file mode 100644 index 00000000..dc2624bc --- /dev/null +++ b/src/Components/ProfilePages.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { useParams } from "react-router-dom"; +import ProfilePage from './ProfilePage.js' + +export default function MemberPages(props) { + const { memberID } = useParams(); + + const memberpage = props.members.filter((member) => member.id === memberID).map((member) => ) + + return ( + <> + {memberpage} + + ) +} \ No newline at end of file diff --git a/src/Components/System.js b/src/Components/System.js index c838e264..97c592ba 100644 --- a/src/Components/System.js +++ b/src/Components/System.js @@ -1,5 +1,6 @@ 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'; @@ -15,6 +16,8 @@ import { FaAddressCard } from "react-icons/fa"; export default function System(props) { + const match = useRouteMatch("/pk-webs/dash/:memberID"); + const { register: registerEdit, handleSubmit: handleSubmitEdit @@ -112,6 +115,8 @@ const submitPrivacy = data => { }) } + if (match) return null; + return ( diff --git a/src/Custom.scss b/src/Custom.scss index 4f77831f..6e22c505 100644 --- a/src/Custom.scss +++ b/src/Custom.scss @@ -3,6 +3,10 @@ src: url('https://dl.dropboxusercontent.com/s/qfpakpjedhsrdb9/OpenDyslexicAlta-Regular.ttf'); } +#root { + z-index: -5; +} + html { position: relative; min-height: 100vh; @@ -21,12 +25,21 @@ body { transition: background-color 0.3s ease; } +.card-header { + background-color: $gray-200 !important; + opacity: 1 !important; +} + .dark-mode .card { color: $white; background-color: $gray-800; border: 1px solid #191c1f !important; } +.card-body { + background-color: $white; +} + .dark-mode .card-body { color: $white; background-color: $gray-800; @@ -34,8 +47,8 @@ body { } .dark-mode .card-header { - color: $gray-100; - background-color: $gray-900; + color: $gray-100 !important; + background-color: $gray-900 !important; transition: background-color 0.3s ease; } @@ -265,4 +278,36 @@ blockquote { width: auto; } +.backdrop { + position:fixed; + padding:0; + margin:0; + + top:0; + left:0; + + width: 100%; + height: 100%; + z-index: -4; + opacity: 0.6; +} + +.backdrop-overlay { + position:fixed; + padding:0; + margin:0; + + top:0; + left:0; + + width: 100%; + height: 100%; + z-index: -3; + background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); +} + +.dark-mode .backdrop-overlay { + background: linear-gradient(to bottom, rgba(52, 58, 64, 1) 0%, rgba(255, 255, 255, 0) 100%); +} + @import "~bootstrap/scss/bootstrap";