import React, { useState, useEffect } from 'react'; import { useHistory } from 'react-router-dom'; import * as loadImage from 'blueimp-load-image'; import ReactCrop from 'react-image-crop'; import 'react-image-crop/dist/ReactCrop.css'; import './light.css'; import { MembersDropdown } from './Members.js'; import { Button, Container, Form, Grid, Header, Message, Segment } from 'semantic-ui-react'; import './components/MembersList' import { requester, randomString } from './utils.js'; import { MembersList } from './components/MembersList'; function LogoutEverywhere(props) { const { token } = props; const [error, setError] = useState(false); const [loading, setLoading] = useState(false); const [yousure, setYousure] = useState(false); const history = useHistory(); const handleClick = () => { if (yousure) { if (loading) return; setLoading(true); requester('/rest-auth/logout/', 'POST', token, {}) .then(res => { setYousure(false); history.push('/'); window.scrollTo(0, 0); }) .catch(err => { setLoading(false); console.log(err); setError(err.data); }); } else { setYousure(true); } }; return (
Log Out from Everywhere

Use this to log out from all sessions on all computers.

{error &&

Error, something went wrong.

}
); }; function ChangePasswordForm(props) { const { token } = props; const [input, setInput] = useState({}); const [error, setError] = useState({}); const [progress, setProgress] = useState([]); const [loading, setLoading] = useState(false); const history = useHistory(); const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value }); const handleChange = (e) => handleValues(e, e.currentTarget); const handleSubmit = (e) => { if (loading) return; setLoading(true); const request_id = randomString(); const getStatus = () => { requester('/stats/progress/?request_id='+request_id, 'GET') .then(res => { setProgress(res); }) .catch(err => { console.log(err); }); }; const interval = setInterval(getStatus, 500); const data = { ...input, request_id: request_id }; requester('/password/change/', 'POST', token, data) .then(res => { clearInterval(interval); setError({}); history.push('/'); }) .catch(err => { clearInterval(interval); setLoading(false); console.log(err); setError(err.data); }); }; const makeProps = (name) => ({ name: name, onChange: handleChange, value: input[name] || '', error: error[name], }); return (
Change Password

{progress.map(x => <>{x}
)}

Submit ); }; export function ImageCrop(props) { const { file, crop, setCrop } = props; const [src, setSrc] = useState(false); useEffect(() => { setSrc(false); setCrop({ unit: '%', height: 100, aspect: 3/4 }); loadImage( file, img => { setSrc(img.toDataURL()); }, { meta: true, orientation: true, canvas: true, maxWidth: 300, maxHeight: 300, } ); }, [file]); return ( src ? setCrop(percentCrop)} /> :

Loading...

); } export function AccountForm(props) { const { token, user, refreshUser, isSignup } = props; const member = user.member; const [input, setInput] = useState({ ...member, set_details: true }); const [error, setError] = useState({}); const [loading, setLoading] = useState(false); const [crop, setCrop] = useState(false); const history = useHistory(); const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value }); const handleUpload = (e, v) => setInput({ ...input, [v.name]: e.target.files[0] }); const handleChange = (e) => handleValues(e, e.currentTarget); const handleCheck = (e, v) => setInput({ ...input, [v.name]: v.checked }); const handleSubmit = (e) => { if (loading) return; setLoading(true); const data = { ...input, email: input.email.toLowerCase(), crop: JSON.stringify(crop) }; requester('/members/' + member.id + '/', 'PATCH', token, data) .then(res => { setError({}); refreshUser(); history.push('/'); }) .catch(err => { setLoading(false); console.log(err); setError(err.data); }); }; const makeProps = (name) => ({ name: name, onChange: handleChange, value: input[name] || '', error: error[name], ...(input[name] ? {} : {icon: 'edit'}), }); return (
Member Details

{user.username}

{!isSignup && } {!isSignup && } {member.mediawiki_username &&

{member.mediawiki_username}

} {member.discourse_username && } {member.discourse_username && member.discourse_username !== input.discourse_username && Make sure you remember

You'll use this to log into the Protospace Forum (Spacebar).

} {!isSignup && } {!isSignup && } {input.photo && <> {crop && crop.width === crop.height ?

It's the perfect size!

:

Move the box above to crop your image.

} } {isSignup && } {isSignup && } Submit ); }; export function Sponsorship(props) { const { user: { member } } = props; return (
My sponsors:
I am sponsoring:
); }; export function BioNotesForm(props) { const { token, user, refreshUser } = props; const member = user.member; const [input, setInput] = useState({ ...member, set_details: true }); const [error, setError] = useState({}); const [loading, setLoading] = useState(false); const history = useHistory(); const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value }); const handleChange = (e) => handleValues(e, e.currentTarget); const handleSubmit = (e) => { if (loading) return; setLoading(true); requester('/members/' + member.id + '/', 'PATCH', token, input) .then(res => { setError({}); refreshUser(); history.push('/'); }) .catch(err => { setLoading(false); console.log(err); setError(err.data); }); }; const makeProps = (name) => ({ name: name, onChange: handleChange, value: input[name] || '', error: error[name], }); return (
Bio / Notes
400 ? ' — ' + input.public_bio.length + ' / 512' : '')} {...makeProps('public_bio')} />

Bio shared with members. Example: contact info, allergies, hobbies, etc.

400 ? ' — ' + input.private_notes.length + ' / 512' : '')} {...makeProps('private_notes')} />

Notes visible only to directors and admins.

Submit ); }; export function Account(props) { return (
Account Settings
); };