diff --git a/front/src/assets/integrations/cover/ewelink_logo.png b/front/src/assets/integrations/cover/ewelink_logo.png
new file mode 100644
index 0000000000..15c5376474
Binary files /dev/null and b/front/src/assets/integrations/cover/ewelink_logo.png differ
diff --git a/front/src/components/app.jsx b/front/src/components/app.jsx
index 73d834c571..392a85376b 100644
--- a/front/src/components/app.jsx
+++ b/front/src/components/app.jsx
@@ -129,6 +129,7 @@ import EweLinkPage from '../routes/integration/all/ewelink/device-page';
import EweLinkEditPage from '../routes/integration/all/ewelink/edit-page';
import EweLinkDiscoverPage from '../routes/integration/all/ewelink/discover-page';
import EweLinkSetupPage from '../routes/integration/all/ewelink/setup-page';
+import EweLinkSetupLoginPage from '../routes/integration/all/ewelink/setup-page/login';
// OpenAI integration
import OpenAIPage from '../routes/integration/all/openai/index';
@@ -271,6 +272,7 @@ const AppRouter = connect(
+
diff --git a/front/src/components/header/index.jsx b/front/src/components/header/index.jsx
index 7203c8aefc..188c744441 100644
--- a/front/src/components/header/index.jsx
+++ b/front/src/components/header/index.jsx
@@ -22,7 +22,8 @@ const PAGES_WITHOUT_HEADER = [
'/confirm-email',
'/dashboard/integration/device/google-home/authorize',
'/dashboard/integration/device/alexa/authorize',
- '/locked'
+ '/locked',
+ '/dashboard/integration/device/ewelink/setup/login'
];
const Header = ({ ...props }) => {
diff --git a/front/src/config/demo.js b/front/src/config/demo.js
index 90399ebb1e..cddd840338 100644
--- a/front/src/config/demo.js
+++ b/front/src/config/demo.js
@@ -3132,6 +3132,21 @@ const data = {
]
}
],
+ 'get /api/v1/service/ewelink/status': {
+ configured: true,
+ connected: true
+ },
+ 'get /api/v1/service/ewelink/config': {
+ application_id: 'ewelink_APPID',
+ application_secret: 'ewelink_APP_SECRET',
+ application_region: 'eu'
+ },
+ 'post /api/v1/service/ewelink/config': {
+ application_id: 'ewelink_APPID',
+ application_secret: 'ewelink_APP_SECRET',
+ application_region: 'eu'
+ },
+ 'post /api/v1/service/ewelink/token': {},
'get /api/v1/service/tp-link': {
id: 'c9fe2705-35dc-417b-b6fc-c4bbb9c69886',
pod_id: null,
diff --git a/front/src/config/i18n/en.json b/front/src/config/i18n/en.json
index dd82e2472f..3184a0c7b6 100644
--- a/front/src/config/i18n/en.json
+++ b/front/src/config/i18n/en.json
@@ -14,6 +14,8 @@
"degreeValue": "{{value}}°",
"workInProgress": "Work in progress...",
"save": "Save",
+ "edit": "Edit",
+ "cancel": "Cancel",
"celsius": "C",
"fahrenheit": "F",
"metersPerSec": "m/s",
@@ -1430,15 +1432,27 @@
"setup": {
"title": "eWeLink configuration",
"eweLinkDescription": "You can connect Gladys to your eWeLink cloud account to command the associated devices.",
- "userLabel": "Username",
- "userPlaceholder": "Enter eWeLink username",
- "passwordLabel": "Password",
- "passwordPlaceholder": "Enter eWeLink password",
- "saveLabel": "Save configuration",
- "error": "An error occured while saving configuration.",
- "connecting": "Configuration saved. Now connecting to your eWeLink cloud account...",
- "connected": "Connected to the eWeLink cloud account with success !",
- "connectionError": "Error while connecting, please check your configuration."
+ "applicationSetupLabel": "eWeLink application setup",
+ "applicationIdLabel": "Application Identifier (APPID)",
+ "applicationIdPlaceholder": "Enter APPID value",
+ "applicationSecretLabel": "Application Secret (APP SECRET)",
+ "applicationSecretPlaceholder": "Enter APP SECRET value",
+ "applicationRegionLabel": "Region",
+ "userConnectedLabel": "Connected",
+ "userNotConnectedLabel": "No user connected",
+ "connectLabel": "Connect",
+ "disconnectLabel": "Disconnect",
+ "loadStatusError": "An error occured while fetching eWeLink integration status. Gladys may be not reachable.",
+ "saveConfigError": "Unable to save eWeLink application configuration. Gladys may be not reachable.",
+ "loginRedirectError": "An error occured while connecting to eWeLink, please contact Gladys community.",
+ "exchangeTokenError": "An error occured while connecting to exchanging eWeLink user token, please contact Gladys community.",
+ "exchangeTokenSuccess": "Authentication succeed, current tab can be closed.",
+ "regions": {
+ "cn": "Mainland China",
+ "as": "Asia",
+ "us": "Americas",
+ "eu": "Europe"
+ }
},
"error": {
"defaultError": "There was an error saving the device.",
diff --git a/front/src/config/i18n/fr.json b/front/src/config/i18n/fr.json
index da7fb53ef8..ee89851f5b 100644
--- a/front/src/config/i18n/fr.json
+++ b/front/src/config/i18n/fr.json
@@ -14,6 +14,8 @@
"degreeValue": "{{value}}°",
"workInProgress": "Travail en cours...",
"save": "Enregistrer",
+ "edit": "Modifier",
+ "cancel": "Annuler",
"celsius": "C",
"fahrenheit": "F",
"metersPerSec": "m/s",
@@ -1432,15 +1434,27 @@
"setup": {
"title": "Configuration eWeLink",
"eweLinkDescription": "Vous pouvez connecter Gladys à votre compte cloud eWeLink pour commander les appareils associés.",
- "userLabel": "Nom d'utilisateur",
- "userPlaceholder": "Entrez le nom d'utilisateur eWeLink",
- "passwordLabel": "Mot de passe",
- "passwordPlaceholder": "Entrez le mot de passe utilisateur eWeLink",
- "saveLabel": "Enregistrer la configuration",
- "error": "Une erreur s'est produite lors de la sauvegarde de la configuration.",
- "connecting": "Configuration sauvegardée. Connexion à votre compte cloud eWeLink...",
- "connected": "Connexion réussie au compte cloud eWeLink !",
- "connectionError": "Erreur lors de la connexion, veuillez vérifier votre configuration."
+ "applicationSetupLabel": "Configurationde l'application eWeLink",
+ "applicationIdLabel": "Identifiant de l'application (APPID)",
+ "applicationIdPlaceholder": "Entrez la valeur de APPID",
+ "applicationSecretLabel": "Secret de l'application (APP SECRET)",
+ "applicationSecretPlaceholder": "Entrez la valeur de APP SECRET",
+ "applicationRegionLabel": "Region",
+ "userConnectedLabel": "Connecté",
+ "userNotConnectedLabel": "Aucun utilisateur connecté",
+ "connectLabel": "Connexion",
+ "disconnectLabel": "Déconnexion",
+ "loadStatusError": "Impossible de remonter les informations sur l'état de l'intégration eWeLink. Gladys ne semble pas joignable.",
+ "saveConfigError": "Impossible d'enregistrer la configuration de l'application eWeLink. Gladys ne semble pas joignable.",
+ "loginRedirectError": "Une erreur est survenue lors de la connexion à eWeLink, merci de contacter la communauté.",
+ "exchangeTokenError": "Une erreur est survenue lors de la génération du jeton utilisateur eWeLink, merci de contacter la communauté.",
+ "exchangeTokenSuccess": "L'authentification est un succès, cette page peut être fermée.",
+ "regions": {
+ "cn": "Chine",
+ "as": "Asie",
+ "us": "Ameriques",
+ "eu": "Europe"
+ }
},
"error": {
"defaultError": "Une erreur s'est produite lors de l'enregistrement de l'appareil.",
diff --git a/front/src/routes/integration/all/ewelink/setup-page/ApplicationSetup.jsx b/front/src/routes/integration/all/ewelink/setup-page/ApplicationSetup.jsx
new file mode 100644
index 0000000000..6ab6aeb749
--- /dev/null
+++ b/front/src/routes/integration/all/ewelink/setup-page/ApplicationSetup.jsx
@@ -0,0 +1,192 @@
+import { Component } from 'preact';
+import { Localizer, Text } from 'preact-i18n';
+import cx from 'classnames';
+
+import { REGIONS } from './constants';
+
+class ApplicationSetup extends Component {
+ showPasswordTimer = null;
+
+ updateApplicationId = event => {
+ const { value: applicationId } = event.target;
+ this.setState({ applicationId });
+ };
+
+ updateApplicationSecret = event => {
+ const { value: applicationSecret } = event.target;
+ this.setState({ applicationSecret });
+ };
+
+ updateApplicationRegion = event => {
+ const { value: applicationRegion } = event.target;
+ this.setState({ applicationRegion });
+ };
+
+ saveConfiguration = async event => {
+ event.preventDefault();
+ const { applicationId, applicationSecret, applicationRegion } = this.state;
+ const configuration = { applicationId, applicationSecret, applicationRegion };
+ this.props.saveConfiguration(configuration);
+ };
+
+ resetConfiguration = event => {
+ event.preventDefault();
+ const { ewelinkConfig = {} } = this.props;
+ const { applicationId = '', applicationSecret = '', applicationRegion } = ewelinkConfig;
+ this.setState({ applicationId, applicationSecret, applicationRegion });
+ this.props.resetConfiguration();
+ };
+
+ togglePassword = () => {
+ const { showPassword } = this.state;
+
+ if (this.showPasswordTimer) {
+ clearTimeout(this.showPasswordTimer);
+ this.showPasswordTimer = null;
+ }
+
+ this.setState({ showPassword: !showPassword });
+
+ if (!showPassword) {
+ this.showPasswordTimer = setTimeout(() => this.setState({ showPassword: false }), 5000);
+ }
+ };
+
+ constructor(props) {
+ super(props);
+
+ const { ewelinkConfig = {} } = props;
+ const { applicationId = '', applicationSecret = '', applicationRegion } = ewelinkConfig;
+ this.state = {
+ applicationId,
+ applicationSecret,
+ applicationRegion
+ };
+ }
+
+ componentWillUnmount() {
+ if (this.showPasswordTimer) {
+ clearTimeout(this.showPasswordTimer);
+ this.showPasswordTimer = null;
+ }
+ }
+
+ componentWillReceiveProps(nextProps) {
+ const { ewelinkConfig = {} } = nextProps;
+ const { applicationId = '', applicationSecret = '', applicationRegion } = ewelinkConfig;
+ const {
+ applicationId: currentApplicationId,
+ applicationSecret: currentApplicationSecret,
+ applicationRegion: currentApplicationRegion
+ } = this.state;
+
+ if (
+ applicationId !== currentApplicationId ||
+ applicationSecret !== currentApplicationSecret ||
+ applicationRegion !== currentApplicationRegion
+ ) {
+ this.setState({ applicationId, applicationSecret, applicationRegion });
+ }
+ }
+
+ render({ disabled }, { applicationId, applicationSecret, applicationRegion, showPassword }) {
+ const saveDisabled = applicationId === '' || applicationSecret === '' || !applicationRegion;
+ return (
+
+ );
+ }
+}
+
+export default ApplicationSetup;
diff --git a/front/src/routes/integration/all/ewelink/setup-page/SetupSummary.jsx b/front/src/routes/integration/all/ewelink/setup-page/SetupSummary.jsx
new file mode 100644
index 0000000000..3efc2d4337
--- /dev/null
+++ b/front/src/routes/integration/all/ewelink/setup-page/SetupSummary.jsx
@@ -0,0 +1,75 @@
+import { Fragment } from 'preact';
+import { Text } from 'preact-i18n';
+import cx from 'classnames';
+
+const SetupSummary = ({ ewelinkStatus = {}, enableEditionMode, disabled, connectUser, disconnectUser }) => {
+ const { configured, connected } = ewelinkStatus;
+
+ return (
+
+
+
+
+
+
+ {connected && (
+
+
+
+
+ )}
+ {!connected && (
+
+
+
+ {configured && (
+
+ )}
+
+
+ )}
+
+
+ );
+};
+
+export default SetupSummary;
diff --git a/front/src/routes/integration/all/ewelink/setup-page/SetupTab.jsx b/front/src/routes/integration/all/ewelink/setup-page/SetupTab.jsx
index 9f0b2f4546..ebb641fa73 100644
--- a/front/src/routes/integration/all/ewelink/setup-page/SetupTab.jsx
+++ b/front/src/routes/integration/all/ewelink/setup-page/SetupTab.jsx
@@ -1,93 +1,115 @@
-import { Text, Localizer, MarkupText } from 'preact-i18n';
+import { Component } from 'preact';
+import { Text } from 'preact-i18n';
import cx from 'classnames';
import { RequestStatus } from '../../../../../utils/consts';
-const SetupTab = ({ children, ...props }) => {
- return (
-
-
-
-
-
-
-
-
-
- {props.connectEweLinkStatus === RequestStatus.Error && !props.eweLinkConnectionError && (
-
-
-
- )}
- {props.connectEweLinkStatus === RequestStatus.Success && !props.eweLinkConnected && (
-
-
-
- )}
- {props.eweLinkConnected && (
-
-
-
- )}
- {props.eweLinkConnectionError && (
-
-
-
- )}
+import ApplicationSetup from './ApplicationSetup';
+import SetupSummary from './SetupSummary';
+
+class SetupTab extends Component {
+ enableEditionMode = () => {
+ this.setState({ editionMode: true });
+ };
+
+ resetConfiguration = () => {
+ const { ewelinkStatus = {} } = this.props;
+ const { configured = false } = ewelinkStatus;
+ this.setState({
+ editionMode: !configured
+ });
+ };
+
+ constructor(props) {
+ super(props);
-
+ if (ewelinkStatus.configured && this.state.editionMode) {
+ this.setState({ editionMode: false });
+ }
+ }
+
+ render(
+ {
+ ewelinkStatus,
+ loadEwelinkStatus = RequestStatus.Getting,
+ ewelinkConfig,
+ loadEwelinkConfig = RequestStatus.Getting,
+ saveEwelinkConfig,
+ saveConfiguration,
+ connectUser,
+ loadConnectUser,
+ disconnectUser,
+ loadDisconnectUser
+ },
+ { editionMode }
+ ) {
+ const formDisabled =
+ saveEwelinkConfig === RequestStatus.Getting ||
+ loadConnectUser === RequestStatus.Getting ||
+ loadDisconnectUser === RequestStatus.Getting;
+
+ return (
+
+
+
+
+
+
+
+
+
+ {loadEwelinkStatus === RequestStatus.Error && (
+
+
+
+ )}
+ {saveEwelinkConfig === RequestStatus.Error && (
+
+
+
+ )}
+ {editionMode && (
+
+ )}
+ {!editionMode && (
+
+ )}
+
-
- );
-};
+ );
+ }
+}
export default SetupTab;
diff --git a/front/src/routes/integration/all/ewelink/setup-page/constants.js b/front/src/routes/integration/all/ewelink/setup-page/constants.js
new file mode 100644
index 0000000000..2a7afd0984
--- /dev/null
+++ b/front/src/routes/integration/all/ewelink/setup-page/constants.js
@@ -0,0 +1,4 @@
+const REGIONS = ['eu', 'us', 'as', 'cn'];
+const DEFAULT_REGION = REGIONS[0];
+
+export { REGIONS, DEFAULT_REGION };
diff --git a/front/src/routes/integration/all/ewelink/setup-page/index.js b/front/src/routes/integration/all/ewelink/setup-page/index.js
index 483106a333..23ddf18ba3 100644
--- a/front/src/routes/integration/all/ewelink/setup-page/index.js
+++ b/front/src/routes/integration/all/ewelink/setup-page/index.js
@@ -1,39 +1,170 @@
import { Component } from 'preact';
import { connect } from 'unistore/preact';
-import actions from '../actions';
+
import EweLinkPage from '../EweLinkPage';
import SetupTab from './SetupTab';
+import { DEFAULT_REGION } from './constants';
+
import { WEBSOCKET_MESSAGE_TYPES } from '../../../../../../../server/utils/constants';
+import { RequestStatus } from '../../../../../utils/consts';
class EweLinkSetupPage extends Component {
- componentWillMount() {
- this.props.getIntegrationByName('ewelink');
- this.props.loadProps();
- this.props.session.dispatcher.addListener(
- WEBSOCKET_MESSAGE_TYPES.EWELINK.CONNECTED,
- this.props.displayConnectedMessage
- );
- this.props.session.dispatcher.addListener(WEBSOCKET_MESSAGE_TYPES.EWELINK.ERROR, this.props.displayEweLinkError);
+ loadEwelinkStatus = async () => {
+ this.setState({
+ loadEwelinkStatus: RequestStatus.Getting
+ });
+ try {
+ const { configured, connected } = await this.props.httpClient.get('/api/v1/service/ewelink/status');
+ const ewelinkStatus = { configured, connected };
+ this.setState({
+ ewelinkStatus,
+ loadEwelinkStatus: RequestStatus.Success
+ });
+ } catch (e) {
+ console.error('eWeLink error loading status', e);
+ this.setState({
+ loadEwelinkStatus: RequestStatus.Error
+ });
+ }
+ };
+
+ loadEwelinkConfig = async () => {
+ this.setState({
+ loadEwelinkConfig: RequestStatus.Getting
+ });
+ try {
+ const {
+ application_id: applicationId,
+ application_secret: applicationSecret,
+ application_region: applicationRegion = DEFAULT_REGION
+ } = await this.props.httpClient.get('/api/v1/service/ewelink/config');
+ this.setState({
+ ewelinkConfig: { applicationId, applicationSecret, applicationRegion },
+ loadEwelinkConfig: RequestStatus.Success
+ });
+ } catch (e) {
+ console.error('eWeLink error loading config', e);
+ this.setState({
+ loadEwelinkConfig: RequestStatus.Error
+ });
+ }
+ };
+
+ saveEwelinkConfig = async config => {
+ this.setState({
+ saveEwelinkConfig: RequestStatus.Getting
+ });
+ try {
+ const { applicationId, applicationSecret, applicationRegion } = config;
+ const savedConfig = await this.props.httpClient.post('/api/v1/service/ewelink/config', {
+ application_id: applicationId,
+ application_secret: applicationSecret,
+ application_region: applicationRegion
+ });
+ const ewelinkConfig = {
+ applicationId: savedConfig.application_id,
+ applicationSecret: savedConfig.application_secret,
+ applicationRegion: savedConfig.application_secret
+ };
+ this.setState({
+ ewelinkConfig,
+ saveEwelinkConfig: RequestStatus.Success
+ });
+ } catch (e) {
+ console.error('eWeLink error saving config', e);
+ this.setState({
+ saveEwelinkConfig: RequestStatus.Error
+ });
+ }
+ };
+
+ connectUser = async () => {
+ this.setState({ loadConnectUser: RequestStatus.Getting });
+
+ const { origin, pathname } = window.location;
+ try {
+ const { loginUrl } = await this.props.httpClient.get('/api/v1/service/ewelink/loginUrl', {
+ redirect_url: `${origin}${pathname}/login`
+ });
+ const loginPopup = window.open(loginUrl, 'ewelinkLogin');
+ this.setState({ loadConnectUser: RequestStatus.Success, loginPopup });
+ } catch (e) {
+ console.error(e);
+ this.setState({ loadConnectUser: RequestStatus.Error });
+ }
+ };
+
+ disconnectUser = async () => {
+ this.setState({ loadDisconnectUser: RequestStatus.Getting });
+
+ try {
+ await this.props.httpClient.delete('/api/v1/service/ewelink/token');
+ this.setState({ loadDisconnectUser: RequestStatus.Success });
+ } catch (e) {
+ console.error(e);
+ this.setState({ loadDisconnectUser: RequestStatus.Error });
+ }
+ };
+
+ updateStatus = payload => {
+ const { configured, connected } = payload;
+ const ewelinkStatus = { configured, connected };
+
+ const { loginPopup, ewelinkStatus: currentStatus = {} } = this.state;
+ if (!currentStatus.connected && connected && loginPopup && !loginPopup.closed) {
+ loginPopup.close();
+ }
+
+ this.setState({ ewelinkStatus });
+ };
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ loadEwelinkStatus: RequestStatus.Getting
+ };
+ }
+
+ componentDidMount() {
+ this.props.session.dispatcher.addListener(WEBSOCKET_MESSAGE_TYPES.EWELINK.STATUS, this.updateStatus);
+ this.loadEwelinkStatus();
+ this.loadEwelinkConfig();
}
componentWillUnmount() {
- this.props.session.dispatcher.removeListener(
- WEBSOCKET_MESSAGE_TYPES.EWELINK.CONNECTED,
- this.props.displayConnectedMessage
- );
- this.props.session.dispatcher.removeListener(WEBSOCKET_MESSAGE_TYPES.EWELINK.ERROR, this.props.displayEweLinkError);
+ this.props.session.dispatcher.removeListener(WEBSOCKET_MESSAGE_TYPES.EWELINK.STATUS, this.updateStatus);
}
- render(props, {}) {
+ render(
+ {},
+ {
+ loadEwelinkStatus,
+ ewelinkStatus,
+ loadEwelinkConfig,
+ ewelinkConfig,
+ saveEwelinkConfig,
+ loadDisconnectUser,
+ loadConnectUser
+ }
+ ) {
return (
-
+
);
}
}
-export default connect(
- 'user,session,eweLinkUsername,eweLinkPassword,connectEweLinkStatus,eweLinkConnected,eweLinkConnectionError',
- actions
-)(EweLinkSetupPage);
+export default connect('user,session,httpClient')(EweLinkSetupPage);
diff --git a/front/src/routes/integration/all/ewelink/setup-page/login/ErrorPage.jsx b/front/src/routes/integration/all/ewelink/setup-page/login/ErrorPage.jsx
new file mode 100644
index 0000000000..97698bc65a
--- /dev/null
+++ b/front/src/routes/integration/all/ewelink/setup-page/login/ErrorPage.jsx
@@ -0,0 +1,10 @@
+const ErrorPage = ({ children }) => (
+
+);
+
+export default ErrorPage;
diff --git a/front/src/routes/integration/all/ewelink/setup-page/login/ExchangeTokenPage.jsx b/front/src/routes/integration/all/ewelink/setup-page/login/ExchangeTokenPage.jsx
new file mode 100644
index 0000000000..20ebf4aa91
--- /dev/null
+++ b/front/src/routes/integration/all/ewelink/setup-page/login/ExchangeTokenPage.jsx
@@ -0,0 +1,75 @@
+import { Component } from 'preact';
+import cx from 'classnames';
+
+import { RequestStatus } from '../../../../../../utils/consts';
+import { Text } from 'preact-i18n';
+import ErrorPage from './ErrorPage';
+
+class ExchangeTokenPage extends Component {
+ exchangeToken = async () => {
+ this.setState({
+ exchangeTokenStatus: RequestStatus.Getting,
+ exchangeTokenError: null
+ });
+
+ try {
+ const { code, region, redirectUrl, state } = this.props;
+
+ await this.props.httpClient.post('/api/v1/service/ewelink/token', {
+ code,
+ region,
+ redirect_url: redirectUrl,
+ state
+ });
+ this.setState({
+ exchangeTokenStatus: RequestStatus.Success
+ });
+ } catch (e) {
+ console.error(e);
+ console.error(e.response);
+ this.setState({
+ exchangeTokenStatus: RequestStatus.Error,
+ exchangeTokenError: e
+ });
+ }
+ };
+
+ componentDidMount() {
+ this.exchangeToken();
+ }
+
+ render({}, { exchangeTokenStatus = RequestStatus.Getting, exchangeTokenError }) {
+ const { response = {} } = exchangeTokenError || {};
+ const { data = {} } = response;
+ const { message } = data;
+
+ return (
+
+
+
+ {exchangeTokenStatus === RequestStatus.Error && (
+
+
+
+
+ {message ? message : exchangeTokenError}
+
+
+ )}
+ {exchangeTokenStatus === RequestStatus.Success && (
+
+
+
+ )}
+
+
+ );
+ }
+}
+
+export default ExchangeTokenPage;
diff --git a/front/src/routes/integration/all/ewelink/setup-page/login/index.js b/front/src/routes/integration/all/ewelink/setup-page/login/index.js
new file mode 100644
index 0000000000..98d9379c82
--- /dev/null
+++ b/front/src/routes/integration/all/ewelink/setup-page/login/index.js
@@ -0,0 +1,109 @@
+import { Component } from 'preact';
+import { connect } from 'unistore/preact';
+import { Localizer, Text } from 'preact-i18n';
+
+import { RequestStatus } from '../../../../../../utils/consts';
+import ErrorPage from './ErrorPage';
+import ExchangeTokenPage from './ExchangeTokenPage';
+
+class EweLinkSetupLoginPage extends Component {
+ exchangeToken = async config => {
+ this.setState({
+ saveEwelinkConfig: RequestStatus.Getting
+ });
+ try {
+ const { applicationId, applicationSecret, applicationRegion } = config;
+ const savedConfig = await this.props.httpClient.post('/api/v1/service/ewelink/token', {
+ application_id: applicationId,
+ application_secret: applicationSecret,
+ application_region: applicationRegion
+ });
+ const ewelinkConfig = {
+ applicationId: savedConfig.application_id,
+ applicationSecret: savedConfig.application_secret,
+ applicationRegion: savedConfig.application_secret
+ };
+ this.setState({
+ ewelinkConfig,
+ saveEwelinkConfig: RequestStatus.Success
+ });
+ } catch (e) {
+ console.error('eWeLink error saving config', e);
+ this.setState({
+ saveEwelinkConfig: RequestStatus.Error
+ });
+ }
+ };
+
+ constructor(props) {
+ super(props);
+
+ const { search: queryString, origin, pathname } = window.location;
+ const queryParams = new URLSearchParams(queryString);
+
+ // Map query params to JSON Object
+ const params = {};
+ for (const [key, value] of queryParams.entries()) {
+ params[key] = value;
+ }
+
+ this.state = {
+ params,
+ redirectUrl: `${origin}${pathname}`
+ };
+ }
+
+ render({ httpClient }, { params, redirectUrl }) {
+ const { code, region, state } = params;
+ const success = code && region && state;
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ />
+
+
+
+
+ {success && (
+
+ )}
+ {!success && (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+export default connect('user,session,httpClient')(EweLinkSetupLoginPage);
diff --git a/server/utils/constants.js b/server/utils/constants.js
index 4f4d4a8d70..e7b8f71294 100644
--- a/server/utils/constants.js
+++ b/server/utils/constants.js
@@ -917,7 +917,7 @@ const WEBSOCKET_MESSAGE_TYPES = {
DISCOVER: 'bluetooth.discover',
},
EWELINK: {
- CONNECTED: 'ewelink.connected',
+ STATUS: 'ewelink.status',
NEW_DEVICE: 'ewelink.new-device',
ERROR: 'ewelink.error',
},