aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2021-04-27 09:44:56 +0200
committerlonkaars <loek@pipeframe.xyz>2021-04-27 09:44:56 +0200
commit8ab459c8b6c517086eab9be6b2953368738f651b (patch)
tree0ebe2f331083630e4650372a8247f8597fda3501
parent93b7033fed80cca1df0e339c76755dd85089141d (diff)
edit username/email in settings page
-rw-r--r--api/api.ts1
-rw-r--r--api/user/info.py7
-rw-r--r--pages/settings.tsx98
3 files changed, 88 insertions, 18 deletions
diff --git a/api/api.ts b/api/api.ts
index 0949139..f8eda07 100644
--- a/api/api.ts
+++ b/api/api.ts
@@ -8,6 +8,7 @@ export interface userInfo {
friends: number;
relation?: 'none' | 'friends' | 'incoming' | 'outgoing' | 'blocked';
rating: number;
+ email?: string;
}
export type ruleset = {
diff --git a/api/user/info.py b/api/user/info.py
index fc303a6..9eaed22 100644
--- a/api/user/info.py
+++ b/api/user/info.py
@@ -30,7 +30,7 @@ def count_friends(user_id):
# get user/info of `user_id` as `viewer` (id)
-def format_user(user_id, viewer=''):
+def format_user(user_id, viewer='', private_details=False):
user = cursor.execute(
"select " + ", ".join(
[
@@ -39,6 +39,7 @@ def format_user(user_id, viewer=''):
"country",
"registered",
"status",
+ "email",
]
) + " from users where user_id = ?", [user_id]
).fetchone()
@@ -51,8 +52,10 @@ def format_user(user_id, viewer=''):
"friends": count_friends(user_id),
"rating":
get_rating(user_id), #TODO: calculate rating based on game analysis
+ "email": None
}
if viewer: formatted_user["relation"] = get_relation_to(viewer, user_id)
+ if private_details: formatted_user["email"] = user[5]
return formatted_user
@@ -64,7 +67,7 @@ info = Blueprint('info', __name__)
@info.route('/info', methods=['GET', 'POST'])
@one_person
def index(user_id, viewer):
- user = format_user(user_id, viewer)
+ user = format_user(user_id, viewer, user_id == viewer)
return user, 200
diff --git a/pages/settings.tsx b/pages/settings.tsx
index f52b332..0574b8e 100644
--- a/pages/settings.tsx
+++ b/pages/settings.tsx
@@ -1,6 +1,6 @@
import axios from 'axios';
import reduce from 'image-blob-reduce';
-import { useContext, useEffect } from 'react';
+import { useContext, useEffect, useState } from 'react';
import * as cookie from 'react-cookies';
import { AccountAvatar } from '../components/account';
@@ -10,7 +10,9 @@ import { NavBar } from '../components/navbar';
import { CenteredPage, PageTitle } from '../components/page';
import PreferencesContext from '../components/preferencesContext';
import ThemePicker from '../components/themes';
-import { CheckBox, ColorPicker, IconLabelButton, Vierkant } from '../components/ui';
+import { CheckBox, ColorPicker, IconLabelButton, Vierkant, Input, Button } from '../components/ui';
+import { userInfo } from '../api/api';
+import { DialogBox } from '../components/dialogBox';
import EditOutlinedIcon from '@material-ui/icons/EditOutlined';
import PublishOutlinedIcon from '@material-ui/icons/PublishOutlined';
@@ -41,6 +43,45 @@ async function uploadNewProfileImage() {
};
}
+function EditImportantThingDialog(props: {
+ thing: "username" | "email";
+ hidden?: boolean;
+ setHidden?: () => void;
+}) {
+ var lang = {
+ "username": {
+ name: "Gebruikersnaam",
+ new: "Nieuwe gebruikersnaam",
+ },
+ "email": {
+ name: "Email",
+ new: "Nieuw email-adres",
+ },
+ }[props.thing]
+ var title = lang.name + " aanpassen"
+ return !props.hidden && <DialogBox title={title} onclick={props.setHidden}>
+ <Input className="bg-900 pad-m fullwidth round-t" label={lang.new} id="newThing" autocomplete="off"/>
+ <div className="pad-s"></div>
+ <Input className="bg-900 pad-m fullwidth round-t" label="Huidig wachtwoord" id="currentPassword" type="password" autocomplete="current-password"/>
+ <div className="pad-m"></div>
+ <Button text={title} onclick={() => {
+ var data = {
+ password: (document.getElementById("currentPassword") as HTMLInputElement).value
+ }
+ data[props.thing] = (document.getElementById("newThing") as HTMLInputElement).value
+ axios.request({
+ method: "post",
+ url: "/api/user/" + props.thing,
+ headers: { 'content-type': 'application/json' },
+ data
+ }).then(() => {
+ window.location.reload()
+ })
+ props.setHidden();
+ }}/>
+ </DialogBox>
+}
+
export default function SettingsPage() {
useEffect(() => {
var loggedIn = !!cookie.load('token');
@@ -49,6 +90,22 @@ export default function SettingsPage() {
var { preferences, updatePreference } = useContext(PreferencesContext);
+ var [ userInfo, setUserInfo ] = useState<userInfo>();
+ var [ emailVisible, setEmailVisible ] = useState(false);
+
+ var [ editUsernameDiagVisisble, setEditUsernameDiagVisisble ] = useState(false);
+ var [ editEmailDiagVisisble, setEditEmailDiagVisisble ] = useState(false);
+
+ useEffect(() => {
+ axios.request<userInfo>({
+ url: `/api/user/info`
+ }).then(req => {
+ setUserInfo(req.data);
+ }).catch(err => {
+ console.error(err)
+ })
+ }, []);
+
return (
<div>
<NavBar />
@@ -76,22 +133,31 @@ export default function SettingsPage() {
}}
/>
</div>
- {false && <>
- <div className='subsection'>
- <IconLabelButton text='Bewerken' icon={<EditOutlinedIcon />} />
- <div className='dispbl'>
- <h3>Gebruikersnaam</h3>
- <p>Hier staat hij dan</p>
- </div>
+ <div className='subsection'>
+ <EditImportantThingDialog thing="username" hidden={!editUsernameDiagVisisble} setHidden={() => setEditUsernameDiagVisisble(false)}/>
+ <IconLabelButton text='Bewerken' icon={<EditOutlinedIcon />} onclick={() => setEditUsernameDiagVisisble(true)} />
+ <div className='dispbl'>
+ <h3>Gebruikersnaam</h3>
+ <p>{ userInfo?.username }</p>
</div>
- <div className='subsection'>
- <IconLabelButton text='Bewerken' icon={<EditOutlinedIcon />} />
- <IconLabelButton text='Onthullen' icon={<VisibilityOutlinedIcon />} />
- <div className='dispbl'>
- <h3>Email</h3>
- <p>******@example.com</p>
- </div>
+ </div>
+ <div className='subsection'>
+ <EditImportantThingDialog thing="email" hidden={!editEmailDiagVisisble} setHidden={() => setEditEmailDiagVisisble(false)}/>
+ <IconLabelButton text='Bewerken' icon={<EditOutlinedIcon />} onclick={() => setEditEmailDiagVisisble(true)} />
+ { emailVisible ?
+ <IconLabelButton text='Verbergen' icon={<VisibilityOutlinedIcon />} onclick={() => setEmailVisible(!emailVisible)} /> :
+ <IconLabelButton text='Onthullen' icon={<VisibilityOutlinedIcon />} onclick={() => setEmailVisible(!emailVisible)} />
+ }
+ <div className='dispbl'>
+ <h3>Email</h3>
+ <p>{ (() => {
+ var email = userInfo?.email;
+ if (email && !emailVisible) email = email.replace(/.+?(?=@)/, "************")
+ return email
+ })() }</p>
</div>
+ </div>
+ {false && <>
<div className='subsection'>
<IconLabelButton text='Bewerken' icon={<EditOutlinedIcon />} />
<div className='dispbl'>