diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 717e9bc..f187c7e 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -6,6 +6,7 @@ import ApiSelector from '../api-selector';
import UserMenu from '../user-menu';
import VersionSelector from '../version-selector';
import LookupContainer from '../lookup-container';
+import Share from '../share';
import Submit from '../submit';
const Header = () =>
@@ -14,6 +15,7 @@ const Header = () =>
+
diff --git a/src/components/share/index.jsx b/src/components/share/index.jsx
new file mode 100644
index 0000000..3a34682
--- /dev/null
+++ b/src/components/share/index.jsx
@@ -0,0 +1,57 @@
+import React, { useState } from 'react';
+import { connect } from 'react-redux';
+
+import './style.css';
+
+const Share = ( { api, version, method, url, pathLabeled, pathValues, queryParams } ) => {
+ const [ buttonText, setButtonText ] = useState( 'Share' );
+
+ // The API console has two methods, 1. Directly type in the URL, 2. Use the form to build the URL.
+ // I'm calling 2 the "madlibs" method, because it's like filling in the blanks of a story.
+ // This function constructs the madlibs path if we can't use the direct request.url.
+ const constructMadlibsPath = () => {
+ let path = pathLabeled;
+ Object.keys( pathValues ).forEach( ( key ) => {
+ path = path.replace( key, encodeURIComponent( pathValues[ key ] ) );
+ console.log( key, pathValues[ key ], path );
+ } );
+ if ( queryParams ) {
+ const queryParamsString = new URLSearchParams( queryParams ).toString();
+ path += `?${ queryParamsString }`;
+ }
+ return path;
+ };
+
+ const buildShareableLink = () => {
+ const finalPath = url || constructMadlibsPath();
+ const baseUrl = window.location.origin;
+ const queryParams = new URLSearchParams( { api, version, method, url: finalPath } ).toString();
+ const shareableUrl = `${ baseUrl }?${ queryParams }`;
+
+ navigator.clipboard
+ .writeText( shareableUrl )
+ .then( () => {
+ setButtonText( 'Copied!' );
+ setTimeout( () => setButtonText( 'Share' ), 2000 );
+ } )
+ .catch( ( err ) => console.error( 'Error copying URL to clipboard', err ) ); // Error handling
+ };
+
+ return (
+
+ );
+};
+
+const mapStateToProps = ( state ) => ( {
+ api: state.ui.api,
+ version: state.ui.version,
+ method: state.request.method,
+ url: state.request.url,
+ pathValues: state.request?.pathValues,
+ queryParams: state.request?.queryParams,
+ pathLabeled: state.request?.endpoint?.pathLabeled,
+} );
+
+export default connect( mapStateToProps )( Share );
diff --git a/src/components/share/style.css b/src/components/share/style.css
new file mode 100644
index 0000000..a3819ae
--- /dev/null
+++ b/src/components/share/style.css
@@ -0,0 +1,16 @@
+#share-button {
+ cursor: pointer;
+ min-width: 44px;
+ background-color: #fff;
+ border: 0;
+ color: rgb(133, 192, 224);
+ transition: background-color 0.2s ease, color 0.2s ease;
+}
+#share-button:hover, #share-button:focus {
+ background-color: rgb(133, 192, 224);
+ color: #fff;
+}
+#share-button:active {
+ background-color: rgb(103, 162, 194);
+ color: #fff;
+}
diff --git a/src/state/index.js b/src/state/index.js
index b95b768..fa4a5dd 100644
--- a/src/state/index.js
+++ b/src/state/index.js
@@ -4,6 +4,7 @@ import thunk from 'redux-thunk';
import reducer from './reducer';
import { boot } from './security/actions';
import { loadInitialState, persistState } from '../lib/redux/cache';
+import initStateFromUrl from './init-state-from-url';
const store = createStore(
reducer,
@@ -12,5 +13,6 @@ const store = createStore(
);
persistState( store, reducer );
store.dispatch( boot() );
+initStateFromUrl( store );
export default store;
diff --git a/src/state/init-state-from-url.js b/src/state/init-state-from-url.js
new file mode 100644
index 0000000..a294bcc
--- /dev/null
+++ b/src/state/init-state-from-url.js
@@ -0,0 +1,23 @@
+import { selectApi, selectVersion } from './ui/actions';
+import { updateMethod, updateUrl } from './request/actions';
+
+function initStateFromUrl( store ) {
+ const requestUrl = new URL( window.location );
+ const api = requestUrl.searchParams.get( 'api' );
+ const version = requestUrl.searchParams.get( 'version' );
+ const method = requestUrl.searchParams.get( 'method' );
+ const url = requestUrl.searchParams.get( 'url' );
+ if ( api ) {
+ store.dispatch( selectApi( api ) );
+ }
+ if ( version ) {
+ store.dispatch( selectVersion( version ) );
+ }
+ if ( method ) {
+ store.dispatch( updateMethod( method ) );
+ }
+ if ( url ) {
+ store.dispatch( updateUrl( url ) );
+ }
+}
+export default initStateFromUrl;