diff --git a/frontend/src/components/RequestForStorageItem/RequestForStorageItemComponent.tsx b/frontend/src/components/RequestForStorageItem/RequestForStorageItemComponent.tsx
new file mode 100644
index 0000000..9f07ab8
--- /dev/null
+++ b/frontend/src/components/RequestForStorageItem/RequestForStorageItemComponent.tsx
@@ -0,0 +1,89 @@
+import React from "react";
+import styled from "styled-components";
+
+import { CircularProgress } from "@mui/material";
+import { MdCheck, MdError } from "react-icons/md";
+import RequestForStorageContractModel from "../../data/models/RequestForStorageContractModel";
+import constants from "../../util/Constants";
+
+function RequestForStorageContractComponent(props: { item: RequestForStorageContractModel }) {
+ return (
+
+
+
+ Request ID:
+ {props.item.requestId}
+
+
+
+
+ Client:
+ {props.item.request.client}
+
+
+
+
+ Content:
+ {props.item.request.content.cid}
+
+
+
+ );
+}
+
+export default RequestForStorageContractComponent;
+
+const RequestForStorageContractComponentWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ background-color: ${constants.surfaceColor};
+ border-radius: 8px;
+ padding: 10px;
+ width: 80%;
+ margin-top: 20px;
+
+ div {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ margin: 5px;
+ }
+
+ div p:nth-child(1) {
+ text-align: start;
+ }
+
+ div p:nth-child(2) {
+ text-align: end;
+ }
+
+ p {
+ flex: 1;
+ font-size: 1rem;
+ text-align: start;
+ margin: 5px;
+ }
+
+ p span {
+ font-weight: bold;
+ }
+
+ #cid {
+ flex: 2;
+ }
+
+ @media (max-width: 1180px) {
+ width: 85%;
+ }
+
+ @media (max-width: 768px) {
+ width: 90%;
+ }
+
+ @media (max-width: 450px) {
+ width: 95%;
+ }
+`;
diff --git a/frontend/src/data/models/RequestForStorageContractModel.ts b/frontend/src/data/models/RequestForStorageContractModel.ts
index 8272892..726f5d7 100644
--- a/frontend/src/data/models/RequestForStorageContractModel.ts
+++ b/frontend/src/data/models/RequestForStorageContractModel.ts
@@ -1,17 +1,31 @@
-enum RequestForStorageContractStatus {
- UPLOADING = "UPLOADING",
- UPLOADED = "UPLOADED",
- FAILED = "FAILED",
-}
-
type RequestForStorageContractModel = {
- purchaseid: string;
- lastModified: string;
- reward: string;
- duration: string;
- collateral: string;
- status: RequestForStorageContractStatus;
+ requestId: string;
+ request: Request;
+ state: string;
+ error: string;
};
-export default RequestForStorageContractModel;
-export { RequestForStorageContractStatus };
+type Request = {
+ client: string;
+ ask: Ask;
+ content: Content;
+ expiry: string;
+ nonce: string;
+ id: string;
+ }
+
+ type Ask = {
+ slots: number;
+ slotSize: string;
+ duration: string;
+ proofProbability: string;
+ reward: string;
+ collateral: string;
+ maxSlotLoss: number;
+ }
+
+ type Content = {
+ cid: string;
+ }
+
+export default RequestForStorageContractModel;
\ No newline at end of file
diff --git a/frontend/src/pages/marketplace/Marketplace.tsx b/frontend/src/pages/marketplace/Marketplace.tsx
index 8e1f971..96e0bfc 100644
--- a/frontend/src/pages/marketplace/Marketplace.tsx
+++ b/frontend/src/pages/marketplace/Marketplace.tsx
@@ -3,16 +3,16 @@ import TabBarView from "../../components/layout/tabBarView/TabBarView";
import styled from "styled-components";
import { MdFileUpload, MdFileDownload } from "react-icons/md";
-import UploadTab from "./tabs/status/status";
+import UploadTab from "./tabs/status/StatusTab";
import DownloadTab from "./tabs/create/CreateTab";
-import AvailableTab from "./tabs/status/status";
+import StatusTab from "./tabs/status/StatusTab";
import CreateTab from "./tabs/create/CreateTab";
function MarketplacePage() {
return (
-
+
diff --git a/frontend/src/pages/marketplace/tabs/status/StatusTab.tsx b/frontend/src/pages/marketplace/tabs/status/StatusTab.tsx
new file mode 100644
index 0000000..ea42216
--- /dev/null
+++ b/frontend/src/pages/marketplace/tabs/status/StatusTab.tsx
@@ -0,0 +1,109 @@
+import { useCallback, useEffect, useRef, useState } from "react";
+import { useDropzone } from "react-dropzone";
+import styled from "styled-components";
+import RequestForStorageContractModel from "../../../../data/models/RequestForStorageContractModel";
+import axios from "axios";
+
+import { useDexyStore } from "../../../../store";
+import constants from "../../../../util/Constants";
+import RequestForStorageContractComponent from "../../../../components/RequestForStorageItem/RequestForStorageItemComponent";
+
+function StatusTab() {
+ const { storageRequests, setStorageRequests, nodeInfo } = useDexyStore();
+ const purchaseIds = useRef([]);
+ const purchaseInfo = useRef([]);
+ const [isLoading, setIsLoading] = useState(false);
+
+ useEffect(() => {
+ setIsLoading(true);
+ // Fetch purchase IDs
+ fetch(`/api/codex/v1/storage/purchases`, {
+ headers: {
+ Authorization: nodeInfo.auth ? "Basic " + btoa(nodeInfo.auth) : "",
+ },
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ purchaseIds.current = data;
+ setIsLoading(false);
+ })
+ .catch((error) => {
+ console.error("Error fetching purchase IDs:", error);
+ setIsLoading(false);
+ });
+ }, []);
+
+ useEffect(() => {
+ if (purchaseIds.current.length > 0) {
+ setIsLoading(true);
+ // Fetch purchase info for each purchase ID
+ Promise.all(
+ purchaseIds.current.map((purchaseId) =>
+ fetch(`/api/codex/v1/storage/purchases/${purchaseId}`, {
+ headers: {
+ Authorization: nodeInfo.auth ? "Basic " + btoa(nodeInfo.auth) : "",
+ },
+ }).then((response) => response.json())
+ )
+ )
+ .then((data) => {
+ purchaseInfo.current = data;
+ setIsLoading(false);
+ })
+ .catch((error) => {
+ console.error("Error fetching purchase info:", error);
+ setIsLoading(false);
+ });
+ }
+ }, [purchaseIds.current]);
+
+ useEffect(() => {
+ if (purchaseInfo.current.length !== storageRequests.length) {
+ setStorageRequests(purchaseInfo.current);
+ }
+ }, [purchaseInfo.current]);
+
+ return (
+
+ 0 ? "60vh" : "0%",
+ }}
+ >
+ {isLoading ? (
+
Loading...
+ ) : (
+ storageRequests.map((item) => (
+
+ ))
+ )}
+
+
+ );
+}
+
+export default StatusTab;
+
+const StatusTabWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ width: 100%;
+ padding: 16px;
+
+ #request-wrap {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: start;
+ width: 100%;
+ overflow-y: scroll;
+ margin-top: 16px;
+ }
+`;
diff --git a/frontend/src/pages/marketplace/tabs/status/status.tsx b/frontend/src/pages/marketplace/tabs/status/status.tsx
deleted file mode 100644
index 05177e4..0000000
--- a/frontend/src/pages/marketplace/tabs/status/status.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import { useCallback, useEffect, useRef } from "react";
-import { useDropzone } from "react-dropzone";
-import styled from "styled-components";
-import UploadedItemModel, {
- UploadedItemStatus,
-} from "../../../../data/models/UploadedItemModel";
-import UploadedItemComponent from "../../../../components/uploadedItem/UploadedItemComponent";
-import axios from "axios";
-
-import { useDexyStore } from "../../../../store";
-import constants from "../../../../util/Constants";
-
-function AvailableTab() {
-// fetch(
-// `/api/codex/v1/storage/request/${cid}`,
-// {
-// headers:
-// (nodeInfo.auth !== null && {
-// Authorization:
-// (nodeInfo.auth && "Basic " + btoa(nodeInfo.auth)) || "",
-// }) ||
-// {},
-// body: JSON.stringify({
-// reward: reward,
-// duration: duration,
-// proofProbability: proofProbability,
-// collateral: collateral
-// })
-// }
-// )
-// // create a popup in the browser to show if the upload was successful
-// .then((response) => {
-// if (response.status === 200) {
-// alert("Upload successful!");
-// } else {
-// alert("Upload failed!");
-// }
-// })
-// }
- return (
-
- {/* 0 ? "60vh" : "0%",
- }}
- >
- {uploads.map((file) => (
-
- ))}
-
*/}
-
- );
-}
-
-export default AvailableTab;
-
-const AvailableTabWrapper = styled.div`
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 100%;
- width: 100%;
- padding: 16px;
-
- #dropzone {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 100%;
- border: 2px dashed #9e9e9e;
- border-radius: 8px;
- }
-
- p {
- font-size: 1rem;
- text-align: center;
- }
-
- #uploaded-items-wrap {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: start;
- width: 100%;
- overflow-y: scroll;
- margin-top: 16px;
- }
-`;