diff --git a/src/components/basket/FormatShoppingItem.js b/src/components/basket/FormatShoppingItem.js
new file mode 100644
index 0000000000000000000000000000000000000000..5adfc7cd85a0e34ce0d051c5613d17da5bceac09
--- /dev/null
+++ b/src/components/basket/FormatShoppingItem.js
@@ -0,0 +1,22 @@
+import React, { useContext, useEffect } from "react";
+import { Button } from 'react-bootstrap';
+import { GlobalContext } from "../../contexts/GlobalContext";
+import { getAPIIcon } from "../../utils/styling";
+
+export default function FormatShoppingItem(props) {
+    const { api_host, isAuthenticated } = useContext(GlobalContext);
+
+    const profileUrl = api_host + "accounts/user-profiles/";
+
+    if (isAuthenticated) {
+
+        return <a href={profileUrl} target="_blank">
+            <Button variant="outline-primary">{getAPIIcon()}&nbsp;API (expert user)
+            </Button>
+        </a>
+
+    } else {
+        // do not show shopping basket when not authenticated
+        return null
+    }
+}
\ No newline at end of file
diff --git a/src/components/basket/MyBasketPage.js b/src/components/basket/MyBasketPage.js
index 6026eb9381df393046db643f8046eeb1e7bd51a4..c27dddf2e5df7f40cd6bfa1c97d899ad0a4e0590 100644
--- a/src/components/basket/MyBasketPage.js
+++ b/src/components/basket/MyBasketPage.js
@@ -3,13 +3,56 @@ import { Table, Container, Alert } from "react-bootstrap";
 
 import { BasketContext } from "../../contexts/BasketContext";
 import { GlobalContext } from "../../contexts/GlobalContext";
+import { QueryContext } from "../../contexts/QueryContext";
+
 import AddToBasket from "./AddToBasketCheckBox";
 import APIButton from "./APIButton"
 import EmptyBasketButton from "./EmptyBasketButton"
