diff --git a/src/components/Developers/components/DeveloperSignup/DeveloperSignup.jsx b/src/components/Developers/components/DeveloperSignup/DeveloperSignup.jsx
index 1c4dba96..c4d13bcc 100644
--- a/src/components/Developers/components/DeveloperSignup/DeveloperSignup.jsx
+++ b/src/components/Developers/components/DeveloperSignup/DeveloperSignup.jsx
@@ -1,4 +1,4 @@
-import React, { Component } from 'react';
+import React, { useState } from 'react';
import { Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import _ from 'lodash';
@@ -12,14 +12,11 @@ import ChrisStore from '../../../../store/ChrisStore';
import FormInput from '../../../FormInput';
import isTouchDevice from './isTouchDevice';
-export class DeveloperSignup extends Component {
- constructor(props) {
- super(props);
- this.handleSubmit = this.handleSubmit.bind(this);
- this.handleChange = this.handleChange.bind(this);
+const DeveloperSignup = (props) => {
const queryParams = new URLSearchParams(window.location.search);
const emailVal = queryParams.get('email');
- this.state = {
+
+ const [state, setState] = useState({
loading: false,
error: {
message: String(),
@@ -29,20 +26,72 @@ export class DeveloperSignup extends Component {
email: emailVal,
password: String(),
passwordConfirm: String(),
- };
+ });
+
+ const { username, email, password, passwordConfirm, error, loading, toDashboard, } = state;
+ const { store } = props;
+
+const handleChange = (value, name) => {
+ setState({ [name]: value });
}
- handleChange(value, name) {
- this.setState({ [name]: value });
+ const handleStoreLogin = async () => {
+ const storeURL = process.env.REACT_APP_STORE_URL;
+ const usersURL = `${storeURL}users/`;
+ const authURL = `${storeURL}auth-token/`;
+ let authToken;
+
+ try {
+ await StoreClient.createUser(usersURL, username, password, email);
+ } catch (e) {
+ if (_.has(e, 'response')) {
+ if (_.has(e, 'response.data.username')) {
+ setState({
+ loading: false,
+ error: {
+ message: 'This username is already registered.',
+ controls: ['username'],
+ },
+ });
+ } else {
+ setState({
+ loading: false,
+ error: {
+ message: 'This email is already registered.',
+ controls: ['email'],
+ },
+ });
+ }
+ } else {
+ setState({
+ loading: false,
+ });
+ }
+ return e;
+ }
+
+ try {
+ authToken = await StoreClient.getAuthToken(authURL, username, password);
+ } catch (e) {
+ return Promise.reject(e);
+ }
+
+ return setState(
+ {
+ toDashboard: true,
+ },
+ () => {
+ store.set('authToken')(authToken);
+ return authToken;
+ }
+ );
}
- handleSubmit(event) {
+const handleSubmit = (event) => {
event.persist();
- const { username, email, password, passwordConfirm } = this.state;
- const { store } = this.props;
if (!username) {
- return this.setState({
+ return setState({
error: {
message: 'Username is required',
controls: ['username'],
@@ -51,7 +100,7 @@ export class DeveloperSignup extends Component {
}
if (!email || !validate(email)) {
- return this.setState({
+ return setState({
error: {
message: 'A valid Email is required',
controls: ['email'],
@@ -60,7 +109,7 @@ export class DeveloperSignup extends Component {
}
if (!password) {
- return this.setState({
+ return setState({
error: {
message: 'Password is required',
controls: ['password'],
@@ -69,7 +118,7 @@ export class DeveloperSignup extends Component {
}
if (!passwordConfirm) {
- return this.setState({
+ return setState({
error: {
message: 'Confirmation is required',
controls: ['confirmation'],
@@ -78,7 +127,7 @@ export class DeveloperSignup extends Component {
}
if (password !== passwordConfirm) {
- return this.setState({
+ return setState({
error: {
message: 'Password and confirmation do not match',
controls: ['password', 'confirmation'],
@@ -86,7 +135,7 @@ export class DeveloperSignup extends Component {
});
}
- this.setState(
+ setState(
{
loading: true,
error: {
@@ -97,80 +146,14 @@ export class DeveloperSignup extends Component {
() => store.set('userName')(username)
);
- return this.handleStoreLogin();
+ return handleStoreLogin();
}
- async handleStoreLogin() {
- const { username, email, password } = this.state;
- const { store } = this.props;
- const storeURL = process.env.REACT_APP_STORE_URL;
- const usersURL = `${storeURL}users/`;
- const authURL = `${storeURL}auth-token/`;
- let authToken;
-
- try {
- await StoreClient.createUser(usersURL, username, password, email);
- } catch (e) {
- if (_.has(e, 'response')) {
- if (_.has(e, 'response.data.username')) {
- this.setState({
- loading: false,
- error: {
- message: 'This username is already registered.',
- controls: ['username'],
- },
- });
- } else {
- this.setState({
- loading: false,
- error: {
- message: 'This email is already registered.',
- controls: ['email'],
- },
- });
- }
- } else {
- this.setState({
- loading: false,
- });
- }
- return e;
- }
-
- try {
- authToken = await StoreClient.getAuthToken(authURL, username, password);
- } catch (e) {
- return Promise.reject(e);
- }
-
- return this.setState(
- {
- toDashboard: true,
- },
- () => {
- store.set('authToken')(authToken);
- return authToken;
- }
- );
- }
-
- render() {
- const {
- error,
- loading,
- toDashboard,
-
- username,
- email,
- password,
- passwordConfirm,
- } = this.state;
-
if (toDashboard) return ;
const disableControls = loading;
return (
-
);
}
-}
+
export default ChrisStore.withStore(DeveloperSignup);
diff --git a/src/components/Plugin/Plugin.jsx b/src/components/Plugin/Plugin.jsx
index 0a4ddafe..4791298b 100644
--- a/src/components/Plugin/Plugin.jsx
+++ b/src/components/Plugin/Plugin.jsx
@@ -1,4 +1,4 @@
-import React, { Component } from 'react';
+import React, { useEffect, useState } from 'react';
import { Badge, Grid, GridItem, Split, SplitItem, Button } from '@patternfly/react-core';
import { StarIcon } from '@patternfly/react-icons';
import PropTypes from 'prop-types';
@@ -18,161 +18,153 @@ import './Plugin.css';
/**
* View a plugin by plugin ID.
*/
-export class PluginView extends Component {
- constructor(props) {
- super(props);
+const PluginView = (props) => {
+const [state, setState] = useState({
+ pluginData: undefined,
+ star: undefined,
+ loading: true,
+ errors: [],
+})
- this.state = {
- pluginData: undefined,
- star: undefined,
- loading: true,
- errors: [],
- };
+ const { match, store } = props
+ const { loading, pluginData: plugin, errors, star } = state;
const storeURL = process.env.REACT_APP_STORE_URL;
- const auth = { token: props.store.get('authToken') };
- this.client = new Client(storeURL, auth);
- }
-
- /**
- * Fetch a plugin by ID, from URL params.
- * Then fetch other plugins which have the same name as versions.
- * Set stars if user is logged in.
- */
- async componentDidMount() {
- // eslint-disable-next-line react/destructuring-assignment
- const { pluginId } = this.props.match.params;
- try {
- const plugin = await this.fetchPlugin(pluginId);
- const versions = await this.fetchPluginVersions(plugin.data.name);
-
- let star;
- if (this.isLoggedIn())
- star = await this.fetchIsPluginStarred(plugin.data);
-
- this.setState({
- loading: false,
- pluginData: {
- ...plugin.data,
- url: plugin.url,
- versions
- },
- star,
- });
- } catch (error) {
- this.setState((prev) => ({
- loading: false,
- errors: [...prev.errors, error]
- }));
- }
- }
+ const auth = { token: store.get('authToken') };
+ const client = new Client(storeURL, auth);
- showNotifications = (error) => {
- this.setState((prev) => ({
+const showNotifications = (error) => {
+ setState((prev) => ({
errors: [...prev.errors, error]
}));
}
- // eslint-disable-next-line react/destructuring-assignment
- isFavorite = () => this.state.star !== undefined;
+const isFavorite = () => star !== undefined;
- // eslint-disable-next-line react/destructuring-assignment
- isLoggedIn = () => this.props.store ? this.props.store.get('isLoggedIn') : false;
-
- onStarClicked = () => {
- if (this.isLoggedIn()) {
- if (this.isFavorite())
- this.unfavPlugin();
- else
- this.favPlugin();
- }
- else
- this.showNotifications(new Error('Login required to favorite this plugin.'))
- }
-
- favPlugin = async () => {
- const { pluginData } = this.state;
+const isLoggedIn = () => store ? store.get('isLoggedIn') : false;
+const favPlugin = async () => {
+ const { pluginData } = state;
// Early state change for instant visual feedback
pluginData.stars += 1;
- this.setState({ star: {}, pluginData });
+ setState({ star: {}, pluginData });
try {
- const star = await this.client.createPluginStar({ plugin_name: pluginData.name });
- this.setState({ star: star.data });
+ const createdStar = await client.createPluginStar({ plugin_name: pluginData.name });
+ setState({ star: createdStar.data });
} catch (error) {
- this.showNotifications(new HttpApiCallError(error));
+ showNotifications(new HttpApiCallError(error));
pluginData.stars -= 1;
- this.setState({ star: undefined, pluginData });
+ setState({ star: undefined, pluginData });
}
}
- unfavPlugin = async () => {
- const { pluginData, star: previousStarState } = this.state;
+const unfavPlugin = async () => {
+ const { pluginData, star: previousStarState } = state;
// Early state change for instant visual feedback
pluginData.stars -= 1;
- this.setState({ star: undefined, pluginData });
+ setState({ star: undefined, pluginData });
try {
await (
- await this.client.getPluginStar(previousStarState.id)
+ await client.getPluginStar(previousStarState.id)
).delete();
} catch (error) {
pluginData.stars += 1;
- this.setState({ star: previousStarState, pluginData });
- this.showNotifications(new HttpApiCallError(error));
+ setState({ star: previousStarState, pluginData });
+ showNotifications(new HttpApiCallError(error));
}
}
- renderStar = () => {
- let name;
- let className;
-
- if (this.isLoggedIn()) {
- className = this.isFavorite() ? 'plugin-star-favorite' : 'plugin-star';
- name = this.isFavorite() ? 'star' : 'star-o';
- } else {
- className = 'plugin-star-disabled';
- name = 'star-o';
+ const onStarClicked = () => {
+ if (isLoggedIn()) {
+ if (isFavorite())
+ unfavPlugin();
+ else
+ favPlugin();
}
- return ;
+ else
+ showNotifications(new Error('Login required to favorite this plugin.'))
}
+// const renderStar = () => {
+// let name;
+// let className;
+
+// if (isLoggedIn()) {
+// className = isFavorite() ? 'plugin-star-favorite' : 'plugin-star';
+// name = isFavorite() ? 'star' : 'star-o';
+// } else {
+// className = 'plugin-star-disabled';
+// name = 'star-o';
+// }
+// return onStarClicked()} />;
+// }
+
/**
* Fetch a plugin by ID
* @param {string} pluginId
* @returns {Promise} Plugin
*/
- async fetchPlugin(pluginId) {
- // eslint-disable-next-line react/destructuring-assignment
- return this.client.getPlugin(parseInt(pluginId, 10));
- }
+const fetchPlugin = async (pluginId) => client.getPlugin(parseInt(pluginId, 10));
/**
* Fetch all versions of a plugin by name.
* @param {string} name Plugin name
* @returns Promise => void
*/
- async fetchPluginVersions(name) {
- const versions = await this.client.getPlugins({ limit: 10e6, name_exact: name });
- const firstplg = await this.client.getPlugin(parseInt(versions.data[0].id, 10));
+const fetchPluginVersions = async (name) => {
+ const versions = await client.getPlugins({ limit: 10e6, name_exact: name });
+ const firstplg = await client.getPlugin(parseInt(versions.data[0].id, 10));
return [
{ ...versions.data[0], url: firstplg.url },
...versions.data.slice(1)
]
}
- async fetchIsPluginStarred({ name }) {
- const response = await this.client.getPluginStars({ plugin_name: name });
+const fetchIsPluginStarred = async ({ name }) => {
+ const response = await client.getPluginStars({ plugin_name: name });
if (response.data.length > 0)
return response.data[0];
return undefined;
}
- render() {
- const { loading, pluginData: plugin, errors } = this.state;
-
+ /**
+ * Fetch a plugin by ID, from URL params.
+ * Then fetch other plugins which have the same name as versions.
+ * Set stars if user is logged in.
+ */
+useEffect(() => {
+ const { pluginId } = match.params;
+ const fetchData = async() => {
+ try {
+ const fetchedPlugin = await fetchPlugin(pluginId);
+ const versions = await fetchPluginVersions(fetchedPlugin.data.name);
+
+ // eslint-disable-next-line no-shadow
+ let star;
+ if (isLoggedIn())
+ star = await fetchIsPluginStarred(plugin.data);
+
+ setState({
+ loading: false,
+ pluginData: {
+ ...plugin.data,
+ url: plugin.url,
+ versions
+ },
+ star,
+ });
+ } catch (error) {
+ setState((prev) => ({
+ loading: false,
+ errors: [...prev.errors, error]
+ }));
+ }
+}
+fetchData()
+})
if (!loading && !plugin)
return
@@ -202,12 +194,12 @@ export class PluginView extends Component {
{
- !this.isFavorite() ?
-