diff --git a/app/Components/About.tsx b/app/Components/About.tsx
new file mode 100644
index 0000000..cd6db5f
--- /dev/null
+++ b/app/Components/About.tsx
@@ -0,0 +1,38 @@
+import { Box, Card, CardContent, Typography, Link, Button, Avatar, Stack } from "@mui/material";
+import GitHubIcon from "@mui/icons-material/GitHub";
+
+export default function About() {
+ const repo = "https://github.com/";
+
+ return (
+
+
+
+
+
+
+
+ Depin Web Client
+
+
+
+ Web client for the MSBD5017 Depin project.
+
+
+
+ In case the website is down, you can run your own local instance by following the instructions in the GitHub repository.
+
+
+
+
+ } variant="outlined">
+ Open GitHub Repository
+
+
+
+
+
+
+ );
+}
+// ...existing code...
\ No newline at end of file
diff --git a/app/Components/Metamask/NewDiscover.tsx b/app/Components/Metamask/NewDiscover.tsx
new file mode 100644
index 0000000..b65052c
--- /dev/null
+++ b/app/Components/Metamask/NewDiscover.tsx
@@ -0,0 +1,126 @@
+// ...existing code...
+import React, { useState } from "react";
+import { useSyncProviders } from "./useSyncProviders";
+import useAuth from "~/hooks/useAuth";
+import type { EIP6963ProviderDetail } from "./EthereumProviderTypes";
+import {
+ Box,
+ Grid,
+ Card,
+ CardContent,
+ Avatar,
+ Typography,
+ Button,
+ Stack,
+ CircularProgress,
+ Alert,
+} from "@mui/material";
+
+const shortAddress = (addr: string) =>
+ addr.length > 12 ? `${addr.slice(0, 6)}...${addr.slice(-6)}` : addr;
+
+export const DiscoverWalletProviders: React.FC = () => {
+ const providers = useSyncProviders();
+ const { auth, setAuth } = useAuth();
+ const [loadingUuid, setLoadingUuid] = useState(null);
+ const [error, setError] = useState(null);
+
+ const handleConnect = async (providerWithInfo: EIP6963ProviderDetail) => {
+ setError(null);
+ setLoadingUuid(providerWithInfo.info.uuid);
+ try {
+ const accounts = await providerWithInfo.provider.request({
+ method: "eth_requestAccounts",
+ });
+
+ if (Array.isArray(accounts) && accounts.length > 0 && typeof accounts[0] === "string") {
+ setAuth({ providerWithInfo, accounts });
+ } else {
+ setError("No accounts returned from wallet.");
+ }
+ } catch (err: any) {
+ console.error(err);
+ setError(err?.message ?? String(err));
+ } finally {
+ setLoadingUuid(null);
+ }
+ };
+
+ return (
+
+
+ Wallets Detected
+
+
+ {error && (
+
+ {error}
+
+ )}
+
+ {providers.length === 0 ? (
+ There are no announced providers.
+ ) : (
+
+ {providers.map((p) => (
+
+
+
+
+
+
+ {p.info.name}
+
+
+
+
+
+
+
+
+ ))}
+
+ )}
+
+
+
+ {auth?.accounts?.length > 0 ? "Wallet Selected" : "No Wallet Selected"}
+
+
+ {auth?.accounts?.length > 0 && auth.providerWithInfo && (
+
+
+
+
+
+ {auth.providerWithInfo.info.name}
+
+ {shortAddress(auth.accounts[0])}
+
+
+
+
+
+
+ )}
+
+
+ );
+};
+
+export default DiscoverWalletProviders;
+// ...existing code...
\ No newline at end of file
diff --git a/app/Components/ServerList.tsx b/app/Components/ServerList.tsx
index b2decc9..36e9b34 100644
--- a/app/Components/ServerList.tsx
+++ b/app/Components/ServerList.tsx
@@ -2,9 +2,11 @@ import * as React from 'react';
import ButtonGroup from '@mui/material/ButtonGroup';
import Button from '@mui/material/Button';
import Avatar from '@mui/material/Avatar';
-import { Grid, Card, CardContent, CardActions, Typography, Box, Chip } from "@mui/material";
+import { Grid, Card, CardContent, CardActions, Typography, Box, Chip, Dialog, DialogTitle, DialogContent, DialogActions, TextField } from "@mui/material";
import ServerIcon from '@mui/icons-material/Dns';
import SignalCellularAltIcon from '@mui/icons-material/SignalCellularAlt';
+import AttachMoneyIcon from '@mui/icons-material/AttachMoney';
+import Rating from '@mui/material/Rating';
import useAuth from '~/hooks/useAuth';
import { signMessage } from './Metamask/Connections';
import axios from 'axios';
@@ -12,10 +14,14 @@ import axios from 'axios';
interface Node {
ip: string;
traffic: number;
+ price : number;
}
function NodeItem({node}: {node: Node}) {
const { auth } = useAuth();
+ const [ratingOpen, setRatingOpen] = React.useState(false);
+ const [ratingValue, setRatingValue] = React.useState(null);
+ const [submittingRating, setSubmittingRating] = React.useState(false);
const connect = async ({ip}: {ip: string}) => {
const res = await signMessage(auth.providerWithInfo.provider, auth.accounts[0]);
try {
@@ -28,7 +34,33 @@ function NodeItem({node}: {node: Node}) {
}
const disconnect = ({ip}: {ip: string}) => {
- console.log("Disconnect from ", ip);
+ // TODO check code
+ setRatingOpen(true);
+ }
+
+ const handleCloseRating = () => {
+ setRatingOpen(false);
+ setRatingValue(null);
+ };
+
+ const handleSubmitRating = async () => {
+ if (ratingValue == null) {
+ return;
+ }
+ setSubmittingRating(true);
+ try {
+ // await axios.post('http://' + node.ip + ":8080/rate", {
+ // rating: ratingValue,
+ // }, {
+ // headers: { "Content-Type": "application/json" }
+ // });
+ // console.log('Rating submitted');
+ } catch (err) {
+ console.error('Failed to submit rating', err);
+ } finally {
+ setSubmittingRating(false);
+ handleCloseRating();
+ }
}
return (
@@ -56,6 +88,19 @@ function NodeItem({node}: {node: Node}) {
variant="outlined"
/>
+
+
+
+
+ Price:
+
+ 15 ? "warning" : "success"}
+ variant="outlined"
+ />
+
+
+
);
}
export default function FolderList() {
- const [nodes, setNodes] = React.useState([{ip: "57.158.82.48", traffic: 5},{ip: "10.0.0.3", traffic: 3},{ip: "10.0.0.4", traffic: 7}]);
+ const [nodes, setNodes] = React.useState([{ip: "57.158.82.48", traffic: 5, price: 10},{ip: "57.158.82.47", traffic: 3, price: 15},{ip: "57.158.82.49", traffic: 7, price: 20}]);
return (
diff --git a/app/routes/about.tsx b/app/routes/about.tsx
index 00e16ad..6e87319 100644
--- a/app/routes/about.tsx
+++ b/app/routes/about.tsx
@@ -1,8 +1,8 @@
+import About from "~/Components/About";
-
-export default function About() {
+export default function AboutPage() {
return(
- About Page
+
);
}
\ No newline at end of file
diff --git a/app/routes/wallets.tsx b/app/routes/wallets.tsx
index 4b2ccfe..5a7ec66 100644
--- a/app/routes/wallets.tsx
+++ b/app/routes/wallets.tsx
@@ -1,7 +1,10 @@
import { DiscoverWalletProviders } from "~/Components/Metamask/DiscoverWalletProviders";
+import NewDiscover from "~/Components/Metamask/NewDiscover";
+
export default function Wallets() {
return(
-
+ //
+
);
}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c8b8f34..eaa9bdd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -60,7 +60,6 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -566,7 +565,6 @@
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -610,7 +608,6 @@
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz",
"integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -1209,7 +1206,6 @@
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.5.tgz",
"integrity": "sha512-8VVxFmp1GIm9PpmnQoCoYo0UWHoOrdA57tDL62vkpzEgvb/d71Wsbv4FRg7r1Gyx7PuSo0tflH34cdl/NvfHNQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/runtime": "^7.28.4",
"@mui/core-downloads-tracker": "^7.3.5",
@@ -1598,7 +1594,6 @@
"resolved": "https://registry.npmjs.org/@react-router/serve/-/serve-7.9.6.tgz",
"integrity": "sha512-qIT8hp1RJ0VAHyXpfuwoO31b9evrjPLRhUugqYJ7BZLpyAwhRsJIaQvvj60yZwWBMF2/3LdZu7M39rf0FhL6Iw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@mjackson/node-fetch-server": "^0.2.0",
"@react-router/express": "7.9.6",
@@ -2219,7 +2214,6 @@
"integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -2241,7 +2235,6 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.6.tgz",
"integrity": "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w==",
"license": "MIT",
- "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -2495,7 +2488,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.25",
"caniuse-lite": "^1.0.30001754",
@@ -3134,7 +3126,6 @@
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
@@ -4465,7 +4456,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -4629,7 +4619,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -4639,7 +4628,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -4668,7 +4656,6 @@
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.6.tgz",
"integrity": "sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
@@ -5317,7 +5304,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -5433,7 +5419,6 @@
"integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",