aboutsummaryrefslogtreecommitdiff
path: root/pages/user.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'pages/user.tsx')
-rw-r--r--pages/user.tsx544
1 files changed, 306 insertions, 238 deletions
diff --git a/pages/user.tsx b/pages/user.tsx
index 5f5b1eb..4f7331c 100644
--- a/pages/user.tsx
+++ b/pages/user.tsx
@@ -1,89 +1,106 @@
-import { ReactNode, Children, useState, useEffect, useContext } from 'react';
import Icon from '@mdi/react';
import axios from 'axios';
+import { Children, ReactNode, useContext, useEffect, useState } from 'react';
+import { userGames, userInfo } from '../api/api';
+import { AccountAvatar } from '../components/account';
+import { Footer } from '../components/footer';
import { NavBar } from '../components/navbar';
import { CenteredPage, PageTitle } from '../components/page';
-import { Vierkant, IconLabelButton } from '../components/ui';
-import { AccountAvatar } from '../components/account';
-import { userInfo, userGames } from '../api/api';
import RecentGames from '../components/recentGames';
-import { ToastContext } from '../components/toast';
import { SocketContext } from '../components/socketContext';
-import { Footer } from '../components/footer';
+import { ToastContext } from '../components/toast';
+import { IconLabelButton, Vierkant } from '../components/ui';
-import PersonAddOutlinedIcon from '@material-ui/icons/PersonAddOutlined';
-import AssignmentIndOutlinedIcon from '@material-ui/icons/AssignmentIndOutlined';
import ArrowDownwardOutlinedIcon from '@material-ui/icons/ArrowDownwardOutlined';
import ArrowUpwardOutlinedIcon from '@material-ui/icons/ArrowUpwardOutlined';
-import PeopleOutlineOutlinedIcon from '@material-ui/icons/PeopleOutlineOutlined';
+import AssignmentIndOutlinedIcon from '@material-ui/icons/AssignmentIndOutlined';
+import DoneOutlinedIcon from '@material-ui/icons/DoneOutlined';
import EditOutlinedIcon from '@material-ui/icons/EditOutlined';
+import PeopleOutlineOutlinedIcon from '@material-ui/icons/PeopleOutlineOutlined';
+import PersonAddOutlinedIcon from '@material-ui/icons/PersonAddOutlined';
import SettingsOutlinedIcon from '@material-ui/icons/SettingsOutlined';
-import DoneOutlinedIcon from '@material-ui/icons/DoneOutlined';
import {
mdiAccountCancelOutline,
- mdiEqual,
+ mdiAccountMinusOutline,
+ mdiAccountRemoveOutline,
mdiCheckboxBlankCircle,
mdiClipboardTextOutline,
- mdiGamepadSquareOutline,
mdiEarth,
- mdiAccountMinusOutline,
- mdiAccountRemoveOutline } from '@mdi/js';
+ mdiEqual,
+ mdiGamepadSquareOutline,
+} from '@mdi/js';
function InfoModule(props: {
label: string;
icon: ReactNode;
}) {
- return <div style={{
- position: "relative",
- height: "100%"
- }}>
- <div style={{
- position: "absolute",
- left: "50%",
- transform: "translateX(-50%)"
- }}>{props.icon}</div>
- <div style={{
- position: "absolute",
- top: 24 + 6,
- left: 0, right: 0, bottom: 0,
- }}>
- <span style={{
- position: "absolute",
- top: "50%",
- transform: "translateY(-50%)",
- width: "100%",
- textAlign: "center"
- }}>{props.label}</span>
+ return <div
+ style={{
+ position: 'relative',
+ height: '100%',
+ }}
+ >
+ <div
+ style={{
+ position: 'absolute',
+ left: '50%',
+ transform: 'translateX(-50%)',
+ }}
+ >
+ {props.icon}
+ </div>
+ <div
+ style={{
+ position: 'absolute',
+ top: 24 + 6,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ }}
+ >
+ <span
+ style={{
+ position: 'absolute',
+ top: '50%',
+ transform: 'translateY(-50%)',
+ width: '100%',
+ textAlign: 'center',
+ }}
+ >
+ {props.label}
+ </span>
</div>
- </div>
+ </div>;
}
-function InfoSection(props: { children: ReactNode }) {
+function InfoSection(props: { children: ReactNode; }) {
return <Vierkant fullwidth>
- <div style={{
- display: "grid",
- gridTemplateColumns: `repeat(${Children.count(props.children)}, 1fr)`,
- gridGap: 12,
- height: 64
- }}>
+ <div
+ style={{
+ display: 'grid',
+ gridTemplateColumns: `repeat(${Children.count(props.children)}, 1fr)`,
+ gridGap: 12,
+ height: 64,
+ }}
+ >
{props.children}
</div>
- </Vierkant>
+ </Vierkant>;
}
export default function AccountPage() {
- var server = typeof window === "undefined";
- var loggedIn = !server && document.cookie.includes("token");
- var pageID = server ? "" : new URLSearchParams(window.location.search).get("id");
+ var server = typeof window === 'undefined';
+ var loggedIn = !server && document.cookie.includes('token');
+ var pageID = server ? '' : new URLSearchParams(window.location.search).get('id');
if (!loggedIn && !pageID) !server && window.history.go(-1);
- var reqData = loggedIn && pageID ? { "id": pageID } : undefined;
+ var reqData = loggedIn && pageID ? { 'id': pageID } : undefined;
var [user, setUser] = useState<userInfo>();
var [gameInfo, setGameInfo] = useState<userGames>();
var [editingStatus, setEditingStatus] = useState(false);
- var [relation, setRelation] = useState<userInfo["relation"]>("none");
+ var [relation, setRelation] = useState<userInfo['relation']>('none');
var [ownPage, setOwnPage] = useState(loggedIn && !pageID);
var { toast } = useContext(ToastContext);
@@ -91,237 +108,288 @@ export default function AccountPage() {
async function getUserData(): Promise<userInfo> {
var userReq = await axios.request<userInfo>({
- method: "post",
+ method: 'post',
url: `/api/user/info`,
- headers: {"content-type": "application/json"},
- data: reqData
+ headers: { 'content-type': 'application/json' },
+ data: reqData,
});
setUser(userReq.data);
- return userReq.data
+ return userReq.data;
}
async function getRelationTo(user: userInfo) {
var user = await getUserData();
- setRelation(user.relation || "none");
+ setRelation(user.relation || 'none');
}
function setIOListeners(user: userInfo) {
- io.on("changedRelation", (data: { id: string }) => {
+ io.on('changedRelation', (data: { id: string; }) => {
if (data.id != user.id) return;
getRelationTo(user);
});
- io.on("incomingFriendRequest", getRelationTo);
+ io.on('incomingFriendRequest', getRelationTo);
}
- useEffect(() => {(async() => {
- var user = await getUserData();
+ useEffect(() => {
+ (async () => {
+ var user = await getUserData();
- getRelationTo(user);
- setIOListeners(user);
- })()}, []);
+ getRelationTo(user);
+ setIOListeners(user);
+ })();
+ }, []);
- useEffect(() => {(async() => {
- var userReq = await axios.request<userInfo>({
- method: "post",
- url: `/api/user/info`,
- headers: {"content-type": "application/json"}
- });
- setOwnPage(ownPage || userReq.data.id == pageID);
- })()}, []);
+ useEffect(() => {
+ (async () => {
+ var userReq = await axios.request<userInfo>({
+ method: 'post',
+ url: `/api/user/info`,
+ headers: { 'content-type': 'application/json' },
+ });
+ setOwnPage(ownPage || userReq.data.id == pageID);
+ })();
+ }, []);
// Get recent games
- useEffect(() => {(async() => {
- var userGamesReq = await axios.request<userGames>({
- method: "post",
- url: `/api/user/games`,
- headers: {"content-type": "application/json"},
- data: reqData
- });
- setGameInfo(userGamesReq.data);
- })()}, []);
+ useEffect(() => {
+ (async () => {
+ var userGamesReq = await axios.request<userGames>({
+ method: 'post',
+ url: `/api/user/games`,
+ headers: { 'content-type': 'application/json' },
+ data: reqData,
+ });
+ setGameInfo(userGamesReq.data);
+ })();
+ }, []);
return <div>
- <NavBar/>
+ <NavBar />
<CenteredPage width={802}>
<PageTitle>Profiel</PageTitle>
<Vierkant fullwidth>
- <AccountAvatar size={128} id={user?.id || ""}/>
- <div style={{
- display: "inline-block",
- verticalAlign: "top",
- marginLeft: 12,
- width: "calc(100% - 128px - 12px)"
- }}>
+ <AccountAvatar size={128} id={user?.id || ''} />
+ <div
+ style={{
+ display: 'inline-block',
+ verticalAlign: 'top',
+ marginLeft: 12,
+ width: 'calc(100% - 128px - 12px)',
+ }}
+ >
<h2 style={{ fontSize: 32 }}>{user?.username}</h2>
- <p id="status" contentEditable={editingStatus ? "true" : "false"} style={{
- marginTop: 6,
- transitionDuration: ".3s"
- }} suppressContentEditableWarning={true}>{user?.status}</p>
+ <p
+ id='status'
+ contentEditable={editingStatus ? 'true' : 'false'}
+ style={{
+ marginTop: 6,
+ transitionDuration: '.3s',
+ }}
+ suppressContentEditableWarning={true}
+ >
+ {user?.status}
+ </p>
</div>
- <div style={{
- position: "absolute",
- backgroundColor: "var(--background)",
- height: "40px",
- bottom: 24, left: 24 + 12 + 128, right: 24
- }}>
- { loggedIn && <div> {
- ownPage ?
- <div>
- <IconLabelButton icon={<SettingsOutlinedIcon/>} href="/settings" text="Instellingen"/>
- {
- !editingStatus ?
- <IconLabelButton
- icon={<EditOutlinedIcon/>}
- text="Status bewerken"
- onclick={() => setEditingStatus(true)}/> :
- <IconLabelButton
- icon={<DoneOutlinedIcon/>}
- text="Status opslaan"
- onclick={() => {
- setEditingStatus(false)
- axios.request({
- method: "post",
- url: `/api/user/status`,
- headers: {"content-type": "application/json"},
- data: { "status": document.getElementById("status").innerText }
- });
- }}/>
- }
- </div> :
- <div>
- {(() => {
- var icon = {
- "blocked": <Icon size={1} path={mdiAccountCancelOutline}/>
- }[relation] || <Icon size={1} path={mdiAccountCancelOutline}/>
+ <div
+ style={{
+ position: 'absolute',
+ backgroundColor: 'var(--background)',
+ height: '40px',
+ bottom: 24,
+ left: 24 + 12 + 128,
+ right: 24,
+ }}
+ >
+ {loggedIn && <div>
+ {ownPage
+ ? <div>
+ <IconLabelButton icon={<SettingsOutlinedIcon />} href='/settings' text='Instellingen' />
+ {!editingStatus
+ ? <IconLabelButton
+ icon={<EditOutlinedIcon />}
+ text='Status bewerken'
+ onclick={() => setEditingStatus(true)}
+ />
+ : <IconLabelButton
+ icon={<DoneOutlinedIcon />}
+ text='Status opslaan'
+ onclick={() => {
+ setEditingStatus(false);
+ axios.request({
+ method: 'post',
+ url: `/api/user/status`,
+ headers: { 'content-type': 'application/json' },
+ data: { 'status': document.getElementById('status').innerText },
+ });
+ }}
+ />}
+ </div>
+ : <div>
+ {(() => {
+ var icon = {
+ 'blocked': <Icon size={1} path={mdiAccountCancelOutline} />,
+ }[relation] || <Icon size={1} path={mdiAccountCancelOutline} />;
- var text = {
- "blocked": "Deblokkeren"
- }[relation] || "Blokkeren"
+ var text = {
+ 'blocked': 'Deblokkeren',
+ }[relation] || 'Blokkeren';
- return <IconLabelButton icon={icon} text={text} onclick={() => {
- var nextRelation = {
- "blocked": {
- "endpoint": "/api/social/unblock",
- "action": `${user.username} gedeblokkeerd`,
- "relation": "none",
- "icon": <Icon size={1} path={mdiAccountCancelOutline}/>,
- }
- }[relation] || {
- "endpoint": "/api/social/block",
- "action": `${user.username} geblokkeerd`,
- "relation": "blocked",
- "icon": <Icon size={1} path={mdiAccountCancelOutline}/>,
- }
+ return <IconLabelButton
+ icon={icon}
+ text={text}
+ onclick={() => {
+ var nextRelation = {
+ 'blocked': {
+ 'endpoint': '/api/social/unblock',
+ 'action': `${user.username} gedeblokkeerd`,
+ 'relation': 'none',
+ 'icon': <Icon size={1} path={mdiAccountCancelOutline} />,
+ },
+ }[relation] || {
+ 'endpoint': '/api/social/block',
+ 'action': `${user.username} geblokkeerd`,
+ 'relation': 'blocked',
+ 'icon': <Icon size={1} path={mdiAccountCancelOutline} />,
+ };
- axios.request({
- method: "post",
- url: nextRelation.endpoint,
- headers: {"content-type": "application/json"},
- data: { "id": user?.id }
- })
- .then(() => {
- toast({ message: nextRelation.action,
- type: "confirmation",
- icon: nextRelation.icon });
- setRelation(nextRelation.relation);
- });
- }}/>
- })()}
- {(() => {
- var icon = {
- "friends": <Icon size={1} path={mdiAccountMinusOutline}/>,
- "outgoing": <Icon size={1} path={mdiAccountRemoveOutline}/>,
- "incoming": <PersonAddOutlinedIcon/>
- }[relation] || <PersonAddOutlinedIcon/>
+ axios.request({
+ method: 'post',
+ url: nextRelation.endpoint,
+ headers: { 'content-type': 'application/json' },
+ data: { 'id': user?.id },
+ })
+ .then(() => {
+ toast({
+ message: nextRelation.action,
+ type: 'confirmation',
+ icon: nextRelation.icon,
+ });
+ setRelation(nextRelation.relation);
+ });
+ }}
+ />;
+ })()}
+ {(() => {
+ var icon = {
+ 'friends': <Icon size={1} path={mdiAccountMinusOutline} />,
+ 'outgoing': <Icon size={1} path={mdiAccountRemoveOutline} />,
+ 'incoming': <PersonAddOutlinedIcon />,
+ }[relation] || <PersonAddOutlinedIcon />;
- var text = {
- "friends": "Vriend verwijderen",
- "outgoing": "Vriendschapsverzoek annuleren",
- "incoming": "Vriendschapsverzoek accepteren"
- }[relation] || "Vriendschapsverzoek sturen"
+ var text = {
+ 'friends': 'Vriend verwijderen',
+ 'outgoing': 'Vriendschapsverzoek annuleren',
+ 'incoming': 'Vriendschapsverzoek accepteren',
+ }[relation] || 'Vriendschapsverzoek sturen';
- return <IconLabelButton icon={icon} text={text} onclick={() => {
- var nextRelation = {
- "friends": {
- "endpoint": "/api/social/remove",
- "action": `${user.username} succesvol verwijderd als vriend`,
- "relation": "none",
- "icon": <Icon size={1} path={mdiAccountMinusOutline}/>,
- },
- "outgoing": {
- "endpoint": "/api/social/remove",
- "action": `Vriendschapsverzoek naar ${user.username} geannuleerd`,
- "relation": "none",
- "icon": <Icon size={1} path={mdiAccountMinusOutline}/>,
- },
- "incoming": {
- "endpoint": "/api/social/accept",
- "action": `Vriendschapsverzoek van ${user.username} geaccepteerd`,
- "relation": "friends",
- "icon": <PersonAddOutlinedIcon/>,
- },
- }[relation] || {
- "endpoint": "/api/social/request",
- "action": `Vriendschapsverzoek gestuurd naar ${user.username}`,
- "relation": "outgoing",
- "icon": <PersonAddOutlinedIcon/>,
- }
+ return <IconLabelButton
+ icon={icon}
+ text={text}
+ onclick={() => {
+ var nextRelation = {
+ 'friends': {
+ 'endpoint': '/api/social/remove',
+ 'action': `${user.username} succesvol verwijderd als vriend`,
+ 'relation': 'none',
+ 'icon': <Icon size={1} path={mdiAccountMinusOutline} />,
+ },
+ 'outgoing': {
+ 'endpoint': '/api/social/remove',
+ 'action': `Vriendschapsverzoek naar ${user.username} geannuleerd`,
+ 'relation': 'none',
+ 'icon': <Icon size={1} path={mdiAccountMinusOutline} />,
+ },
+ 'incoming': {
+ 'endpoint': '/api/social/accept',
+ 'action': `Vriendschapsverzoek van ${user.username} geaccepteerd`,
+ 'relation': 'friends',
+ 'icon': <PersonAddOutlinedIcon />,
+ },
+ }[relation] || {
+ 'endpoint': '/api/social/request',
+ 'action': `Vriendschapsverzoek gestuurd naar ${user.username}`,
+ 'relation': 'outgoing',
+ 'icon': <PersonAddOutlinedIcon />,
+ };
- axios.request({
- method: "post",
- url: nextRelation.endpoint,
- headers: {"content-type": "application/json"},
- data: { "id": user?.id }
- })
- .then(() => {
- toast({ message: nextRelation.action,
- type: "confirmation",
- icon: nextRelation.icon });
- setRelation(nextRelation.relation);
- });
- }}/>
- })()}
- </div>
- }</div>}
+ axios.request({
+ method: 'post',
+ url: nextRelation.endpoint,
+ headers: { 'content-type': 'application/json' },
+ data: { 'id': user?.id },
+ })
+ .then(() => {
+ toast({
+ message: nextRelation.action,
+ type: 'confirmation',
+ icon: nextRelation.icon,
+ });
+ setRelation(nextRelation.relation);
+ });
+ }}
+ />;
+ })()}
+ </div>}
+ </div>}
</div>
</Vierkant>
<InfoSection>
- <InfoModule icon={<Icon size={1} path={mdiCheckboxBlankCircle} color="var(--disk-b-text)"/>} label="Online"/>
- <InfoModule icon={<AssignmentIndOutlinedIcon/>} label={ (() => {
- var memberSince = "Lid sinds";
+ <InfoModule
+ icon={<Icon size={1} path={mdiCheckboxBlankCircle} color='var(--disk-b-text)' />}
+ label='Online'
+ />
+ <InfoModule
+ icon={<AssignmentIndOutlinedIcon />}
+ label={(() => {
+ var memberSince = 'Lid sinds';
- var registered = new Date(user?.registered);
- memberSince += " " + registered.toLocaleString("nl-nl", { month: "long", day: "numeric" });
+ var registered = new Date(user?.registered);
+ memberSince += ' ' + registered.toLocaleString('nl-nl', { month: 'long', day: 'numeric' });
- var currentYear = new Date().getFullYear();
- var memberYear = registered.getFullYear();
- if (currentYear != memberYear) memberSince += " " + memberYear;
+ var currentYear = new Date().getFullYear();
+ var memberYear = registered.getFullYear();
+ if (currentYear != memberYear) memberSince += ' ' + memberYear;
- return memberSince;
- })() }/>
- <InfoModule icon={<PeopleOutlineOutlinedIcon/>} label={(() => {
- var label = user?.friends.toString() + " ";
- label += user?.friends == 1 ? "vriend" : "vrienden";
- return label;
- })()}/>
- <InfoModule icon={<Icon size={1} path={mdiEarth}/>} label="Nederland"/>
+ return memberSince;
+ })()}
+ />
+ <InfoModule
+ icon={<PeopleOutlineOutlinedIcon />}
+ label={(() => {
+ var label = user?.friends.toString() + ' ';
+ label += user?.friends == 1 ? 'vriend' : 'vrienden';
+ return label;
+ })()}
+ />
+ <InfoModule icon={<Icon size={1} path={mdiEarth} />} label='Nederland' />
</InfoSection>
<InfoSection>
- <InfoModule icon={<ArrowUpwardOutlinedIcon style={{ color: "var(--disk-b-text)" }}/>} label={ gameInfo?.totals.win + " keer gewonnen" }/>
- <InfoModule icon={<Icon size={1} path={mdiEqual}/>} label={ gameInfo?.totals.draw + " keer gelijkspel" }/>
- <InfoModule icon={<ArrowDownwardOutlinedIcon style={{ color: "var(--disk-a-text)" }}/>} label={ gameInfo?.totals.lose + " keer verloren" }/>
- <InfoModule icon={<Icon size={1} path={mdiClipboardTextOutline}/>} label={ "Score: " + user?.rating }/>
- <InfoModule icon={<Icon size={1} path={mdiGamepadSquareOutline}/>} label={(() => {
- var label = gameInfo?.totals.games.toString() + " ";
- label += gameInfo?.totals.games == 1 ? "potje" : "potjes";
- return label;
- })()}/>
+ <InfoModule
+ icon={<ArrowUpwardOutlinedIcon style={{ color: 'var(--disk-b-text)' }} />}
+ label={gameInfo?.totals.win + ' keer gewonnen'}
+ />
+ <InfoModule
+ icon={<Icon size={1} path={mdiEqual} />}
+ label={gameInfo?.totals.draw + ' keer gelijkspel'}
+ />
+ <InfoModule
+ icon={<ArrowDownwardOutlinedIcon style={{ color: 'var(--disk-a-text)' }} />}
+ label={gameInfo?.totals.lose + ' keer verloren'}
+ />
+ <InfoModule icon={<Icon size={1} path={mdiClipboardTextOutline} />} label={'Score: ' + user?.rating} />
+ <InfoModule
+ icon={<Icon size={1} path={mdiGamepadSquareOutline} />}
+ label={(() => {
+ var label = gameInfo?.totals.games.toString() + ' ';
+ label += gameInfo?.totals.games == 1 ? 'potje' : 'potjes';
+ return label;
+ })()}
+ />
</InfoSection>
<Vierkant>
- <RecentGames games={gameInfo?.games}/>
+ <RecentGames games={gameInfo?.games} />
</Vierkant>
</CenteredPage>
- <Footer/>
- </div>
+ <Footer />
+ </div>;
}
-