Explorar el Código

Add copy button to API settings, resolves #142

poeti8 hace 7 años
padre
commit
ec52056925

+ 11 - 0
client/components/Settings/Settings.js

@@ -79,6 +79,7 @@ class Settings extends Component {
       passwordMessage: '',
       passwordError: '',
       useHttps: null,
+      isCopied: false,
       ban: {
         domain: false,
         error: '',
@@ -94,6 +95,7 @@ class Settings extends Component {
     this.handleCheckbox = this.handleCheckbox.bind(this);
     this.deleteDomain = this.deleteDomain.bind(this);
     this.showModal = this.showModal.bind(this);
+    this.onCopy = this.onCopy.bind(this);
     this.closeModal = this.closeModal.bind(this);
     this.changePassword = this.changePassword.bind(this);
   }
@@ -151,6 +153,13 @@ class Settings extends Component {
     );
   }
 
+  onCopy() {
+    this.setState({ isCopied: true });
+    setTimeout(() => {
+      this.setState({ isCopied: false });
+    }, 1500);
+  }
+
   onChangeBanCheckboxes(type) {
     return e => {
       const { checked } = e.target;
@@ -265,6 +274,8 @@ class Settings extends Component {
           loader={this.props.apiLoading}
           generateKey={this.props.generateApiKey}
           apikey={this.props.settings.apikey}
+          isCopied={this.state.isCopied}
+          onCopy={this.onCopy}
         />
         <Modal show={this.state.showModal} close={this.closeModal} handler={this.deleteDomain}>
           Are you sure do you want to delete the domain?

+ 37 - 2
client/components/Settings/SettingsApi.js

@@ -1,7 +1,9 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import styled, { css } from 'styled-components';
+import { CopyToClipboard } from 'react-copy-to-clipboard';
 import Button from '../Button';
+import { fadeIn } from '../../helpers/animations';
 
 const Wrapper = styled.div`
   display: flex;
@@ -10,6 +12,7 @@ const Wrapper = styled.div`
 `;
 
 const ApiKeyWrapper = styled.div`
+  position: relative;
   display: flex;
   align-items: center;
   margin: 16px 0;
@@ -34,8 +37,17 @@ const ApiKeyWrapper = styled.div`
   }
 `;
 
+const KeyWrapper = styled.div`
+  max-width: 100%;
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  margin-bottom: 16px;
+`;
+
 const ApiKey = styled.span`
   max-width: 100%;
+  margin-right: 16px;
   font-size: 18px;
   font-weight: bold;
   border-bottom: 2px dotted #999;
@@ -43,6 +55,10 @@ const ApiKey = styled.span`
   @media only screen and (max-width: 768px) {
     font-size: 14px;
   }
+
+  @media only screen and (max-width: 520px) {
+    margin-bottom: 16px;
+  }
 `;
 
 const Link = styled.a`
@@ -53,7 +69,16 @@ const Link = styled.a`
   }
 `;
 
-const SettingsApi = ({ apikey, generateKey, loader }) => (
+const CopyMessage = styled.p`
+  position: absolute;
+  top: -42px;
+  left: 0;
+  font-size: 14px;
+  color: #689f38;
+  animation: ${fadeIn} 0.3s ease-out;
+`;
+
+const SettingsApi = ({ apikey, generateKey, loader, isCopied, onCopy }) => (
   <Wrapper>
     <h3>API</h3>
     <p>
@@ -62,7 +87,15 @@ const SettingsApi = ({ apikey, generateKey, loader }) => (
       client side of your website.
     </p>
     <ApiKeyWrapper apikey={apikey}>
-      {apikey && <ApiKey>{apikey}</ApiKey>}
+      {isCopied && <CopyMessage>Copied to clipboard.</CopyMessage>}
+      {apikey && (
+        <KeyWrapper>
+          <ApiKey>{apikey}</ApiKey>
+          <CopyToClipboard text={apikey} onCopy={onCopy}>
+            <Button icon="copy">Copy</Button>
+          </CopyToClipboard>
+        </KeyWrapper>
+      )}
       <Button color="purple" icon={loader ? 'loader' : 'zap'} onClick={generateKey}>
         {apikey ? 'Regenerate' : 'Generate'} key
       </Button>
@@ -76,7 +109,9 @@ const SettingsApi = ({ apikey, generateKey, loader }) => (
 SettingsApi.propTypes = {
   apikey: PropTypes.string.isRequired,
   loader: PropTypes.bool.isRequired,
+  isCopied: PropTypes.bool.isRequired,
   generateKey: PropTypes.func.isRequired,
+  onCopy: PropTypes.func.isRequired,
 };
 
 export default SettingsApi;