+
-
+ navigate(-1)} size={40} color='darkBlue' />
Data Studio
{metadata.name}
-
-
-
+ {isMobile ? (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
+
-
+ )}
);
}
diff --git a/src/pages/Catalogue.jsx b/src/pages/Catalogue.jsx
index 3dd990c..b406cdf 100644
--- a/src/pages/Catalogue.jsx
+++ b/src/pages/Catalogue.jsx
@@ -137,6 +137,7 @@ function Catalogue() {
@@ -145,11 +146,12 @@ function Catalogue() {
{hasCategories &&
- Object.entries(categories).map(([groupName, artefacts]) => (
+ Object.entries(categories).map(([catID, catObj]) => (
))}
diff --git a/src/pages/DataStudio.jsx b/src/pages/DataStudio.jsx
deleted file mode 100644
index 5efb649..0000000
--- a/src/pages/DataStudio.jsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import { DndContext, DragOverlay } from "@dnd-kit/core";
-import { useState } from "react";
-import { Box, Flex, Text } from "@chakra-ui/react";
-import ItemGrid from "../components/DataStudio/ItemGrid.jsx";
-import ItemGroups from "../components/DataStudio/ItemGroups.jsx";
-import CardItem from "../components/Catalogue/cardItem.jsx";
-
-function DataStudio() {
- const [droppedItems, setDroppedItems] = useState({});
- const [activeItem, setActiveItem] = useState(null);
-
- const handleDragStart = (event) => {
- setActiveItem(event.active.data.current);
- };
-
- const handleDragEnd = (event) => {
- const { active, over } = event;
- setActiveItem(null);
-
- if (over && active) {
- const groupId = over.id;
- const itemId = active.id;
-
- setDroppedItems((prev) => {
- // Avoid duplicates by checking if item already exists in the group
- const existingItems = prev[groupId] || [];
- if (existingItems.some((item) => item.id === itemId)) {
- return prev;
- }
-
- return {
- ...prev,
- [groupId]: [...existingItems, active.data.current],
- };
- });
- }
- };
-
- return (
-
-
- {/* Left Panel (Draggable Items) */}
-
-
- Data Studio
- Batch
-
-
-
-
-
-
- {/* Right Panel (Droppable Groups) */}
-
-
-
-
-
- {/* Drag Preview */}
-
- {activeItem ? (
-
-
-
- ) : null}
-
-
- );
-}
-
-export default DataStudio;
\ No newline at end of file
diff --git a/src/pages/GroupView.jsx b/src/pages/GroupView.jsx
index d3fbe4d..f7dbc72 100644
--- a/src/pages/GroupView.jsx
+++ b/src/pages/GroupView.jsx
@@ -1,9 +1,180 @@
-import { useParams } from 'react-router-dom';
+import { Flex, Box, Text, Grid } from '@chakra-ui/react';
+import { useParams, useNavigate } from 'react-router-dom';
+import { FaCircleArrowLeft } from 'react-icons/fa6';
+import { useEffect, useState } from 'react';
+import CentredSpinner from '../components/CentredSpinner';
+import server, { JSONResponse } from '../networking'
+import ToastWizard from '../components/toastWizard';
+import GroupCardItem from '../components/DataStudio/groupCardItem';
function GroupView() {
const { colID } = useParams();
+ const navigate = useNavigate();
+ const [collection, setCollection] = useState(null);
+ const [loading, setLoading] = useState(true);
- return GroupView for collection {colID}
;
+ useEffect(() => {
+ const fetchCollection = async () => {
+ try {
+ setLoading(true);
+ const response = await server.get(`/cdn/collection/${colID}`);
+
+ if (response.data instanceof JSONResponse) {
+ if (response.data.isErrorStatus()) {
+ const errObject = {
+ response: {
+ data: response.data
+ }
+ };
+ throw errObject;
+ }
+
+ // Success case - format the data
+ let formattedData;
+ const apiData = response.data.raw.data;
+
+ if (apiData.type === 'book') {
+ formattedData = {
+ type: 'book',
+ name: apiData.title,
+ description: apiData.subtitle || '',
+ items: apiData.mmArtefacts.map(art => ({
+ id: art.id,
+ title: art.name,
+ description: art.description,
+ image: art.image || null
+ }))
+ };
+ } else if (apiData.type === 'category') {
+ formattedData = {
+ type: 'category',
+ name: apiData.name,
+ description: apiData.description || '',
+ items: apiData.members.map(art => ({
+ id: art.id,
+ title: art.name,
+ description: art.description,
+ image: art.image
+ }))
+ };
+ } else if (apiData.type === 'batch') {
+ formattedData = {
+ type: 'batch',
+ name: apiData.name || `Batch ${apiData.id}`,
+ description: apiData.description || '',
+ items: apiData.artefacts.map(art => ({
+ id: art.id,
+ title: art.name,
+ description: art.description,
+ image: art.image || null
+ }))
+ };
+ } else {
+ throw new Error('Unknown collection type');
+ }
+
+ setCollection(formattedData);
+ } else {
+ throw new Error("Unexpected response format");
+ }
+ } catch (err) {
+ if (err.response && err.response.data instanceof JSONResponse) {
+ console.log("Error response in collection request:", err.response.data.fullMessage());
+
+ if (err.response.data.userErrorType()) {
+ ToastWizard.standard(
+ "error",
+ "An Error Occured",
+ "We could not fetch the collection data. Please try again later.",
+ 3000,
+ true,
+ fetchCollection,
+ 'Retry'
+ );
+ } else {
+ ToastWizard.standard(
+ "error",
+ "An Error Occured",
+ "We could not fetch the collection data. Please try again later.",
+ 3000,
+ true,
+ fetchCollection,
+ 'Retry'
+ );
+ }
+ } else {
+ console.log("Unexpected error in collection request:", err);
+ ToastWizard.standard(
+ "error",
+ "An Error Occured",
+ "We could not fetch the collection data. Please try again later.",
+ 3000,
+ true,
+ fetchCollection,
+ 'Retry'
+ );
+ }
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchCollection();
+ }, [colID]);
+
+ if (loading || !collection ) return ;
+
+ return (
+
+ {/* Header with back button */}
+
+ navigate(-1)}
+ size={40}
+ color="darkBlue"
+ />
+
+ Group View
+
+
+
+
+ {collection.name}
+ {collection.description && (
+
+ {collection.description}
+
+ )}
+
+
+ {/* Items grid */}
+
+ {collection.items.map(item => (
+
+ ))}
+
+
+ {collection.items.length === 0 && (
+
+ This collection has no items
+
+ )}
+
+ );
}
-export default GroupView;
+export default GroupView;
\ No newline at end of file