React/Redux - publish component #323
9 changed files with 100 additions and 136 deletions
|
@ -1,4 +0,0 @@
|
|||
function sendAuthRequest (channelName, password, url) {
|
||||
const params = `username=${channelName}&password=${password}`;
|
||||
return postRequest(url, params);
|
||||
}
|
|
@ -20,17 +20,36 @@ function showChannelCreationError(msg) {
|
|||
}
|
||||
|
||||
function publishNewChannel (event) {
|
||||
const userName = document.getElementById('new-channel-name').value;
|
||||
const username = document.getElementById('new-channel-name').value;
|
||||
const password = document.getElementById('new-channel-password').value;
|
||||
// prevent default so this script can handle submission
|
||||
event.preventDefault();
|
||||
// validate submission
|
||||
validationFunctions.validateNewChannelSubmission(userName, password)
|
||||
validationFunctions.validateNewChannelSubmission(username, password)
|
||||
.then(() => {
|
||||
showChannelCreateInProgressDisplay();
|
||||
return sendAuthRequest(userName, password, '/signup') // post the request
|
||||
// return sendAuthRequest(userName, password, '/signup') // post the request
|
||||
return fetch('/signup', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({username, password}),
|
||||
headers: new Headers({
|
||||
'Content-Type': 'application/json'
|
||||
}),
|
||||
credentials: 'include',
|
||||
})
|
||||
.then(result => {
|
||||
.then(function(response) {
|
||||
if (response.ok){
|
||||
return response.json();
|
||||
} else {
|
||||
throw response;
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw error;
|
||||
})
|
||||
})
|
||||
.then(signupResult => {
|
||||
console.log('signup success:', signupResult);
|
||||
showChannelCreateDoneDisplay();
|
||||
window.location = '/';
|
||||
})
|
||||
|
@ -40,7 +59,7 @@ function publishNewChannel (event) {
|
|||
validationFunctions.showError(channelNameErrorDisplayElement, error.message);
|
||||
} else {
|
||||
console.log('signup failure:', error);
|
||||
showChannelCreationError('Unfortunately, we encountered an error while creating your channel. Please let us know in slack!');
|
||||
showChannelCreationError('Unfortunately, we encountered an error while creating your channel. Please let us know in slack!', error);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,94 +1,3 @@
|
|||
function getRequest (url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let xhttp = new XMLHttpRequest();
|
||||
xhttp.open('GET', url, true);
|
||||
xhttp.responseType = 'json';
|
||||
xhttp.onreadystatechange = () => {
|
||||
if (xhttp.readyState === 4 ) {
|
||||
if ( xhttp.status === 200) {
|
||||
resolve(xhttp.response);
|
||||
} else if (xhttp.status === 403) {
|
||||
reject('Wrong channel name or password');
|
||||
} else {
|
||||
reject('request failed with status:' + xhttp.status);
|
||||
};
|
||||
}
|
||||
};
|
||||
xhttp.send();
|
||||
})
|
||||
}
|
||||
|
||||
function postRequest (url, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let xhttp = new XMLHttpRequest();
|
||||
xhttp.open('POST', url, true);
|
||||
xhttp.responseType = 'json';
|
||||
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhttp.onreadystatechange = () => {
|
||||
if (xhttp.readyState === 4 ) {
|
||||
if ( xhttp.status === 200) {
|
||||
resolve(xhttp.response);
|
||||
} else if (xhttp.status === 401) {
|
||||
reject( new AuthenticationError('Wrong channel name or password'));
|
||||
} else {
|
||||
reject('request failed with status:' + xhttp.status);
|
||||
};
|
||||
}
|
||||
};
|
||||
xhttp.send(params);
|
||||
})
|
||||
}
|
||||
|
||||
function createProgressBar(element, size){
|
||||
var x = 0;
|
||||
var adder = 1;
|
||||
// create the bar holder & place it
|
||||
var barHolder = document.createElement('p');
|
||||
for (var i = 0; i < size; i++) {
|
||||
const bar = document.createElement('span');
|
||||
bar.innerText = '| ';
|
||||
bar.setAttribute('class', 'progress-bar progress-bar--inactive');
|
||||
barHolder.appendChild(bar);
|
||||
}
|
||||
element.appendChild(barHolder);
|
||||
// get the bars
|
||||
const bars = document.getElementsByClassName('progress-bar');
|
||||
// function to update the bars' classes
|
||||
function updateOneBar(){
|
||||
// update the appropriate bar
|
||||
if (x > -1 && x < size){
|
||||
if (adder === 1){
|
||||
bars[x].setAttribute('class', 'progress-bar progress-bar--active');
|
||||
} else {
|
||||
bars[x].setAttribute('class', 'progress-bar progress-bar--inactive');
|
||||
}
|
||||
}
|
||||
// set x
|
||||
if (x === size){
|
||||
adder = -1;
|
||||
} else if ( x === -1){
|
||||
adder = 1;
|
||||
}
|
||||
// update the adder
|
||||
x += adder;
|
||||
|
||||
};
|
||||
// start updater
|
||||
setInterval(updateOneBar, 300);
|
||||
}
|
||||
|
||||
function copyToClipboard(event){
|
||||
var elementToCopy = event.target.dataset.elementtocopy;
|
||||
var element = document.getElementById(elementToCopy);
|
||||
var errorElement = 'input-error-copy-text' + elementToCopy;
|
||||
element.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
} catch (err) {
|
||||
validationFunctions.showError(errorElement, 'Oops, unable to copy');
|
||||
}
|
||||
}
|
||||
|
||||
// Create new error objects, that prototypically inherit from the Error constructor
|
||||
function FileError(message) {
|
||||
this.name = 'FileError';
|
||||
|
|
|
@ -1,11 +1,28 @@
|
|||
function loginToChannel (event) {
|
||||
const userName = document.getElementById('channel-login-name-input').value;
|
||||
const username = document.getElementById('channel-login-name-input').value;
|
||||
const password = document.getElementById('channel-login-password-input').value;
|
||||
// prevent default
|
||||
event.preventDefault()
|
||||
validationFunctions.validateNewChannelLogin(userName, password)
|
||||
validationFunctions.validateNewChannelLogin(username, password)
|
||||
.then(() => {
|
||||
return sendAuthRequest(userName, password, '/login')
|
||||
return fetch('/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({username, password}),
|
||||
headers: new Headers({
|
||||
'Content-Type': 'application/json'
|
||||
}),
|
||||
credentials: 'include',
|
||||
})
|
||||
.then(function(response) {
|
||||
if (response.ok){
|
||||
return response.json();
|
||||
} else {
|
||||
throw response;
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw error;
|
||||
})
|
||||
})
|
||||
.then(result => {
|
||||
window.location = '/';
|
||||
|
|
|
@ -18,9 +18,23 @@ const validationFunctions = {
|
|||
}
|
||||
},
|
||||
// validation functions to check claim & channel name eligibility as the inputs change
|
||||
isChannelNameAvailable: function (name) {
|
||||
return this.isNameAvailable(name, '/api/channel-is-available/');
|
||||
},
|
||||
isClaimNameAvailable: function (name) {
|
||||
return this.isNameAvailable(name, '/api/claim-is-available/')
|
||||
},
|
||||
isNameAvailable: function (name, apiUrl) {
|
||||
console.log('isNameAvailable?', name);
|
||||
const url = apiUrl + name;
|
||||
return getRequest(url)
|
||||
return fetch(url)
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('isNameAvailable error', error);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
showError: function (errorDisplay, errorMsg) {
|
||||
errorDisplay.hidden = false;
|
||||
|
@ -38,20 +52,24 @@ const validationFunctions = {
|
|||
successElement.hidden = true;
|
||||
successElement.innerHTML = "";
|
||||
},
|
||||
checkAvailability: function (name, successDisplayElement, errorDisplayElement, validateName, errorMessage, apiUrl) {
|
||||
checkChannelName: function (name) {
|
||||
var successDisplayElement = document.getElementById('input-success-channel-name');
|
||||
var errorDisplayElement = document.getElementById('input-error-channel-name');
|
||||
var channelName = `@${name}`;
|
||||
var that = this;
|
||||
try {
|
||||
// check to make sure the characters are valid
|
||||
validateName(name);
|
||||
that.validateChannelName(channelName);
|
||||
// check to make sure it is available
|
||||
that.isNameAvailable(name, apiUrl)
|
||||
.then(function (result) {
|
||||
if (result === true) {
|
||||
that.isChannelNameAvailable(channelName)
|
||||
.then(function(isAvailable){
|
||||
console.log('isChannelNameAvailable:', isAvailable);
|
||||
if (isAvailable) {
|
||||
that.hideError(errorDisplayElement);
|
||||
that.showSuccess(successDisplayElement)
|
||||
} else {
|
||||
that.hideSuccess(successDisplayElement);
|
||||
that.showError(errorDisplayElement, errorMessage);
|
||||
that.showError(errorDisplayElement, 'Sorry, that name is already taken');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -63,12 +81,6 @@ const validationFunctions = {
|
|||
that.showError(errorDisplayElement, error.message);
|
||||
}
|
||||
},
|
||||
checkChannelName: function (name) {
|
||||
const successDisplayElement = document.getElementById('input-success-channel-name');
|
||||
const errorDisplayElement = document.getElementById('input-error-channel-name');
|
||||
name = `@${name}`;
|
||||
this.checkAvailability(name, successDisplayElement, errorDisplayElement, this.validateChannelName, 'Sorry, that name is already taken', '/api/channel-is-available/');
|
||||
},
|
||||
// validation function which checks all aspects of a new channel submission
|
||||
validateNewChannelSubmission: function (userName, password) {
|
||||
const channelName = `@${userName}`;
|
||||
|
@ -87,16 +99,15 @@ const validationFunctions = {
|
|||
return reject(error);
|
||||
}
|
||||
// 3. if all validation passes, check availability of the name
|
||||
that.isNameAvailable(channelName, '/api/channel-is-available/') // validate the availability
|
||||
.then(function(result) {
|
||||
if (result) {
|
||||
that.isChannelNameAvailable(channelName)
|
||||
.then(function(isAvailable) {
|
||||
if (isAvailable) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new ChannelNameError('Sorry, that name is already taken'));
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log('error evaluating channel name availability', error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
<body id="main-body">
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
<script src="/assets/js/validationFunctions.js"></script>
|
||||
<script src="/assets/js/authFunctions.js"></script>
|
||||
<script src="/assets/js/loginFunctions.js"></script>
|
||||
<script src="/assets/js/createChannelFunctions.js"></script>
|
||||
{{{ body }}}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -113,4 +113,15 @@
|
|||
toggle.dataset.status = "closed";
|
||||
}
|
||||
}
|
||||
function copyToClipboard(event){
|
||||
var elementToCopy = event.target.dataset.elementtocopy;
|
||||
var element = document.getElementById(elementToCopy);
|
||||
var errorElement = 'input-error-copy-text' + elementToCopy;
|
||||
element.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
} catch (err) {
|
||||
validationFunctions.showError(errorElement, 'Oops, unable to copy');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -29,9 +29,11 @@
|
|||
|
||||
<div id="channel-publish-in-progress" hidden="true">
|
||||
<p>Creating your new channel. This may take a few seconds...</p>
|
||||
<div id="create-channel-progress-bar"></div>
|
||||
{{> progressBar}}
|
||||
</div>
|
||||
|
||||
<div id="channel-publish-done" hidden="true">
|
||||
<p>Your channel has been successfully created!</p>
|
||||
</div>
|
||||
|
||||
<script src="/assets/js/createChannelFunctions.js"></script>
|
||||
|
|
|
@ -24,3 +24,5 @@
|
|||
<button class="button--primary" onclick="loginToChannel(event)">Authenticate</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script src="/assets/js/loginFunctions.js"></script>
|
||||
|
|
Loading…
Reference in a new issue