+import { renderRowApertif, renderHeaderApertif }  from "../services/layout/ApertifResultsLayout"
+import { renderRowAstronVO, renderHeaderAstronVO }  from "../services/layout/AstronVOLayout"
+
+function renderRow(item) {
+    switch(item.archive) {
+
+        case 'apertif':
+
+            return <div>
+                <Table className="mt-3" size="sm" responsive>
+                    <thead>
+                    <tr className="bg-light">
+                        {renderHeaderApertif()}
+                    </tr>
+                    </thead>
+                    <tbody>
+                        {renderRowApertif((item.record))}
+                    </tbody>
+                </Table>
+            </div>
+
+        case 'astron_vo':
+
+            return <div>
+                <Table className="mt-3" size="sm" responsive>
+                    <thead>
+                    <tr className="bg-light">
+                        {renderHeaderAstronVO()}
+                    </tr>
+                    </thead>
+                    <tbody>
+                        {renderRowAstronVO((item.record))}
+                    </tbody>
+                </Table>
+            </div>
+
+        default:
+            return JSON.stringify(item)
+    }
+}
 
 export default function MyBasketPage() {
     const { api_host, isAuthenticated } = useContext(GlobalContext);
     const basketContext = useContext(BasketContext);
+    const { preview } = useContext(QueryContext);
 
     // work on a local copy of datasets, to be able (un)(re)select items before saving
     const [items, setItems] = useState(basketContext.datasets);
@@ -18,19 +61,22 @@ export default function MyBasketPage() {
         return null
     }
 
+    //if (items.length === basketContext.datasets.length) {
+    //    basketContext.changed(false)
+    //}
+
     // parse the items and build a line to display
     let my_list = items.map((item, index) => {
         let id = `${index}`
         let archive = item.archive
-        let item_as_string = JSON.stringify(item)
 
-        return <tr>
+        return <><tr>
             <td>
                 <AddToBasket id={id} item={item} label=""/>
             </td>
             <td>{archive}</td>
-            <td>{item_as_string}</td>
-        </tr>
+            <td>{renderRow(item)}</td>
+        </tr></>
     })
 
     return (
diff --git a/src/components/query/ApertifResults.js b/src/components/query/ApertifResults.js
deleted file mode 100644
index 01c940e8852ee90d1d396367e2f723c6864a62e1..0000000000000000000000000000000000000000
--- a/src/components/query/ApertifResults.js
+++ /dev/null
@@ -1,137 +0,0 @@
-import React, { useContext, useState, useEffect } from "react";
-import { Table, Alert } from "react-bootstrap";
-import axios from "axios";
-import { QueryContext } from "../../contexts/QueryContext";
-import { GlobalContext } from "../../contexts/GlobalContext";
-
-import LoadingSpinner from "../LoadingSpinner";
-import Paginate from "../Paginate";
-import HandlePreview from "./HandlePreview";
-import Preview from "./Preview";
-import AddToBasket from "../basket/AddToBasketCheckBox";
-
-function createBasketItem(record){
-    return {
-        archive: "apertif",
-        record: record,
-    };
-}
-
-export default function ApertifResults({ catalog }) {
-  const { queryMap, preview } = useContext(QueryContext);
-  const { api_host } = useContext(GlobalContext);
-  const [page, setPage] = useState(queryMap.get(catalog).page);const { isAuthenticated } = useContext(GlobalContext);
-
-  useEffect(() => {
-    queryMap.set(catalog, {
-      catalog: catalog,
-      page: page,
-      esapquery: queryMap.get(catalog).esapquery + `&page=${page}`,
-    });
-    const url = api_host + "query/query/?" + queryMap.get(catalog).esapquery;
-    axios
-      .get(url)
-      .then((queryResponse) => {
-        queryMap.set(catalog, {
-          catalog: catalog,
-          esapquery: queryMap.get(catalog).esapquery,
-          page: page,
-          status: "fetched",
-          results: queryResponse.data,
-        });
-      })
-      .catch(() => {
-        queryMap.set(catalog, {
-          catalog: catalog,
-          esapquery: queryMap.get(catalog).esapquery,
-          page: page,
-          status: "error",
-          results: null,
-        });
-      });
-  }, [page])
-
-  if (!queryMap) return null;
-  if (queryMap.get(catalog).status === "fetched") {
-    if (!("results" in queryMap.get(catalog).results))
-      return <Alert variant="warning">{queryMap.get(catalog).results}</Alert>;
-    if (queryMap.get(catalog).results.results.length === 0)
-      return <Alert variant="warning">No matching results found!</Alert>;
-
-    const numPages = queryMap.get(catalog).results.pages;
-    console.log("Query results:", queryMap.get(catalog).results.results);
-    return (
-      <>
-        <Paginate
-          getNewPage={(args) => {
-            return args.target ? setPage(parseInt(args.target.text)) : null;
-          }}
-          currentPage={queryMap.get(catalog).page}
-          numAdjacent={3}
-          numPages={numPages}
-        />
-
-        <Table className="mt-3" responsive>
-          <thead>
-            <tr className="bg-light">
-              <th>Basket</th>
-              <th>Name</th>
-              <th>RA</th>
-              <th>Dec</th>
-              <th>fov</th>
-              <th>Dataset ID</th>
-              <th>Data Product Type</th>
-              <th>Data Product Subtype</th>
-              <th>Link to data</th>
-              <th></th>
-            </tr>
-          </thead>
-          <tbody>
-            {queryMap.get(catalog).results.results.map((result) => {
-              return (
-                <>
-                <tr key={result.PID}>
-                  <td>
-                    <AddToBasket id={result.id} item={createBasketItem(result)} />
-                  </td>
-                  <td>{result.name}</td>
-                  <td>{Number(result.RA).toFixed(1)}</td>
-                  <td>{Number(result.dec).toFixed(1)}</td>
-                  <td>{Number(result.fov).toFixed(1)}</td>
-                  <td>{result.datasetID}</td>
-                  <td>{result.dataProductType}</td>
-                  <td>{result.dataProductSubType}</td>
-                  <td>
-                    <a
-                      href={result.url}
-                      target="_blank"
-                      rel="noopener noreferrer"
-                      download
-                    >
-                      Download data
-                    </a>
-                  </td>
-                  <td>
-                      <HandlePreview result={result} />
-                  </td>
-                </tr>
-                {preview === result.url && 
-                    <tr key={result.url}>
-                      <td></td>
-                      <td></td>
-                      <td></td>
-                      <td></td>
-                      <td colSpan="4" ><Preview /></td>
-                      <td></td>
-                    </tr>}
-                </>
-              );
-            })}
-          </tbody>
-        </Table>
-      </>
-    );
-  } else {
-    return <LoadingSpinner />;
-  }
-}
diff --git a/src/components/query/QueryADEX.js b/src/components/query/QueryADEX.js
index 96243532d47e28f408aa03835d7851d2a0f477ff..ef2adfe2f2074392cbb29c724af4a5702a327e40 100644
--- a/src/components/query/QueryADEX.js
+++ b/src/components/query/QueryADEX.js
@@ -5,7 +5,7 @@ import { Container } from "react-bootstrap";
 import Form from "react-jsonschema-form";
 import { GlobalContext } from "../../contexts/GlobalContext";
 import { QueryContext } from "../../contexts/QueryContext";
-import QueryResults from "./QueryResults";
+import QueryResults from "../services/query_results/QueryResults";
 import parseQueryForm from "../../utils/form/parseQueryForm";
 
 export default function QueryCatalogs() {
diff --git a/src/components/query/QueryCatalogs.js b/src/components/query/QueryCatalogs.js
index 2207b9e02d4678f62bc91189f2cbd3ee16f048f2..6aad437fe34ea6e36313bc70641f1be7ea7e788c 100644
--- a/src/components/query/QueryCatalogs.js
+++ b/src/components/query/QueryCatalogs.js
@@ -6,7 +6,7 @@ import Form from "react-jsonschema-form";
 import { GlobalContext } from "../../contexts/GlobalContext";
 import { BasketContextProvider } from "../../contexts/BasketContext"
 import { QueryContext } from "../../contexts/QueryContext";
-import QueryResults from "./QueryResults";
+import QueryResults from "../services/query_results/QueryResults";
 import parseQueryForm from "../../utils/form/parseQueryForm";
 
 export default function QueryCatalogs() {
diff --git a/src/components/query/QueryIVOARegistry.js b/src/components/query/QueryIVOARegistry.js
index bf12abd1c6c51662599e5d84476790661efe7f00..69df97b6dd6d77376c34f5f5d064444062fca9b9 100644
--- a/src/components/query/QueryIVOARegistry.js
+++ b/src/components/query/QueryIVOARegistry.js
@@ -5,11 +5,11 @@ import { Container, Button, Row, Col, Form as RBForm } from "react-bootstrap";
 import Form from "react-jsonschema-form";
 import { GlobalContext } from "../../contexts/GlobalContext";
 import { QueryContext } from "../../contexts/QueryContext";
-import QueryResults from "./QueryResults";
+import QueryResults from "../services/query_results/QueryResults";
 import parseQueryForm from "../../utils/form/parseQueryForm";
 import { IVOAContext } from "../../contexts/IVOAContext";
 import parseVOServiceForm from "../../utils/form/parseVOServiceForm";
-import VOServiceResults from "./VOServiceResults";
+import VOServiceResults from "../services/query_results/VOServiceResults";
 import { getQueryIcon } from "../../utils/styling";
 
 export default function QueryIVOARegistry() {
diff --git a/src/components/Interactive.js b/src/components/services/Interactive.js
similarity index 93%
rename from src/components/Interactive.js
rename to src/components/services/Interactive.js
index 2cf8a907572c6021db7eb799c8cf0fd861ca1275..00d59d047c120c0bb308624a82490291b799bec1 100644
--- a/src/components/Interactive.js
+++ b/src/components/services/Interactive.js
@@ -1,7 +1,7 @@
 import React, { useContext } from "react";
 import { Button, Form, Container, Alert } from "react-bootstrap";
-import { IDAContext } from "../contexts/IDAContext";
-import { GlobalContext } from "../contexts/GlobalContext";
+import { IDAContext } from "../../contexts/IDAContext";
+import { GlobalContext } from "../../contexts/GlobalContext";
 
 
 export default  function Interactive() {
diff --git a/src/components/Rucio.js b/src/components/services/Rucio.js
similarity index 100%
rename from src/components/Rucio.js
rename to src/components/services/Rucio.js
diff --git a/src/components/services/layout/ApertifResultsLayout.js b/src/components/services/layout/ApertifResultsLayout.js
new file mode 100644
index 0000000000000000000000000000000000000000..0b86e0cf61e730a9b79b2d8d1db88a32ae8d7c37
--- /dev/null
+++ b/src/components/services/layout/ApertifResultsLayout.js
@@ -0,0 +1,29 @@
+import React, { useContext, useState, useEffect } from "react";
+
+export function renderHeaderApertif() {
+
+    return (<>
+            <th style={{width: '10%'}}>Name</th>
+            <th style={{width: '5%'}}>RA</th>
+            <th style={{width: '5%'}}>Dec</th>
+            <th style={{width: '5%'}}>fov</th>
+            <th style={{width: '10%'}}>DataProduct Type</th>
+            <th style={{width: '10%'}}>DataProduct SubType</th>
+            <th style={{width: '5%'}}>Dataset ID</th>
+        </>
+    );
+}
+
+export function renderRowApertif(result) {
+
+    return (<>
+            <td>{result.name}</td>
+            <td>{Number(result.RA).toFixed(1)}</td>
+            <td>{Number(result.dec).toFixed(1)}</td>
+            <td>{Number(result.fov).toFixed(1)}</td>
+            <td>{result.dataProductType}</td>
+            <td>{result.dataProductSubType}</td>
+            <td>{result.datasetID}</td>
+        </>
+    );
+}
diff --git a/src/components/services/layout/AstronVOLayout.js b/src/components/services/layout/AstronVOLayout.js
new file mode 100644
index 0000000000000000000000000000000000000000..241ace6ee3ca4e9c7fd140ce5582e3cf367085ca
--- /dev/null
+++ b/src/components/services/layout/AstronVOLayout.js
@@ -0,0 +1,29 @@
+import React, { useContext, useState, useEffect } from "react";
+
+export function renderHeaderAstronVO() {
+
+    return (<>
+        <th style={{width: '10%'}}>Collection</th>
+        <th style={{width: '5%'}}>RA</th>
+        <th style={{width: '5%'}}>Dec</th>
+        <th style={{width: '5%'}}>fov</th>
+            <th style={{width: '10%'}}>DataProduct Type</th>
+            <th style={{width: '10%'}}>Calibration Level</th>
+            <th style={{width: '5%'}}>Size</th>
+        </>
+    );
+}
+
+export function renderRowAstronVO(result) {
+
+    return (<>
+        <td>{result.obs_collection}</td>
+        <td>{Number(result.ra).toFixed(1)}</td>
+        <td>{Number(result.dec).toFixed(1)}</td>
+        <td>{Number(result.fov).toFixed(1)}</td>
+        <td>{result.dataproduct_type}</td>
+        <td>{result.calibration_level}</td>
+        <td>{Number((result.size / 1024).toFixed(1))} MB</td>
+        </>
+    );
+}
diff --git a/src/components/query/ASTRONVOResults.js b/src/components/services/query_results/ASTRONVOResults.js
similarity index 74%
rename from src/components/query/ASTRONVOResults.js
rename to src/components/services/query_results/ASTRONVOResults.js
index 870bc02e27d4af57683dce96b0a9994cc608ca82..3caaa626d683cdf135c7c16f1e868051e5374f38 100644
--- a/src/components/query/ASTRONVOResults.js
+++ b/src/components/services/query_results/ASTRONVOResults.js
@@ -1,15 +1,16 @@
 import React, { useContext, useState, useEffect } from "react";
 import { Table, Alert } from "react-bootstrap";
 import axios from "axios";
-import { QueryContext } from "../../contexts/QueryContext";
-import { GlobalContext } from "../../contexts/GlobalContext";
-import LoadingSpinner from "../LoadingSpinner";
-import Paginate from "../Paginate";
-import HandlePreview from "./HandlePreview";
-import Preview from "./Preview";
-import AddToBasket from "../basket/AddToBasketCheckBox";
+import { QueryContext } from "../../../contexts/QueryContext";
+import { GlobalContext } from "../../../contexts/GlobalContext";
+import LoadingSpinner from "../../LoadingSpinner";
+import Paginate from "../../Paginate";
+import HandlePreview from "../../query/HandlePreview";
+import Preview from "../../query/Preview";
+import AddToBasket from "../../basket/AddToBasketCheckBox";
+import { renderRowAstronVO, renderHeaderAstronVO }  from "../layout/AstronVOLayout"
 
-function SAMPBasketItem(record){
+function createBasketItem(record){
     return {
         archive: "astron_vo",
         record: record,
@@ -74,13 +75,7 @@ export default function ASTRONVOResults({ catalog }) {
           <thead>
             <tr className="bg-light">
               <th>Basket</th>
-              <th>Collection</th>
-              <th>RA</th>
-              <th>Dec</th>
-              <th>fov</th>
-              <th>Data Product Type</th>
-              <th>Calibration Level</th>
-              <th>Size</th>
+                {renderHeaderAstronVO()}
               <th>Link to data</th>
               <th></th>
             </tr>
@@ -91,15 +86,10 @@ export default function ASTRONVOResults({ catalog }) {
                 <>
                   <tr key={result.url}>
                     <td>
-                      <AddToBasket id={result.id} item={SAMPBasketItem(result)} />
+                      <AddToBasket id={result.id} item={createBasketItem(result)} />
                     </td>
-                    <td>{result.obs_collection}</td>
-                    <td>{Number(result.ra).toFixed(1)}</td>
-                    <td>{Number(result.dec).toFixed(1)}</td>
-                    <td>{Number(result.fov).toFixed(1)}</td>
-                    <td>{result.dataproduct_type}</td>
-                    <td>{result.calibration_level}</td>
-                    <td>{Number((result.size / 1024).toFixed(1))} MB</td>
+                      {renderRowAstronVO(result)}
+
                     <td>
                       <a href={result.url} rel="noopener noreferrer" download>
                         Download data
diff --git a/src/components/services/query_results/ApertifResults.js b/src/components/services/query_results/ApertifResults.js
new file mode 100644
index 0000000000000000000000000000000000000000..66dd82614565934e82ca2d45134805bbd6abd0f1
--- /dev/null
+++ b/src/components/services/query_results/ApertifResults.js
@@ -0,0 +1,127 @@
+import React, { useContext, useState, useEffect } from "react";
+import { Table, Alert } from "react-bootstrap";
+import axios from "axios";
+import { QueryContext } from "../../../contexts/QueryContext";
+import { GlobalContext } from "../../../contexts/GlobalContext";
+
+import LoadingSpinner from "../../LoadingSpinner";
+import Paginate from "../../Paginate";
+import HandlePreview from "../../query/HandlePreview";
+import Preview from "../../query/Preview";
+import AddToBasket from "../../basket/AddToBasketCheckBox";
+import { renderRowApertif, renderHeaderApertif }  from "../layout/ApertifResultsLayout"
+
+
+function createBasketItem(record){
+    return {
+        archive: "apertif",
+        record: record,
+    };
+}
+
+export default function ApertifResults({ catalog }) {
+    const { queryMap, preview } = useContext(QueryContext);
+    const { api_host } = useContext(GlobalContext);
+    const [page, setPage] = useState(queryMap.get(catalog).page);const { isAuthenticated } = useContext(GlobalContext);
+
+    useEffect(() => {
+        queryMap.set(catalog, {
+            catalog: catalog,
+            page: page,
+            esapquery: queryMap.get(catalog).esapquery + `&page=${page}`,
+        });
+        const url = api_host + "query/query/?" + queryMap.get(catalog).esapquery;
+        axios
+            .get(url)
+            .then((queryResponse) => {
+                queryMap.set(catalog, {
+                    catalog: catalog,
+                    esapquery: queryMap.get(catalog).esapquery,
+                    page: page,
+                    status: "fetched",
+                    results: queryResponse.data,
+                });
+            })
+            .catch(() => {
+                queryMap.set(catalog, {
+                    catalog: catalog,
+                    esapquery: queryMap.get(catalog).esapquery,
+                    page: page,
+                    status: "error",
+                    results: null,
+                });
+            });
+    }, [page])
+
+    if (!queryMap) return null;
+    if (queryMap.get(catalog).status === "fetched") {
+        if (!("results" in queryMap.get(catalog).results))
+            return <Alert variant="warning">{queryMap.get(catalog).results}</Alert>;
+        if (queryMap.get(catalog).results.results.length === 0)
+            return <Alert variant="warning">No matching results found!</Alert>;
+
+        const numPages = queryMap.get(catalog).results.pages;
+        console.log("Query results:", queryMap.get(catalog).results.results);
+        return (
+            <>
+            <Paginate
+                getNewPage={(args) => {
+                    return args.target ? setPage(parseInt(args.target.text)) : null;
+                }}
+                currentPage={queryMap.get(catalog).page}
+                numAdjacent={3}
+                numPages={numPages}
+            />
+
+            <Table className="mt-3" responsive>
+              <thead>
+              <tr className="bg-light">
+                <th>Basket</th>
+                  {renderHeaderApertif()}
+                <th>Link to data</th>
+                <th></th>
+              </tr>
+              </thead>
+              <tbody>
+              {queryMap.get(catalog).results.results.map((result) => {
+                  return (
+                      <>
+                      <tr key={result.PID}>
+                        <td>
+                          <AddToBasket id={result.id} item={createBasketItem(result)} />
+                        </td>
+                          {renderRowApertif(result)}
+                        <td>
+                          <a
+                              href={result.url}
+                              target="_blank"
+                              rel="noopener noreferrer"
+                              download
+                          >
+                            Download data
+                          </a>
+                        </td>
+                        <td>
+                          <HandlePreview result={result} />
+                        </td>
+                      </tr>
+                      {preview === result.url &&
+                      <tr key={result.url}>
+                        <td></td>
+                        <td></td>
+                        <td></td>
+                        <td></td>
+                        <td colSpan="4" ><Preview /></td>
+                        <td></td>
+                      </tr>}
+                      </>
+                  );
+              })}
+              </tbody>
+            </Table>
+            </>
+        );
+    } else {
+        return <LoadingSpinner />;
+    }
+}
diff --git a/src/components/query/LOFARResults.js b/src/components/services/query_results/LOFARResults.js
similarity index 95%
rename from src/components/query/LOFARResults.js
rename to src/components/services/query_results/LOFARResults.js
index 54a4ce05d3b9939e01ab52c03bdd28b85dc0f761..8487171d34fdec6c2f831102ad28cfad02dadc9d 100644
--- a/src/components/query/LOFARResults.js
+++ b/src/components/services/query_results/LOFARResults.js
@@ -1,9 +1,9 @@
 import React, { useContext, useState, useEffect } from "react";
 import { Table, Alert } from "react-bootstrap";
 import axios from "axios";
-import { QueryContext } from "../../contexts/QueryContext";
-import { GlobalContext } from "../../contexts/GlobalContext";
-import LoadingSpinner from "../LoadingSpinner";
+import { QueryContext } from "../../../contexts/QueryContext";
+import { GlobalContext } from "../../../contexts/GlobalContext";
+import LoadingSpinner from "../../LoadingSpinner";
 
 export default function LOFARResults({ catalog }) {
   const { queryMap } = useContext(QueryContext);
diff --git a/src/components/query/QueryResults.js b/src/components/services/query_results/QueryResults.js
similarity index 100%
rename from src/components/query/QueryResults.js
rename to src/components/services/query_results/QueryResults.js
diff --git a/src/components/query/RucioResults.js b/src/components/services/query_results/RucioResults.js
similarity index 95%
rename from src/components/query/RucioResults.js
rename to src/components/services/query_results/RucioResults.js
index c1252c8d177cb7de152028eeed4f137535ce7d61..f63e19f2960b112e907ce76c8b95655d9bf9af99 100644
--- a/src/components/query/RucioResults.js
+++ b/src/components/services/query_results/RucioResults.js
@@ -1,10 +1,10 @@
 import React, { useContext } from "react";
 import { Table, Alert, Form } from "react-bootstrap";
-import { QueryContext } from "../../contexts/QueryContext";
+import { QueryContext } from "../../../contexts/QueryContext";
 // import { BasketContext } from "../../contexts/BasketContext";
-import LoadingSpinner from "../LoadingSpinner";
-import Paginate from "../Paginate";
-import AddToBasket from "../basket/AddToBasketCheckBox";
+import LoadingSpinner from "../../LoadingSpinner";
+import Paginate from "../../Paginate";
+import AddToBasket from "../../basket/AddToBasketCheckBox";
 
 function createBasketItem(record){
     return {
diff --git a/src/components/query/SampResults.js b/src/components/services/query_results/SampResults.js
similarity index 83%
rename from src/components/query/SampResults.js
rename to src/components/services/query_results/SampResults.js
index c67ce83184a7c1e6c17b6b13371032d92cdcdbb0..e0a4f7af04f12ed3d7c758f4243f801b17d5b5a4 100644
--- a/src/components/query/SampResults.js
+++ b/src/components/services/query_results/SampResults.js
@@ -1,5 +1,5 @@
 import React, { useContext, useState, useEffect } from "react";
-import SampPage from './samp/SampPage';
+import SampPage from '../samp/SampPage';
 
 // TODO: this is not hooked up to the database yet as a catalog
 export default function SampResults({ catalog }) {
diff --git a/src/components/query/VORegListResults.js b/src/components/services/query_results/VORegListResults.js
similarity index 94%
rename from src/components/query/VORegListResults.js
rename to src/components/services/query_results/VORegListResults.js
index bf4f333f2317aa858a1ca73b384e9356f968e35f..77e439f6a92165234fd1a79754abea15703220a0 100644
--- a/src/components/query/VORegListResults.js
+++ b/src/components/services/query_results/VORegListResults.js
@@ -1,9 +1,9 @@
 import React, { useContext, useEffect } from "react";
 import { Table, Alert, InputGroup } from "react-bootstrap";
-import { QueryContext } from "../../contexts/QueryContext";
-import LoadingSpinner from "../LoadingSpinner";
-import Paginate from "../Paginate";
-import { IVOAContext } from "../../contexts/IVOAContext";
+import { QueryContext } from "../../../contexts/QueryContext";
+import LoadingSpinner from "../../LoadingSpinner";
+import Paginate from "../../Paginate";
+import { IVOAContext } from "../../../contexts/IVOAContext";
 
 export default function VORegListResults({ catalog }) {
   const { queryMap } = useContext(QueryContext);
diff --git a/src/components/query/VOServiceResults.js b/src/components/services/query_results/VOServiceResults.js
similarity index 95%
rename from src/components/query/VOServiceResults.js
rename to src/components/services/query_results/VOServiceResults.js
index 1ea90cbdc31fcd1bcc1f4ef44471f0431b84a30d..d5e73265782d8286282655b6378d19a4de9d3f65 100644
--- a/src/components/query/VOServiceResults.js
+++ b/src/components/services/query_results/VOServiceResults.js
@@ -1,9 +1,9 @@
 import React, { useContext } from "react";
 import { Alert, Table, Button } from "react-bootstrap"; 
-import { QueryContext } from "../../contexts/QueryContext";
-import LoadingSpinner from "../LoadingSpinner";
-import Paginate from "../Paginate";
-import Preview from "./Preview";
+import { QueryContext } from "../../../contexts/QueryContext";
+import LoadingSpinner from "../../LoadingSpinner";
+import Paginate from "../../Paginate";
+import Preview from "../../query/Preview";
 
 export default function VORegistryResults({ catalog }) {
   const { queryMap, page, setPage, preview, setPreview, setURL } = useContext(QueryContext);
diff --git a/src/components/query/ZooniverseResults.js b/src/components/services/query_results/ZooniverseResults.js
similarity index 96%
rename from src/components/query/ZooniverseResults.js
rename to src/components/services/query_results/ZooniverseResults.js
index 36ebf541717b12cb08d06db9e048d9c27e21053c..c391d9c53ac462ae05a2c57781cb3b1e3aa13eed 100644
--- a/src/components/query/ZooniverseResults.js
+++ b/src/components/services/query_results/ZooniverseResults.js
@@ -1,13 +1,13 @@
 import React, { useContext, useEffect } from "react";
 import { Table, Alert, Form } from "react-bootstrap";
 import axios from "axios";
-import { GlobalContext } from "../../contexts/GlobalContext";
-import { QueryContext } from "../../contexts/QueryContext";
-import { BasketContext } from "../../contexts/BasketContext";
-import LoadingSpinner from "../LoadingSpinner";
-import Paginate, { pagination_fields } from "../Paginate";
-import SaveBasketButton from "../basket/SaveBasketButton";
-import AddToBasket from "../basket/AddToBasketCheckBox";
+import { GlobalContext } from "../../../contexts/GlobalContext";
+import { QueryContext } from "../../../contexts/QueryContext";
+import { BasketContext } from "../../../contexts/BasketContext";
+import LoadingSpinner from "../../LoadingSpinner";
+import Paginate, { pagination_fields } from "../../Paginate";
+import SaveBasketButton from "../../basket/SaveBasketButton";
+import AddToBasket from "../../basket/AddToBasketCheckBox";
 
 const DATETIME_OPTIONS = {
   year: "numeric",
@@ -254,7 +254,7 @@ function ZooniverseWorkflowResults(context) {
         numPages={numPages}
       />
       <Form>
-      <SaveBasketButton style={saveBasketStyle} />
+
       {queryMap
         .get("zooniverse_workflows")
         .results.results.map((project) => {
diff --git a/src/components/query/samp/ReactVOTable.js b/src/components/services/samp/ReactVOTable.js
similarity index 100%
rename from src/components/query/samp/ReactVOTable.js
rename to src/components/services/samp/ReactVOTable.js
diff --git a/src/components/query/samp/SampGrid.js b/src/components/services/samp/SampGrid.js
similarity index 100%
rename from src/components/query/samp/SampGrid.js
rename to src/components/services/samp/SampGrid.js
diff --git a/src/components/query/samp/SampPage.js b/src/components/services/samp/SampPage.js
similarity index 100%
rename from src/components/query/samp/SampPage.js
rename to src/components/services/samp/SampPage.js
diff --git a/src/contexts/BasketContext.js b/src/contexts/BasketContext.js
index 3482e8f89f93906bbb69e7d0c26f1417258ba9f4..346f30437709963dfdb0e62b6e60ef590b3ca4e4 100644
--- a/src/contexts/BasketContext.js
+++ b/src/contexts/BasketContext.js
@@ -29,6 +29,7 @@ export function BasketContextProvider({ children }) {
             setHasChanged,
             add: handleAddDataset,
             remove: handleRemoveDataset,
+            changed: setHasChanged
         }}
       >
       {children}
diff --git a/src/routes/Routes.js b/src/routes/Routes.js
index 7c70b2559626a8ee04d3a405a5b5fa506c55ec96..169cfaa6f1375cdbe625f4a75baeaaeba0bd83cb 100644
--- a/src/routes/Routes.js
+++ b/src/routes/Routes.js
@@ -8,14 +8,14 @@ import QueryCatalogs from "../components/query/QueryCatalogs";
 import QueryIVOARegistry from "../components/query/QueryIVOARegistry";
 import { BrowserRouter as Router } from "react-router-dom";
 import NavBar from "../components/NavBar";
-import Rucio from "../components/Rucio";
-import Interactive from "../components/Interactive";
+import Rucio from "../components/services/Rucio";
+import Interactive from "../components/services/Interactive";
 import MyBasketPage from "../components/basket/MyBasketPage";
 
 
 import { IVOAContextProvider } from "../contexts/IVOAContext";
 import { IDAContext } from "../contexts/IDAContext";
-import SampPage from '../components/query/samp/SampPage';
+import SampPage from '../components/services/samp/SampPage';
 
 export default function Routes() {
     const { navbar, handleLogin, handleLogout, handleError } = useContext(GlobalContext);
@@ -72,7 +72,7 @@ export default function Routes() {
 
         </Switch>
 
-      <footer><small>esap-gui version 9 jul 2021 - 11:00</small></footer>
+      <footer><small>esap-gui version 9 jul 2021 - 15:00</small></footer>
     </Router>
   );
 }