account identity update
allow users to update their JamKazam email and password securly.
This commit is contained in:
parent
b563f22a32
commit
aeb2e50692
|
|
@ -3,7 +3,8 @@ import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const JKModalDialog = ({ title, children, show, onToggle, showFooter }) => {
|
const JKModalDialog = (args) => {
|
||||||
|
const { show, title, children, onToggle, showFooter, ...rest } = args;
|
||||||
const [modal, setModal] = useState(show);
|
const [modal, setModal] = useState(show);
|
||||||
|
|
||||||
const toggle = () => {
|
const toggle = () => {
|
||||||
|
|
@ -18,7 +19,7 @@ const JKModalDialog = ({ title, children, show, onToggle, showFooter }) => {
|
||||||
}, [show]);
|
}, [show]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={modal} toggle={toggle}>
|
<Modal isOpen={modal} toggle={toggle} {...rest}>
|
||||||
<ModalHeader toggle={toggle}>{title}</ModalHeader>
|
<ModalHeader toggle={toggle}>{title}</ModalHeader>
|
||||||
<ModalBody>{children}</ModalBody>
|
<ModalBody>{children}</ModalBody>
|
||||||
{showFooter && (
|
{showFooter && (
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import JKNewMusicSession from '../page/JKNewMusicSession';
|
||||||
import JKMusicSessionsLobby from '../page/JKMusicSessionsLobby';
|
import JKMusicSessionsLobby from '../page/JKMusicSessionsLobby';
|
||||||
|
|
||||||
import JKEditProfile from '../page/JKEditProfile';
|
import JKEditProfile from '../page/JKEditProfile';
|
||||||
|
import JKEditAccount from '../page/JKEditAccount';
|
||||||
|
|
||||||
//import loadable from '@loadable/component';
|
//import loadable from '@loadable/component';
|
||||||
//const DashboardRoutes = loadable(() => import('../../layouts/JKDashboardRoutes'));
|
//const DashboardRoutes = loadable(() => import('../../layouts/JKDashboardRoutes'));
|
||||||
|
|
@ -198,6 +199,7 @@ function JKDashboardMain() {
|
||||||
<PrivateRoute path="/sessions" component={JKMusicSessions} />
|
<PrivateRoute path="/sessions" component={JKMusicSessions} />
|
||||||
<PrivateRoute path="/notifications" component={JKNotifications} />
|
<PrivateRoute path="/notifications" component={JKNotifications} />
|
||||||
<PrivateRoute path="/profile" component={JKEditProfile} />
|
<PrivateRoute path="/profile" component={JKEditProfile} />
|
||||||
|
<PrivateRoute path="/account/identity" component={JKEditAccount} />
|
||||||
{/*Redirect*/}
|
{/*Redirect*/}
|
||||||
<Redirect to="/errors/404" />
|
<Redirect to="/errors/404" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Row, Col, Card, CardBody } from 'reactstrap';
|
||||||
|
import FalconCardHeader from '../common/FalconCardHeader';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import JKEditEmail from '../profile/JKEditEmail';
|
||||||
|
import JKEditPassword from '../profile/JKEditPassword';
|
||||||
|
import JKModalDialog from '../common/JKModalDialog';
|
||||||
|
|
||||||
|
const JKEditAccount = () => {
|
||||||
|
const { t } = useTranslation('account');
|
||||||
|
const [alertText, setAlertText] = useState("")
|
||||||
|
|
||||||
|
const [showAlert, setShowAlert] = useState(false);
|
||||||
|
const toggleAlert = () => setShowAlert(!showAlert);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Card>
|
||||||
|
<FalconCardHeader title={t('identity.page_title')} titleClass="font-weight-bold" />
|
||||||
|
<CardBody className="pt-3" style={{ backgroundColor: '#edf2f9' }}>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<JKEditEmail setAlert={setAlertText} toggleAlert={toggleAlert} />
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<JKEditPassword setAlert={setAlertText} toggleAlert={toggleAlert} />
|
||||||
|
</Col>
|
||||||
|
<Col></Col>
|
||||||
|
</Row>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
<JKModalDialog
|
||||||
|
show={showAlert}
|
||||||
|
onToggle={toggleAlert}
|
||||||
|
title={t('identity.modals.update_notification.title')}
|
||||||
|
data-testid="native-app-unavailable"
|
||||||
|
size="md"
|
||||||
|
>
|
||||||
|
{alertText}
|
||||||
|
</JKModalDialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JKEditAccount;
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import {
|
||||||
|
|
||||||
|
Card,
|
||||||
|
CardHeader,
|
||||||
|
CardBody,
|
||||||
|
Form,
|
||||||
|
FormGroup,
|
||||||
|
Label,
|
||||||
|
Input,
|
||||||
|
InputGroup,
|
||||||
|
InputGroupAddon
|
||||||
|
} from 'reactstrap';
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
|
import { postUpdateAccountEmail } from '../../helpers/rest';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
||||||
|
const JKEditEmail = ({setAlert, toggleAlert}) => {
|
||||||
|
const { t } = useTranslation('account');
|
||||||
|
const { currentUser } = useAuth();
|
||||||
|
const [user, setUser] = useState(null);
|
||||||
|
const [showEmailPassword, setShowEmailPassword] = useState(false);
|
||||||
|
const [submitting, setSubmitting] = useState(false)
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleSubmit,
|
||||||
|
control,
|
||||||
|
formState: { errors },
|
||||||
|
setError,
|
||||||
|
setValue,
|
||||||
|
} = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
current_password: '',
|
||||||
|
new_email: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentUser) {
|
||||||
|
setUser(currentUser);
|
||||||
|
}
|
||||||
|
}, [currentUser]);
|
||||||
|
|
||||||
|
const onSubmitEmail = (data) => {
|
||||||
|
setSubmitting(true)
|
||||||
|
//post
|
||||||
|
const { new_email, current_password } = data;
|
||||||
|
postUpdateAccountEmail(currentUser.id, { email: new_email, current_password })
|
||||||
|
.then(response => {
|
||||||
|
setAlert('A confirmation email has been sent to your email. Please check your email and click the link to confirm your new email address.');
|
||||||
|
setValue('current_password', '');
|
||||||
|
setValue('new_email', '');
|
||||||
|
toggleAlert()
|
||||||
|
})
|
||||||
|
.catch(async error => {
|
||||||
|
const errorResp = await error.json()
|
||||||
|
console.log(errorResp)
|
||||||
|
if(errorResp.errors){
|
||||||
|
const errors = errorResp.errors;
|
||||||
|
if(errors.current_password && errors.current_password.length){
|
||||||
|
errors.current_password.forEach(error => {
|
||||||
|
setError('current_password', {
|
||||||
|
type: 'manual',
|
||||||
|
message: `Current password ${error}`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(errors.update_email && errors.update_email.length){
|
||||||
|
errors.update_email.forEach(error => {
|
||||||
|
setError('new_email', {
|
||||||
|
type: 'manual',
|
||||||
|
message: `New email ${error}`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}).finally(() => {
|
||||||
|
setSubmitting(false)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<h5>Email</h5>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody className="bg-light" style={{ minHeight: 300 }}>
|
||||||
|
<small>
|
||||||
|
To update the email associated with your account, enter your current password (for security reasons) and the
|
||||||
|
new email, and click the "Save Email" button.
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<Form className="mt-2" onSubmit={handleSubmit(onSubmitEmail)}>
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="current_password">Current Password</Label>
|
||||||
|
<Controller
|
||||||
|
name="current_password"
|
||||||
|
control={control}
|
||||||
|
rules={{ required: 'Current password is required' }}
|
||||||
|
render={({ field }) => (
|
||||||
|
<InputGroup>
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type={showEmailPassword ? 'text' : 'password'}
|
||||||
|
className="form-control"
|
||||||
|
id="current_password"
|
||||||
|
placeholder="Current Password"
|
||||||
|
/>
|
||||||
|
<InputGroupAddon
|
||||||
|
addonType="append"
|
||||||
|
onClick={() => {
|
||||||
|
setShowEmailPassword(!showEmailPassword);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="input-group-text">
|
||||||
|
<FontAwesomeIcon icon={showEmailPassword ? 'eye-slash' : 'eye'} />
|
||||||
|
</span>
|
||||||
|
</InputGroupAddon>
|
||||||
|
</InputGroup>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.current_password && <div className="text-danger"><small>{errors.current_password.message}</small></div>}
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="new_email">New Email</Label>
|
||||||
|
<Controller
|
||||||
|
name="new_email"
|
||||||
|
control={control}
|
||||||
|
rules={{
|
||||||
|
required: 'New email is required',
|
||||||
|
pattern: {
|
||||||
|
value: /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/,
|
||||||
|
message: 'Invalid email address'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="email"
|
||||||
|
className="form-control"
|
||||||
|
id="new_email"
|
||||||
|
placeholder={user ? user.email : 'New Email'}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.new_email && <div className="text-danger"><small>{errors.new_email.message}</small></div>}
|
||||||
|
</FormGroup>
|
||||||
|
<div className='d-flex align-content-center justify-content-start'>
|
||||||
|
<input type="submit" className="btn btn-primary" value="Save Email" disabled={submitting} />
|
||||||
|
<span className='ml-2'>
|
||||||
|
{ submitting && <FontAwesomeIcon icon="spinner" />}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JKEditEmail;
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Card, CardHeader, CardBody, Form, FormGroup, Label, Input, InputGroup, InputGroupAddon } from 'reactstrap';
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
|
import { postUpdateAccountPassword, requestPasswordReset } from '../../helpers/rest';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
||||||
|
const JKEditPassword = ({ setAlert, toggleAlert }) => {
|
||||||
|
const { t } = useTranslation('account');
|
||||||
|
const { currentUser } = useAuth();
|
||||||
|
const [user, setUser] = useState(null);
|
||||||
|
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
const [showNewPassword, setShowNewPassword] = useState(false);
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleSubmit: handleSubmit,
|
||||||
|
control: control,
|
||||||
|
formState: { errors },
|
||||||
|
setError,
|
||||||
|
setValue
|
||||||
|
} = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
current_password: '',
|
||||||
|
new_password: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentUser) {
|
||||||
|
setUser(currentUser);
|
||||||
|
}
|
||||||
|
}, [currentUser]);
|
||||||
|
|
||||||
|
const onSubmitPassword = data => {
|
||||||
|
setSubmitting(true);
|
||||||
|
const { new_password, current_password } = data;
|
||||||
|
postUpdateAccountPassword(currentUser.id, { current_password, new_password })
|
||||||
|
.then(response => {
|
||||||
|
setAlert('Your password has been successfully updated.');
|
||||||
|
setValue('current_password', '');
|
||||||
|
setValue('new_password', '');
|
||||||
|
toggleAlert();
|
||||||
|
})
|
||||||
|
.catch(async error => {
|
||||||
|
console.log(error);
|
||||||
|
const errorResp = await error.json();
|
||||||
|
console.log(errorResp);
|
||||||
|
if (errorResp.errors) {
|
||||||
|
const errors = errorResp.errors;
|
||||||
|
if (errors.current_password && errors.current_password.length) {
|
||||||
|
errors.current_password.forEach(error => {
|
||||||
|
setError('current_password', {
|
||||||
|
type: 'manual',
|
||||||
|
message: `Current password ${error}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (errors.password && errors.password.length) {
|
||||||
|
errors.password.forEach(error => {
|
||||||
|
setError('new_password', {
|
||||||
|
type: 'manual',
|
||||||
|
message: `New password ${error}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setSubmitting(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const requestResetPassword = async (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
if (!currentUser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await requestPasswordReset(currentUser.id);
|
||||||
|
setAlert(
|
||||||
|
'A password reset email has been sent to your email. Please check your email and click the link to reset your password.'
|
||||||
|
);
|
||||||
|
toggleAlert();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<h5>Password</h5>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody className="bg-light" style={{ minHeight: 300 }}>
|
||||||
|
<small>
|
||||||
|
To update the password associated with your account, enter your current password (for security reasons) and
|
||||||
|
the new password, and click the "Save Password" button.
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<Form className="mt-2" onSubmit={handleSubmit(onSubmitPassword)}>
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="current_password">Current Password</Label>
|
||||||
|
<Controller
|
||||||
|
name="current_password"
|
||||||
|
control={control}
|
||||||
|
rules={{ required: 'Current password is required' }}
|
||||||
|
render={({ field }) => (
|
||||||
|
<InputGroup>
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type={showPassword ? 'text' : 'password'}
|
||||||
|
className="form-control"
|
||||||
|
id="current_password"
|
||||||
|
placeholder="Current Password"
|
||||||
|
/>
|
||||||
|
<InputGroupAddon
|
||||||
|
addonType="append"
|
||||||
|
onClick={() => {
|
||||||
|
setShowPassword(!showPassword);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="input-group-text">
|
||||||
|
<FontAwesomeIcon icon={showPassword ? 'eye-slash' : 'eye'} />
|
||||||
|
</span>
|
||||||
|
</InputGroupAddon>
|
||||||
|
</InputGroup>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.current_password && (
|
||||||
|
<div className="text-danger">
|
||||||
|
<small>{errors.current_password.message}</small>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="new_password">New Password</Label>
|
||||||
|
<Controller
|
||||||
|
name="new_password"
|
||||||
|
control={control}
|
||||||
|
rules={{ required: 'New password is required' }}
|
||||||
|
render={({ field }) => (
|
||||||
|
<InputGroup>
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
type={showNewPassword ? 'text' : 'password'}
|
||||||
|
className="form-control"
|
||||||
|
id="new_password"
|
||||||
|
placeholder="New Password"
|
||||||
|
/>
|
||||||
|
<InputGroupAddon
|
||||||
|
addonType="append"
|
||||||
|
onClick={() => {
|
||||||
|
setShowNewPassword(!showNewPassword);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="input-group-text">
|
||||||
|
<FontAwesomeIcon icon={showNewPassword ? 'eye-slash' : 'eye'} />
|
||||||
|
</span>
|
||||||
|
</InputGroupAddon>
|
||||||
|
</InputGroup>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{errors.new_password && (
|
||||||
|
<div className="text-danger">
|
||||||
|
<small>{errors.new_password.message}</small>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</FormGroup>
|
||||||
|
<div className="d-flex align-content-center justify-content-start">
|
||||||
|
<input type="submit" className="btn btn-primary" value="Save Password" disabled={submitting} />
|
||||||
|
<span className="ml-2">{submitting && <FontAwesomeIcon icon="spinner" />}</span>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
<div className="mt-2">
|
||||||
|
<small>
|
||||||
|
If you can not remember your current password, <a href="#" onClick={requestResetPassword}>Click here</a> to reset
|
||||||
|
your password, and you will receive an email with instructions on how to reset your password to the email
|
||||||
|
address associated with your JamKazam account.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JKEditPassword;
|
||||||
|
|
@ -41,7 +41,6 @@ function secureFetch(path, options) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log('apiFetch Some error occured');
|
console.log('apiFetch Some error occured');
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
//here you also can thorow custom error too
|
//here you also can thorow custom error too
|
||||||
reject(response);
|
reject(response);
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ import {
|
||||||
faExclamationTriangle,
|
faExclamationTriangle,
|
||||||
faExternalLinkAlt,
|
faExternalLinkAlt,
|
||||||
faEye,
|
faEye,
|
||||||
|
faEyeSlash,
|
||||||
faFileAlt,
|
faFileAlt,
|
||||||
faFileArchive,
|
faFileArchive,
|
||||||
faFilePdf,
|
faFilePdf,
|
||||||
|
|
@ -158,7 +159,7 @@ import {
|
||||||
faRecordVinyl,
|
faRecordVinyl,
|
||||||
faAddressCard,
|
faAddressCard,
|
||||||
faVolumeUp,
|
faVolumeUp,
|
||||||
faSpinner
|
faSpinner,
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
//import { faAcousticGuitar } from "../icons";
|
//import { faAcousticGuitar } from "../icons";
|
||||||
|
|
@ -245,6 +246,7 @@ library.add(
|
||||||
faFilePdf,
|
faFilePdf,
|
||||||
faFileAlt,
|
faFileAlt,
|
||||||
faEye,
|
faEye,
|
||||||
|
faEyeSlash,
|
||||||
faCaretUp,
|
faCaretUp,
|
||||||
faCodeBranch,
|
faCodeBranch,
|
||||||
faExclamationTriangle,
|
faExclamationTriangle,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import apiFetch from "./apiFetch";
|
import apiFetch from './apiFetch';
|
||||||
|
|
||||||
export const getMusicians = (page) => {
|
export const getMusicians = page => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/search/musicians?results=true`)
|
apiFetch(`/search/musicians?results=true`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// export const getPeople = (page) => {
|
// export const getPeople = (page) => {
|
||||||
// return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
|
|
@ -16,48 +16,48 @@ export const getMusicians = (page) => {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export const getPersonById = (id) => {
|
export const getPersonById = id => {
|
||||||
return new Promise((resolve, reject) => (
|
return new Promise((resolve, reject) =>
|
||||||
apiFetch(`/users/${id}/profile?show_teacher=true`)
|
apiFetch(`/users/${id}/profile?show_teacher=true`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
))
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getPeople = ({ data, offset, limit } = {}) => {
|
export const getPeople = ({ data, offset, limit } = {}) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/filter?offset=${offset}&limit=${limit}`, {
|
apiFetch(`/filter?offset=${offset}&limit=${limit}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getPeopleIndex = () => {
|
export const getPeopleIndex = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/users`)
|
apiFetch(`/users`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getGenres = () => {
|
export const getGenres = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch('/genres')
|
apiFetch('/genres')
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getInstruments = () => {
|
export const getInstruments = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch('/instruments')
|
apiFetch('/instruments')
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// export const getCurrentUser = () => {
|
// export const getCurrentUser = () => {
|
||||||
// return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
|
|
@ -67,13 +67,13 @@ export const getInstruments = () => {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export const getFriends = (userId) => {
|
export const getFriends = userId => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/users/${userId}/friends`)
|
apiFetch(`/users/${userId}/friends`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const addFriend = (userId, friendId) => {
|
export const addFriend = (userId, friendId) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -81,108 +81,106 @@ export const addFriend = (userId, friendId) => {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ friend_id: friendId })
|
body: JSON.stringify({ friend_id: friendId })
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const removeFriend = (userId, friendId) => {
|
export const removeFriend = (userId, friendId) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/users/${userId}/friends/${friendId}`, {
|
apiFetch(`/users/${userId}/friends/${friendId}`, {
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getTextMessages = (options = {}) => {
|
export const getTextMessages = (options = {}) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/text_messages?${new URLSearchParams(options)}`)
|
apiFetch(`/text_messages?${new URLSearchParams(options)}`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const createTextMessage = (options) => {
|
export const createTextMessage = options => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/text_messages`, {
|
apiFetch(`/text_messages`, {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify(options)
|
body: JSON.stringify(options)
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const createLobbyChatMessage = (options) => {
|
export const createLobbyChatMessage = options => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/chat`, {
|
apiFetch(`/chat`, {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify(options)
|
body: JSON.stringify(options)
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getNotifications = (userId, options = {}) => {
|
export const getNotifications = (userId, options = {}) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/users/${userId}/notifications?${new URLSearchParams(options)}`)
|
apiFetch(`/users/${userId}/notifications?${new URLSearchParams(options)}`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export const acceptFriendRequest = (userId, options = {}) => {
|
export const acceptFriendRequest = (userId, options = {}) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const { status, friend_request_id } = options
|
const { status, friend_request_id } = options;
|
||||||
apiFetch(`/users/${userId}/friend_requests/${friend_request_id}`, {
|
apiFetch(`/users/${userId}/friend_requests/${friend_request_id}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ status })
|
body: JSON.stringify({ status })
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const deleteNotification = (userId, notificationId) => {
|
export const deleteNotification = (userId, notificationId) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/users/${userId}/notifications/${notificationId}`, {
|
apiFetch(`/users/${userId}/notifications/${notificationId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE'
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getSessions = () => {
|
export const getSessions = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/sessions`)
|
apiFetch(`/sessions`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getLatencyToUsers = (currentUserId, participantIds) => {
|
export const getLatencyToUsers = (currentUserId, participantIds) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const query = participantIds.map(id => `user_ids[]=${id}`).join('&')
|
const query = participantIds.map(id => `user_ids[]=${id}`).join('&');
|
||||||
apiFetch(`/users/${currentUserId}/latencies?${query}`)
|
apiFetch(`/users/${currentUserId}/latencies?${query}`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getLobbyChatMessages = (options = {}) => {
|
export const getLobbyChatMessages = (options = {}) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
console.log('getLobbyChatMessages', options)
|
console.log('getLobbyChatMessages', options);
|
||||||
apiFetch(`/chat?${new URLSearchParams(options)}`)
|
apiFetch(`/chat?${new URLSearchParams(options)}`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
export const updateUser = (userId, options) => {
|
export const updateUser = (userId, options) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -190,32 +188,65 @@ export const updateUser = (userId, options) => {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
body: JSON.stringify(options)
|
body: JSON.stringify(options)
|
||||||
})
|
})
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
export const getCountries = () => {
|
export const getCountries = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/countries`)
|
apiFetch(`/countries`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getRegions = (countryId) => {
|
export const getRegions = countryId => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/regions?country=${countryId}`)
|
apiFetch(`/regions?country=${countryId}`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getCities = (countryId, regionId) => {
|
export const getCities = (countryId, regionId) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
apiFetch(`/cities?country=${countryId}®ion=${regionId}`)
|
apiFetch(`/cities?country=${countryId}®ion=${regionId}`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const postUpdateAccountEmail = (userId, options) => {
|
||||||
|
const { email, current_password } = options;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
apiFetch(`/users/${userId}/update_email`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ update_email: email, current_password })
|
||||||
|
})
|
||||||
|
.then(response => resolve(response))
|
||||||
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const postUpdateAccountPassword = (userId, options) => {
|
||||||
|
const { new_password, current_password } = options;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
apiFetch(`/users/${userId}/set_password`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ old_password: current_password, new_password, new_password_confirm: new_password })
|
||||||
|
})
|
||||||
|
.then(response => resolve(response))
|
||||||
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const requestPasswordReset = (userId) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
apiFetch(`/users/${userId}/request_reset_password`, {
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
.then(response => resolve(response))
|
||||||
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import authTranslationsEN from './locales/en/auth.json'
|
||||||
import sessTranslationsEN from './locales/en/sessions.json'
|
import sessTranslationsEN from './locales/en/sessions.json'
|
||||||
import unsubscribeTranslationsEN from './locales/en/unsubscribe.json'
|
import unsubscribeTranslationsEN from './locales/en/unsubscribe.json'
|
||||||
import profileEN from './locales/en/profile.json'
|
import profileEN from './locales/en/profile.json'
|
||||||
|
import accountEN from './locales/en/account.json'
|
||||||
|
|
||||||
import commonTranslationsES from './locales/es/common.json'
|
import commonTranslationsES from './locales/es/common.json'
|
||||||
import homeTranslationsES from './locales/es/home.json'
|
import homeTranslationsES from './locales/es/home.json'
|
||||||
|
|
@ -16,6 +17,7 @@ import authTranslationsES from './locales/es/auth.json'
|
||||||
import sessTranslationsES from './locales/es/sessions.json'
|
import sessTranslationsES from './locales/es/sessions.json'
|
||||||
import unsubscribeTranslationsES from './locales/es/unsubscribe.json'
|
import unsubscribeTranslationsES from './locales/es/unsubscribe.json'
|
||||||
import profileES from './locales/es/profile.json'
|
import profileES from './locales/es/profile.json'
|
||||||
|
import accountES from './locales/es/account.json'
|
||||||
|
|
||||||
i18n.use(initReactI18next).init({
|
i18n.use(initReactI18next).init({
|
||||||
fallbackLng: 'en',
|
fallbackLng: 'en',
|
||||||
|
|
@ -29,7 +31,8 @@ i18n.use(initReactI18next).init({
|
||||||
auth: authTranslationsEN,
|
auth: authTranslationsEN,
|
||||||
sessions: sessTranslationsEN,
|
sessions: sessTranslationsEN,
|
||||||
unsubscribe: unsubscribeTranslationsEN,
|
unsubscribe: unsubscribeTranslationsEN,
|
||||||
profile: profileEN
|
profile: profileEN,
|
||||||
|
account: accountEN
|
||||||
},
|
},
|
||||||
es: {
|
es: {
|
||||||
//translations: require('./locales/es/translations.json')
|
//translations: require('./locales/es/translations.json')
|
||||||
|
|
@ -39,7 +42,8 @@ i18n.use(initReactI18next).init({
|
||||||
auth: authTranslationsES,
|
auth: authTranslationsES,
|
||||||
sessions: sessTranslationsES,
|
sessions: sessTranslationsES,
|
||||||
unsubscribe: unsubscribeTranslationsES,
|
unsubscribe: unsubscribeTranslationsES,
|
||||||
profile: profileES
|
profile: profileES,
|
||||||
|
account: accountES
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//ns: ['translations'],
|
//ns: ['translations'],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"identity": {
|
||||||
|
"page_title": "Identity",
|
||||||
|
"modals": {
|
||||||
|
"update_notification": {
|
||||||
|
"title": "Account Identity Updated"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ class ApiUsersController < ApiController
|
||||||
:friend_show, :friend_destroy, # friends
|
:friend_show, :friend_destroy, # friends
|
||||||
:notification_index, :notification_destroy, # notifications
|
:notification_index, :notification_destroy, # notifications
|
||||||
:band_invitation_index, :band_invitation_show, :band_invitation_update, # band invitations
|
:band_invitation_index, :band_invitation_show, :band_invitation_update, # band invitations
|
||||||
:set_password, :begin_update_email, :update_avatar, :delete_avatar, :generate_filepicker_policy,
|
:set_password, :begin_update_email, :update_avatar, :delete_avatar, :generate_filepicker_policy, :request_reset_password,
|
||||||
:share_session, :share_recording,
|
:share_session, :share_recording,
|
||||||
:affiliate_report, :audio_latency, :get_latencies, :broadcast_notification, :redeem_giftcard]
|
:affiliate_report, :audio_latency, :get_latencies, :broadcast_notification, :redeem_giftcard]
|
||||||
|
|
||||||
|
|
@ -333,6 +333,11 @@ class ApiUsersController < ApiController
|
||||||
respond_with responder: ApiResponder, :status => 204
|
respond_with responder: ApiResponder, :status => 204
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def request_reset_password
|
||||||
|
User.reset_password(current_user.email, ApplicationHelper.base_uri(request))
|
||||||
|
respond_with current_user, responder: ApiResponder, :status => 200
|
||||||
|
end
|
||||||
|
|
||||||
###################### AUTHENTICATION ###################
|
###################### AUTHENTICATION ###################
|
||||||
def auth_session_create
|
def auth_session_create
|
||||||
@user = User.authenticate(params[:email], params[:password])
|
@user = User.authenticate(params[:email], params[:password])
|
||||||
|
|
|
||||||
|
|
@ -403,6 +403,7 @@ Rails.application.routes.draw do
|
||||||
match '/users/complete/:signup_token' => 'api_users#complete', as: 'complete', via: 'post'
|
match '/users/complete/:signup_token' => 'api_users#complete', as: 'complete', via: 'post'
|
||||||
match '/users/authorizations/google' => 'api_users#google_auth', :via => :get
|
match '/users/authorizations/google' => 'api_users#google_auth', :via => :get
|
||||||
match '/users/:id/set_password' => 'api_users#set_password', :via => :post
|
match '/users/:id/set_password' => 'api_users#set_password', :via => :post
|
||||||
|
match '/users/:id/request_reset_password' => 'api_users#request_reset_password', :via => :post
|
||||||
|
|
||||||
match '/reviews' => 'api_reviews#index', :via => :get
|
match '/reviews' => 'api_reviews#index', :via => :get
|
||||||
match '/reviews' => 'api_reviews#create', :via => :post
|
match '/reviews' => 'api_reviews#create', :via => :post
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue