From ee6be5c959fe243f53d8465b2a3e5cb667aaf8fe Mon Sep 17 00:00:00 2001 From: Sophie <47993817+sdankel@users.noreply.github.com> Date: Wed, 16 Apr 2025 21:57:44 -0700 Subject: [PATCH 01/10] add theme --- app/src/App.tsx | 75 +++++++--- .../components/PackageDashboard.css | 0 .../components/PackageDashboard.tsx | 0 .../hooks/useFetchRecentPackages.ts | 0 app/src/pages/Home.tsx | 2 +- app/src/theme/theme.ts | 129 ++++++++++++++++++ app/src/utils/http.ts | 2 +- 7 files changed, 187 insertions(+), 21 deletions(-) rename app/src/features/{dahboard => dashboard}/components/PackageDashboard.css (100%) rename app/src/features/{dahboard => dashboard}/components/PackageDashboard.tsx (100%) rename app/src/features/{dahboard => dashboard}/hooks/useFetchRecentPackages.ts (100%) create mode 100644 app/src/theme/theme.ts diff --git a/app/src/App.tsx b/app/src/App.tsx index 2ae08a6..1fc7124 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,13 +1,11 @@ import React, { ReactNode } from "react"; -import AppBar from "@mui/material/AppBar/AppBar"; -import Toolbar from "@mui/material/Toolbar/Toolbar"; +import { ThemeProvider } from "@mui/material/styles"; +import { AppBar, Toolbar, Box } from "@mui/material"; import { useNavigate } from "react-router-dom"; import UserButton from "./features/toolbar/components/UserButton"; import { useIsMobile } from "./features/toolbar/hooks/useIsMobile"; import SearchBar from "./features/toolbar/components/SearchBar"; -import "./App.css"; - -export const FUEL_GREEN = "#00f58c"; +import theme from "./theme/theme"; interface AppProps { children?: ReactNode; @@ -18,20 +16,59 @@ function App({ children }: AppProps) { const isMobile = useIsMobile(); return ( -
- - -
navigate("/")}> - forc.pub -
- - {!isMobile && } - -
- {isMobile && } -
-
{children}
-
+ + + + + navigate("/")} + sx={{ + cursor: 'pointer', + fontSize: '1.5rem', + fontWeight: 'bold', + color: 'text.primary', + '&:hover': { + opacity: 0.8, + }, + transition: 'opacity 0.2s ease-in-out', + }} + > + forc.pub + + {!isMobile && } + + + {isMobile && } + + + {children} + + + ); } diff --git a/app/src/features/dahboard/components/PackageDashboard.css b/app/src/features/dashboard/components/PackageDashboard.css similarity index 100% rename from app/src/features/dahboard/components/PackageDashboard.css rename to app/src/features/dashboard/components/PackageDashboard.css diff --git a/app/src/features/dahboard/components/PackageDashboard.tsx b/app/src/features/dashboard/components/PackageDashboard.tsx similarity index 100% rename from app/src/features/dahboard/components/PackageDashboard.tsx rename to app/src/features/dashboard/components/PackageDashboard.tsx diff --git a/app/src/features/dahboard/hooks/useFetchRecentPackages.ts b/app/src/features/dashboard/hooks/useFetchRecentPackages.ts similarity index 100% rename from app/src/features/dahboard/hooks/useFetchRecentPackages.ts rename to app/src/features/dashboard/hooks/useFetchRecentPackages.ts diff --git a/app/src/pages/Home.tsx b/app/src/pages/Home.tsx index d799582..46302f2 100644 --- a/app/src/pages/Home.tsx +++ b/app/src/pages/Home.tsx @@ -1,5 +1,5 @@ import React from "react"; -import PackageDashboard from "../features/dahboard/components/PackageDashboard"; +import PackageDashboard from "../features/dashboard/components/PackageDashboard"; import "./Home.css"; function Home() { diff --git a/app/src/theme/theme.ts b/app/src/theme/theme.ts new file mode 100644 index 0000000..10a9b7d --- /dev/null +++ b/app/src/theme/theme.ts @@ -0,0 +1,129 @@ +import { createTheme } from '@mui/material/styles'; + +const theme = createTheme({ + palette: { + mode: 'dark', + primary: { + main: '#00f58c', // FUEL_GREEN + light: '#33f7a3', + dark: '#00ab62', + contrastText: '#000000', + }, + secondary: { + main: '#2196f3', // Blue + light: '#4dabf5', + dark: '#1769aa', + contrastText: '#ffffff', + }, + background: { + default: '#1e1e1e', // Dark background + paper: '#2a2a2a', // Card background + }, + text: { + primary: '#e0e0e0', + secondary: '#c4c4c4', + }, + divider: 'rgba(255, 255, 255, 0.12)', + }, + typography: { + fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif', + h1: { + fontSize: '2.5rem', + fontWeight: 600, + }, + h2: { + fontSize: '2rem', + fontWeight: 600, + }, + h3: { + fontSize: '1.75rem', + fontWeight: 600, + }, + h4: { + fontSize: '1.5rem', + fontWeight: 600, + }, + h5: { + fontSize: '1.25rem', + fontWeight: 600, + }, + h6: { + fontSize: '1rem', + fontWeight: 600, + }, + body1: { + fontSize: '1rem', + lineHeight: 1.5, + }, + body2: { + fontSize: '0.875rem', + lineHeight: 1.43, + }, + }, + shape: { + borderRadius: 8, + }, + spacing: 8, // Base spacing unit in pixels + components: { + MuiButton: { + styleOverrides: { + root: { + textTransform: 'none', + borderRadius: 8, + padding: '8px 16px', + }, + contained: { + boxShadow: 'none', + '&:hover': { + boxShadow: '0 2px 4px rgba(0,0,0,0.2)', + }, + }, + }, + }, + MuiCard: { + styleOverrides: { + root: { + backgroundColor: '#2a2a2a', + borderRadius: 12, + border: '1px solid rgba(255, 255, 255, 0.12)', + transition: 'all 0.2s ease-in-out', + '&:hover': { + transform: 'translateY(-2px)', + boxShadow: '0 4px 12px rgba(0,0,0,0.2)', + }, + }, + }, + }, + MuiAppBar: { + styleOverrides: { + root: { + backgroundColor: '#181818', + boxShadow: '0 2px 8px rgba(0,0,0,0.3)', + }, + }, + }, + MuiToolbar: { + styleOverrides: { + root: { + padding: '16px 24px', + '@media (min-width: 600px)': { + padding: '16px 24px', + }, + }, + }, + }, + MuiInputBase: { + styleOverrides: { + root: { + backgroundColor: '#2a2a2a', + borderRadius: 8, + '&.Mui-focused': { + backgroundColor: '#333333', + }, + }, + }, + }, + }, +}); + +export default theme; diff --git a/app/src/utils/http.ts b/app/src/utils/http.ts index 04a690a..c1cb1cf 100644 --- a/app/src/utils/http.ts +++ b/app/src/utils/http.ts @@ -1,7 +1,7 @@ import type { TypedAxios } from "typed-axios-instance"; import axios from "axios"; import { SERVER_URI } from "../constants"; -import { RecentPackagesResponse } from "../features/dahboard/hooks/useFetchRecentPackages"; +import { RecentPackagesResponse } from "../features/dashboard/hooks/useFetchRecentPackages"; import { FullPackage } from "../features/detail/hooks/usePackageDetail"; export interface AuthenticatedUser { From ddbc0c685b72359b49b1aeb73a3a56b925045451 Mon Sep 17 00:00:00 2001 From: Sophie <47993817+sdankel@users.noreply.github.com> Date: Wed, 16 Apr 2025 22:27:18 -0700 Subject: [PATCH 02/10] CSS cleanup --- app/package-lock.json | 41 +++++++-- app/package.json | 3 - app/public/index.html | 2 +- app/src/App.css | 20 ++--- app/src/App.tsx | 55 +++++++----- .../dashboard/components/PackageDashboard.css | 36 ++++---- .../detail/components/PackageDetail.css | 68 +++++++-------- .../detail/components/PackageSidebar.css | 64 +++++++------- .../tokens/components/CopyableToken.css | 6 +- .../features/toolbar/components/SearchBar.css | 10 +-- .../features/toolbar/components/SearchBar.tsx | 2 +- .../toolbar/components/UserButton.css | 23 +++-- .../toolbar/components/UserButton.tsx | 14 +--- app/src/pages/ApiTokens.css | 27 ++---- app/src/pages/ApiTokens.tsx | 3 - app/src/pages/Home.css | 16 ++-- app/src/theme/theme.ts | 83 +++++++++---------- 17 files changed, 246 insertions(+), 227 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index 19d4988..fe4df2a 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -8,9 +8,6 @@ "name": "app", "version": "0.1.0", "dependencies": { - "@emotion/react": "^11.11.0", - "@emotion/styled": "^11.11.0", - "@mui/base": "^5.0.0-beta.40", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", "@testing-library/jest-dom": "^5.17.0", @@ -2310,6 +2307,8 @@ "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "optional": true, + "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", @@ -2327,12 +2326,16 @@ "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "optional": true, + "peer": true }, "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -2344,6 +2347,8 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -2363,12 +2368,16 @@ "node_modules/@emotion/hash": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==", + "optional": true, + "peer": true }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "optional": true, + "peer": true, "dependencies": { "@emotion/memoize": "^0.8.1" } @@ -2382,6 +2391,8 @@ "version": "11.11.4", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "optional": true, + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -2405,6 +2416,8 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "optional": true, + "peer": true, "dependencies": { "@emotion/hash": "^0.9.1", "@emotion/memoize": "^0.8.1", @@ -2422,6 +2435,8 @@ "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "optional": true, + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -2443,12 +2458,16 @@ "node_modules/@emotion/unitless": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "optional": true, + "peer": true }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "optional": true, + "peer": true, "peerDependencies": { "react": ">=16.8.0" } @@ -8997,7 +9016,9 @@ "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "optional": true, + "peer": true }, "node_modules/find-up": { "version": "5.0.0", @@ -9705,6 +9726,8 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "optional": true, + "peer": true, "dependencies": { "react-is": "^16.7.0" } @@ -9712,7 +9735,9 @@ "node_modules/hoist-non-react-statics/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "optional": true, + "peer": true }, "node_modules/hoopy": { "version": "0.1.4", diff --git a/app/package.json b/app/package.json index 5243aff..c564d67 100644 --- a/app/package.json +++ b/app/package.json @@ -3,9 +3,6 @@ "version": "0.1.0", "private": true, "dependencies": { - "@emotion/react": "^11.11.0", - "@emotion/styled": "^11.11.0", - "@mui/base": "^5.0.0-beta.40", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", "@testing-library/jest-dom": "^5.17.0", diff --git a/app/public/index.html b/app/public/index.html index aa069f2..e65acb3 100644 --- a/app/public/index.html +++ b/app/public/index.html @@ -1,4 +1,4 @@ - + diff --git a/app/src/App.css b/app/src/App.css index ba2ab37..3704068 100644 --- a/app/src/App.css +++ b/app/src/App.css @@ -11,7 +11,7 @@ } .app-toolbar { - background-color: #181818 !important; + background-color: #181818; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } @@ -46,28 +46,28 @@ body { /* Button overrides */ .MuiButton-containedPrimary { - background-color: #0d47a1 !important; - color: #ffffff !important; + background-color: #0d47a1; + color: #ffffff; } .MuiButton-containedPrimary:hover { - background-color: #1565c0 !important; + background-color: #1565c0; } .MuiButton-containedSecondary { - background-color: #00f58c !important; - color: #111111 !important; + background-color: #00f58c; + color: #111111; } .MuiButton-containedSecondary:hover { - background-color: #2dffa0 !important; + background-color: #2dffa0; } .MuiButton-containedWarning { - background-color: #bf360c !important; - color: #ffffff !important; + background-color: #bf360c; + color: #ffffff; } .MuiButton-containedWarning:hover { - background-color: #e64a19 !important; + background-color: #e64a19; } diff --git a/app/src/App.tsx b/app/src/App.tsx index 1fc7124..d0b004e 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -19,33 +19,43 @@ function App({ children }: AppProps) { navigate("/")} sx={{ - cursor: 'pointer', - fontSize: '1.5rem', - fontWeight: 'bold', - color: 'text.primary', - '&:hover': { - opacity: 0.8, + flexGrow: 1, + display: "block", + color: theme.palette.primary.main, + fontSize: "24px", + fontFamily: "monospace", + cursor: "pointer", + fontWeight: "bold", + transition: "color 0.2s ease-in-out", + "&:hover": { + color: theme.palette.primary.light, }, - transition: 'opacity 0.2s ease-in-out', }} > forc.pub @@ -58,11 +68,14 @@ function App({ children }: AppProps) { {children} diff --git a/app/src/features/dashboard/components/PackageDashboard.css b/app/src/features/dashboard/components/PackageDashboard.css index f24dcd1..03a9333 100644 --- a/app/src/features/dashboard/components/PackageDashboard.css +++ b/app/src/features/dashboard/components/PackageDashboard.css @@ -4,55 +4,55 @@ } .section-title { - border-bottom: 2px solid #90caf9 !important; - padding-bottom: 8px !important; - color: #ffffff !important; - font-weight: 500 !important; + border-bottom: 2px solid #90caf9; + padding-bottom: 8px; + color: #ffffff; + font-weight: 500; } .package-card { margin-bottom: 16px; border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3) !important; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); cursor: pointer; transition: transform 0.2s, background-color 0.2s; - background-color: #2a2a2a !important; - border: 1px solid #333 !important; + background-color: #2a2a2a; + border: 1px solid #333; } .package-card-hover { - background-color: #383838 !important; + background-color: #383838; transform: translateY(-2px); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4) !important; + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4); } .card-content { display: flex; align-items: center; justify-content: space-between; - background-color: transparent !important; + background-color: transparent; } .package-name { - color: #90caf9 !important; - margin-bottom: 8px !important; + color: #90caf9; + margin-bottom: 8px; } .package-timestamp { - color: #b0b0b0 !important; - font-size: 0.85rem !important; + color: #b0b0b0; + font-size: 0.85rem; } .package-description { - color: #e0e0e0 !important; - margin-top: 8px !important; + color: #e0e0e0; + margin-top: 8px; } .arrow-icon { - color: #90caf9 !important; + color: #90caf9; margin-left: 16px; align-self: center; - font-size: 1.2rem !important; + font-size: 1.2rem; } diff --git a/app/src/features/detail/components/PackageDetail.css b/app/src/features/detail/components/PackageDetail.css index b61ce12..ae1866c 100644 --- a/app/src/features/detail/components/PackageDetail.css +++ b/app/src/features/detail/components/PackageDetail.css @@ -8,27 +8,27 @@ /* Ensure all MUI components in package detail follow dark theme */ .package-detail-container .MuiPaper-root { - background-color: #2a2a2a !important; - color: #e0e0e0 !important; + background-color: #2a2a2a; + color: #e0e0e0; } .package-detail-container .MuiCard-root { - background-color: #2a2a2a !important; - color: #e0e0e0 !important; - border: 1px solid #333 !important; + background-color: #2a2a2a; + color: #e0e0e0; + border: 1px solid #333; } .package-detail-container .MuiButton-contained { - background-color: #0d47a1 !important; - color: #ffffff !important; + background-color: #0d47a1; + color: #ffffff; } .package-detail-container .MuiButton-contained:hover { - background-color: #1565c0 !important; + background-color: #1565c0; } .package-detail-container .MuiDivider-root { - background-color: #444 !important; + background-color: #444; } /* Make sure all text in the cards is light */ @@ -66,7 +66,7 @@ } .package-tab { - color: #e0e0e0 !important; + color: #e0e0e0; opacity: 0.8; text-transform: none; min-width: 120px; @@ -77,18 +77,18 @@ .package-tab:hover { opacity: 1; - color: #ffffff !important; + color: #ffffff; } /* Style for the active tab */ .package-tabs .Mui-selected { - color: #ffffff !important; + color: #ffffff; opacity: 1; } /* Style for the tab indicator (the line under the active tab) */ .package-tabs .MuiTabs-indicator { - background-color: #2196f3 !important; + background-color: #2196f3; height: 3px; } @@ -96,36 +96,36 @@ margin-bottom: 16px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); - background-color: #2a2a2a !important; - border: 1px solid #333 !important; - color: #e0e0e0 !important; + background-color: #2a2a2a; + border: 1px solid #333; + color: #e0e0e0; } /* Override MUI styles for dark mode */ .card-dark .MuiPaper-root { - background-color: #2a2a2a !important; - color: #e0e0e0 !important; + background-color: #2a2a2a; + color: #e0e0e0; } .card-dark .MuiCardContent-root { - background-color: #2a2a2a !important; + background-color: #2a2a2a; } .card-dark .MuiTypography-root { - color: #e0e0e0 !important; + color: #e0e0e0; } .card-dark .MuiDivider-root { - background-color: #444 !important; + background-color: #444; } .card-dark .MuiListItemText-secondary { - color: #b0b0b0 !important; + color: #b0b0b0; } .card-dark .MuiChip-root { - background-color: #3a3a3a !important; - color: #e0e0e0 !important; + background-color: #3a3a3a; + color: #e0e0e0; } .card-content { @@ -223,27 +223,27 @@ } .alert-dark { - background-color: rgba(30, 70, 100, 0.2) !important; - color: #90caf9 !important; - border-color: #2a5d8a !important; + background-color: rgba(30, 70, 100, 0.2); + color: #90caf9; + border-color: #2a5d8a; } .alert-dark .MuiAlert-icon { - color: #90caf9 !important; + color: #90caf9; } .package-detail-container .MuiAlert-root { - background-color: rgba(30, 70, 100, 0.2) !important; - color: #90caf9 !important; - border-color: #2a5d8a !important; + background-color: rgba(30, 70, 100, 0.2); + color: #90caf9; + border-color: #2a5d8a; } .package-detail-container .MuiAlert-root .MuiAlert-icon { - color: #90caf9 !important; + color: #90caf9; } .package-detail-container .MuiAlert-root .MuiAlert-message { - color: #90caf9 !important; + color: #90caf9; } .download-section { @@ -320,7 +320,7 @@ } .section-divider { - margin: 16px 0 !important; + margin: 16px 0; } .sidebar-link-item { diff --git a/app/src/features/detail/components/PackageSidebar.css b/app/src/features/detail/components/PackageSidebar.css index 2a49aca..069770b 100644 --- a/app/src/features/detail/components/PackageSidebar.css +++ b/app/src/features/detail/components/PackageSidebar.css @@ -1,11 +1,11 @@ /* Dark mode styles for Package Sidebar */ .sidebar-card { margin-top: 0; - background-color: #2a2a2a !important; - color: #e0e0e0 !important; - border: none !important; - border-radius: 12px !important; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2) !important; + background-color: #2a2a2a; + color: #e0e0e0; + border: none; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); } .sidebar-card .MuiCardContent-root { @@ -29,38 +29,38 @@ .sidebar-section-heading { text-transform: uppercase; letter-spacing: 0.5px; - font-size: 0.9rem !important; - color: #aaa !important; - font-weight: 500 !important; - margin-top: 10px !important; - margin-bottom: 8px !important; - border: none !important; - padding: 0 !important; - background: none !important; - position: relative !important; - display: block !important; + font-size: 0.9rem; + color: #aaa; + font-weight: 500; + margin-top: 10px; + margin-bottom: 8px; + border: none; + padding: 0; + background: none; + position: relative; + display: block; } /* Explicitly ensure no decorations or pseudo-elements */ .sidebar-section-heading:after, .sidebar-section-heading:before { - content: none !important; - display: none !important; - border: none !important; - height: 0 !important; - width: 0 !important; - position: static !important; + content: none; + display: none; + border: none; + height: 0; + width: 0; + position: static; } /* Explicitly remove any dividers or borders */ .sidebar-card .MuiDivider-root { - display: none !important; + display: none; } .sidebar-link-item { margin-bottom: 16px; padding-bottom: 16px; - border-bottom: none !important; + border-bottom: none; } .sidebar-list { @@ -78,17 +78,17 @@ } .link-light { - color: #c0c0c0 !important; - text-decoration: none !important; + color: #c0c0c0; + text-decoration: none; word-break: break-word; opacity: 0.9; transition: all 0.2s ease; } .link-light:hover { - color: #ffffff !important; + color: #ffffff; opacity: 1; - text-decoration: underline !important; + text-decoration: underline; } .link-block { @@ -99,15 +99,15 @@ /* Override MUI styles for dark mode */ .sidebar-card .MuiTypography-root { - color: #e0e0e0 !important; + color: #e0e0e0; } .sidebar-card .MuiAlert-root { - background-color: rgba(60, 60, 60, 0.2) !important; - color: #e0e0e0 !important; - border: none !important; + background-color: rgba(60, 60, 60, 0.2); + color: #e0e0e0; + border: none; } .sidebar-card .MuiAlert-icon { - color: #e0e0e0 !important; + color: #e0e0e0; } diff --git a/app/src/features/tokens/components/CopyableToken.css b/app/src/features/tokens/components/CopyableToken.css index d6458c4..08aa925 100644 --- a/app/src/features/tokens/components/CopyableToken.css +++ b/app/src/features/tokens/components/CopyableToken.css @@ -30,12 +30,12 @@ } .copy-button { - color: #e0e0e0 !important; + color: #e0e0e0; } .copy-button:hover { - color: #ffffff !important; - background-color: rgba(255, 255, 255, 0.1) !important; + color: #ffffff; + background-color: rgba(255, 255, 255, 0.1); } .copy-button svg { diff --git a/app/src/features/toolbar/components/SearchBar.css b/app/src/features/toolbar/components/SearchBar.css index 0763aaa..be676d0 100644 --- a/app/src/features/toolbar/components/SearchBar.css +++ b/app/src/features/toolbar/components/SearchBar.css @@ -18,7 +18,6 @@ height: 100%; background-color: #333333; color: #e0e0e0; - border-radius: 4px; padding: 2px 4px; } @@ -27,17 +26,18 @@ .search-input:-moz-placeholder, .search-input::-moz-placeholder, .search-input:-ms-input-placeholder { - color: #c0c0c0 !important; - opacity: 1 !important; + color: #c0c0c0; + opacity: 1; } /* Target the actual input element within MUI Input */ .search-input input::placeholder { - color: #c0c0c0 !important; - opacity: 1 !important; + color: #c0c0c0; + opacity: 1; } .search-icon { color: #c0c0c0; margin-left: 10px; + margin-right: 10px; } diff --git a/app/src/features/toolbar/components/SearchBar.tsx b/app/src/features/toolbar/components/SearchBar.tsx index 16ca205..78f6324 100644 --- a/app/src/features/toolbar/components/SearchBar.tsx +++ b/app/src/features/toolbar/components/SearchBar.tsx @@ -30,7 +30,7 @@ function SearchBar() { className="search-input" startAdornment={ - + } placeholder="Search packages and plugins" diff --git a/app/src/features/toolbar/components/UserButton.css b/app/src/features/toolbar/components/UserButton.css index eae32bc..44bcf59 100644 --- a/app/src/features/toolbar/components/UserButton.css +++ b/app/src/features/toolbar/components/UserButton.css @@ -16,23 +16,23 @@ } .user-button:hover { - background-color: rgba(255, 255, 255, 0.1) !important; + background-color: rgba(255, 255, 255, 0.1); } /* Menu styling */ .menu-paper { - background-color: #2a2a2a !important; - color: #e0e0e0 !important; - border: 1px solid #444 !important; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important; + background-color: #2a2a2a; + color: #e0e0e0; + border: 1px solid #444; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); } .menu-item { - color: #e0e0e0 !important; + color: #e0e0e0; } .menu-item:hover { - background-color: #3a3a3a !important; + background-color: #3a3a3a; } /* Login button styling */ @@ -40,11 +40,11 @@ transition: all 0.2s ease; display: flex; align-items: center; - color: #e0e0e0 !important; + color: #e0e0e0; } .login-button:hover { - background-color: rgba(255, 255, 255, 0.1) !important; + background-color: rgba(255, 255, 255, 0.1); } .login-icon { @@ -55,3 +55,8 @@ margin-left: 10px; color: #e0e0e0; } + +.button-wrapper { + text-wrap: nowrap; + color: inherit; +} diff --git a/app/src/features/toolbar/components/UserButton.tsx b/app/src/features/toolbar/components/UserButton.tsx index f981864..64a1a27 100644 --- a/app/src/features/toolbar/components/UserButton.tsx +++ b/app/src/features/toolbar/components/UserButton.tsx @@ -1,7 +1,6 @@ import React, { useCallback } from "react"; import Lock from "@mui/icons-material/Lock"; import Button from "@mui/material/Button/Button"; -import styled from "@emotion/styled"; import Menu from "@mui/material/Menu/Menu"; import MenuItem from "@mui/material/MenuItem/MenuItem"; import { useNavigate } from "react-router-dom"; @@ -12,11 +11,6 @@ import "./UserButton.css"; export const GITHUB_CLIENT_ID = "Iv1.ebdf596c6c548759"; -const StyledWrapper = styled.div` - text-wrap: nowrap; - color: inherit; -`; - function UserButton() { const navigate = useNavigate(); const [user, logout] = useGithubAuth(); @@ -48,7 +42,7 @@ function UserButton() { if (user) { return ( - +
); } return ( - +
-
+ ); } diff --git a/app/src/pages/ApiTokens.css b/app/src/pages/ApiTokens.css index 1fa1304..c9f1bf5 100644 --- a/app/src/pages/ApiTokens.css +++ b/app/src/pages/ApiTokens.css @@ -37,15 +37,6 @@ margin: 0; } -.new-token-button { - background-color: #0d47a1 !important; - color: #ffffff !important; -} - -.new-token-button:hover { - background-color: #1565c0 !important; -} - .tokens-list-container { display: flex; flex-direction: column; @@ -73,35 +64,35 @@ } .token-name-field { - min-width: 50% !important; + min-width: 50%; } /* Override MUI styles for dark mode */ .api-tokens-container .MuiFilledInput-root { - background-color: #2a2a2a !important; + background-color: #2a2a2a; } .api-tokens-container .MuiInputBase-input { - color: #e0e0e0 !important; + color: #e0e0e0; } .api-tokens-container .MuiInputLabel-root { - color: #b0b0b0 !important; + color: #b0b0b0; } .api-tokens-container .MuiFormLabel-root.Mui-focused { - color: #90caf9 !important; + color: #90caf9; } .api-tokens-container .MuiFilledInput-underline:after { - border-bottom-color: #90caf9 !important; + border-bottom-color: #90caf9; } .generate-button { - background-color: #0d47a1 !important; - color: #ffffff !important; + background-color: #0d47a1; + color: #ffffff; } .generate-button:hover { - background-color: #1565c0 !important; + background-color: #1565c0; } diff --git a/app/src/pages/ApiTokens.tsx b/app/src/pages/ApiTokens.tsx index f27c308..27e6293 100644 --- a/app/src/pages/ApiTokens.tsx +++ b/app/src/pages/ApiTokens.tsx @@ -46,12 +46,9 @@ function ApiTokens() {

{"API Tokens"}

-

API Tokens

-
{ + {data.abiIpfsUrl && } {/* Main Content - Left Side (changes with tabs) */} {/* Readme Tab */} - {activeTab === 0 && renderReadmeTab()} + {activeTab === TABS[0] && renderReadmeTab()} {/* Versions Tab */} - {activeTab === 1 && ( + {activeTab === TABS[1] && ( @@ -131,7 +135,7 @@ const PackageDetail: React.FC = () => { )} {/* Dependencies Tab */} - {activeTab === 2 && ( + {activeTab === TABS[2] && ( @@ -151,7 +155,7 @@ const PackageDetail: React.FC = () => { )} {/* Dependents Tab */} - {activeTab === 3 && ( + {activeTab === TABS[3] && ( @@ -171,7 +175,7 @@ const PackageDetail: React.FC = () => { )} {/* Code Tab */} - {activeTab === 4 && ( + {activeTab === TABS[4] && ( @@ -206,18 +210,6 @@ const PackageDetail: React.FC = () => { IPFS: {data.sourceCodeIpfsUrl.split("/").pop()} - {data.abiIpfsUrl && ( -
- - Download ABI (.json) - -
- )}
@@ -227,6 +219,30 @@ const PackageDetail: React.FC = () => { )} + {/* ABI Tab */} + {activeTab === TABS[5] && ( + + + + Application Binary Interface (ABI) + +
+ {data.abiIpfsUrl && ( +
+ + Download ABI (.json) + +
+ )} +
+
+
+ )} {/* Sidebar - Right Side (always visible) */} From b7fc4fa9f0b35803e4c0c12cade33a4fa75b960b Mon Sep 17 00:00:00 2001 From: Sophie <47993817+sdankel@users.noreply.github.com> Date: Thu, 17 Apr 2025 00:11:33 -0700 Subject: [PATCH 04/10] Add ABI viewer and clean up CSS --- app/package-lock.json | 186 ++++++++++++++++++ app/package.json | 1 + .../features/detail/components/AbiContent.tsx | 89 +++++++++ .../detail/components/PackageDetail.css | 6 +- .../detail/components/PackageDetail.tsx | 63 ++++-- .../features/detail/hooks/useAbiContent.ts | 37 ++++ 6 files changed, 358 insertions(+), 24 deletions(-) create mode 100644 app/src/features/detail/components/AbiContent.tsx create mode 100644 app/src/features/detail/hooks/useAbiContent.ts diff --git a/app/package-lock.json b/app/package-lock.json index fe4df2a..07700a6 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -8,6 +8,7 @@ "name": "app", "version": "0.1.0", "dependencies": { + "@microlink/react-json-view": "^1.26.1", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", "@testing-library/jest-dom": "^5.17.0", @@ -17,8 +18,10 @@ "@types/node": "^16.18.91", "@types/react": "^18.2.67", "@types/react-dom": "^18.2.22", + "ace-builds": "^1.40.0", "axios": "^1.6.8", "react": "^18.2.0", + "react-ace": "^14.0.1", "react-dom": "^18.2.0", "react-markdown": "^10.0.1", "react-router-dom": "^6.22.3", @@ -3451,6 +3454,23 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@microlink/react-json-view": { + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/@microlink/react-json-view/-/react-json-view-1.26.1.tgz", + "integrity": "sha512-2H5QCYdZlJi+oN4YBiUYPPFTNh/KLCN9i9yz8NwmSkRqXSRXYtEVIRffc9L34jdopKGK/tK21SeuzXVJHQLkfQ==", + "dependencies": { + "react-base16-styling": "~0.9.0", + "react-lifecycles-compat": "~3.0.4", + "react-textarea-autosize": "~8.5.7" + }, + "engines": { + "node": ">=17" + }, + "peerDependencies": { + "react": ">= 15", + "react-dom": ">= 15" + } + }, "node_modules/@mui/base": { "version": "5.0.0-beta.40", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", @@ -4519,6 +4539,11 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/base16": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.5.tgz", + "integrity": "sha512-OzOWrTluG9cwqidEzC/Q6FAmIPcnZfm8BFRlIx0+UIUqnuAmi5OS88O0RpT3Yz6qdmqObvUhasrbNsCofE4W9A==" + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -4688,6 +4713,11 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/lodash": { + "version": "4.17.16", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", + "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -5259,6 +5289,11 @@ "node": ">= 0.6" } }, + "node_modules/ace-builds": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.40.0.tgz", + "integrity": "sha512-wOCyJfNRsq/yLTR7z2KpwcjaInuUs/mosu/OFLGGUA+g+ApD9OJ1AToHDIp0Xpa2koHJ79bmOya73oWjCNbjlA==" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -6089,6 +6124,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base16": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", + "integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==" + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -6578,6 +6618,15 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -6591,6 +6640,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -7516,6 +7574,11 @@ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, + "node_modules/diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" + }, "node_modules/diff-sequences": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", @@ -13052,11 +13115,28 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.curry": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", + "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead." + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead." + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -16159,6 +16239,22 @@ "node": ">=0.10.0" } }, + "node_modules/react-ace": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-14.0.1.tgz", + "integrity": "sha512-z6YAZ20PNf/FqmYEic//G/UK6uw0rn21g58ASgHJHl9rfE4nITQLqthr9rHMVQK4ezwohJbp2dGrZpkq979PYQ==", + "dependencies": { + "ace-builds": "^1.36.3", + "diff-match-patch": "^1.0.5", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-app-polyfill": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", @@ -16180,6 +16276,20 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, + "node_modules/react-base16-styling": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.9.1.tgz", + "integrity": "sha512-1s0CY1zRBOQ5M3T61wetEpvQmsYSNtWEcdYzyZNxKa8t7oDvaOn9d21xrGezGAHFWLM7SHcktPuPTrvoqxSfKw==", + "dependencies": { + "@babel/runtime": "^7.16.7", + "@types/base16": "^1.0.2", + "@types/lodash": "^4.14.178", + "base16": "^1.0.0", + "color": "^3.2.1", + "csstype": "^3.0.10", + "lodash.curry": "^4.1.1" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -16319,6 +16429,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "node_modules/react-markdown": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.0.1.tgz", @@ -16455,6 +16570,22 @@ } } }, + "node_modules/react-textarea-autosize": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.9.tgz", + "integrity": "sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -17345,6 +17476,19 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -19068,6 +19212,48 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-composed-ref": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz", + "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz", + "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/usehooks-ts": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-3.0.2.tgz", diff --git a/app/package.json b/app/package.json index c564d67..cd8106e 100644 --- a/app/package.json +++ b/app/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@microlink/react-json-view": "^1.26.1", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", "@testing-library/jest-dom": "^5.17.0", diff --git a/app/src/features/detail/components/AbiContent.tsx b/app/src/features/detail/components/AbiContent.tsx new file mode 100644 index 0000000..a737fc8 --- /dev/null +++ b/app/src/features/detail/components/AbiContent.tsx @@ -0,0 +1,89 @@ +import React from "react"; +import { useAbiContent } from "../hooks/useAbiContent"; +import { CircularProgress, Alert, Box } from "@mui/material"; +import ReactJsonView from "@microlink/react-json-view"; +// import AceEditor from 'react-ace'; +// import 'ace-builds/src-noconflict/mode-json'; +// import 'ace-builds/src-noconflict/theme-chrome'; +// import 'ace-builds/src-noconflict/ext-language_tools'; + +interface AbiContentProps { + abiUrl: string; +} + +export const AbiContent: React.FC = ({ abiUrl }) => { + const { abiContent, loading, error } = useAbiContent(abiUrl); + + if (loading) { + return ( + + + + ); + } + + if (error) { + return ( + + Failed to load ABI content: {error.message} + + ); + } + + if (!abiContent) { + return null; + } + + return ( + +
+ + + {/* */} +
+
+ ); +}; diff --git a/app/src/features/detail/components/PackageDetail.css b/app/src/features/detail/components/PackageDetail.css index ae1866c..03d03c4 100644 --- a/app/src/features/detail/components/PackageDetail.css +++ b/app/src/features/detail/components/PackageDetail.css @@ -37,6 +37,7 @@ margin-top: 0; padding-top: 24px; max-width: 1100px; + overflow: auto; } .package-header { @@ -134,6 +135,7 @@ word-wrap: break-word; display: flex; flex-direction: column; + max-height: calc(100vh - 300px); } .card-title { @@ -270,9 +272,7 @@ } .abi-download { - margin-top: 16px; - padding-top: 16px; - border-top: 1px solid #444; + margin: 8px 0 0px; } .link-light { diff --git a/app/src/features/detail/components/PackageDetail.tsx b/app/src/features/detail/components/PackageDetail.tsx index 4e4ead0..fc8fb58 100644 --- a/app/src/features/detail/components/PackageDetail.tsx +++ b/app/src/features/detail/components/PackageDetail.tsx @@ -19,9 +19,23 @@ import usePackageDetail from "../hooks/usePackageDetail"; import ReactMarkdown from "react-markdown"; import "./PackageDetail.css"; import PackageSidebar from "./PackageSidebar"; +import { AbiContent } from "./AbiContent"; -type Tab = "Readme" | "Versions" | "Dependencies" | "Dependents" | "Code" | "ABI"; -const TABS: Tab[] = ["Readme", "Versions", "Dependencies", "Dependents", "Code", "ABI"]; +type Tab = + | "Readme" + | "Versions" + | "Dependencies" + | "Dependents" + | "Code" + | "ABI"; +const TABS: Tab[] = [ + "Readme", + "Versions", + "Dependencies", + "Dependents", + "Code", + "ABI", +]; const PackageDetail: React.FC = () => { const { name, version } = useParams<{ name: string; version?: string }>(); @@ -182,10 +196,6 @@ const PackageDetail: React.FC = () => { Source Code
- - Browse the source code for {data.name}@{data.version}. - -
{ - Full source code including dependencies + Package source code IPFS: {data.sourceCodeIpfsUrl.split("/").pop()} -
@@ -226,20 +235,32 @@ const PackageDetail: React.FC = () => { Application Binary Interface (ABI) -
- {data.abiIpfsUrl && ( -
- - Download ABI (.json) - + + {data.abiIpfsUrl && ( + <> +
+
+ + + +
+
- )} -
+ + )} )} diff --git a/app/src/features/detail/hooks/useAbiContent.ts b/app/src/features/detail/hooks/useAbiContent.ts new file mode 100644 index 0000000..23d6c5e --- /dev/null +++ b/app/src/features/detail/hooks/useAbiContent.ts @@ -0,0 +1,37 @@ +import { useState, useEffect } from "react"; + +interface UseAbiContentResult { + abiContent: any; + loading: boolean; + error: Error | null; +} + +export const useAbiContent = (abiUrl: string | null): UseAbiContentResult => { + const [abiContent, setAbiContent] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchAbi = async () => { + if (!abiUrl) return; + + setLoading(true); + try { + const response = await fetch(abiUrl); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + setAbiContent(data); + } catch (e) { + setError(e instanceof Error ? e : new Error("Failed to fetch ABI")); + } finally { + setLoading(false); + } + }; + + fetchAbi(); + }, [abiUrl]); + + return { abiContent, loading, error }; +}; From 77dddcee36965d1a37e18ba9d62a1fadbd3bf2b5 Mon Sep 17 00:00:00 2001 From: Sophie <47993817+sdankel@users.noreply.github.com> Date: Thu, 17 Apr 2025 00:18:26 -0700 Subject: [PATCH 05/10] lint --- .../detail/components/PackageDetail.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/src/features/detail/components/PackageDetail.tsx b/app/src/features/detail/components/PackageDetail.tsx index fc8fb58..322fa28 100644 --- a/app/src/features/detail/components/PackageDetail.tsx +++ b/app/src/features/detail/components/PackageDetail.tsx @@ -7,7 +7,7 @@ import { Card, CardContent, Tabs, - Tab, + Tab as TabNames, CircularProgress, Alert, Link, @@ -21,14 +21,14 @@ import "./PackageDetail.css"; import PackageSidebar from "./PackageSidebar"; import { AbiContent } from "./AbiContent"; -type Tab = +type TabNames = | "Readme" | "Versions" | "Dependencies" | "Dependents" | "Code" | "ABI"; -const TABS: Tab[] = [ +const TABS: TabNames[] = [ "Readme", "Versions", "Dependencies", @@ -39,7 +39,7 @@ const TABS: Tab[] = [ const PackageDetail: React.FC = () => { const { name, version } = useParams<{ name: string; version?: string }>(); - const [activeTab, setActiveTab] = useState(TABS[0]); + const [activeTab, setActiveTab] = useState(TABS[0]); const { data, loading, error } = usePackageDetail(name!, version); const handleTabChange = (event: React.SyntheticEvent, newValue: number) => { @@ -115,12 +115,12 @@ const PackageDetail: React.FC = () => { variant="scrollable" scrollButtons="auto" > - - - - - - {data.abiIpfsUrl && } + + + + + + {data.abiIpfsUrl && } From 72ad7a1a0976a6325016d2af4cf26ee9ce59c586 Mon Sep 17 00:00:00 2001 From: Sophie <47993817+sdankel@users.noreply.github.com> Date: Thu, 17 Apr 2025 00:20:33 -0700 Subject: [PATCH 06/10] comment cleanup --- app/src/App.tsx | 11 ------- .../features/detail/components/AbiContent.tsx | 29 ------------------- 2 files changed, 40 deletions(-) diff --git a/app/src/App.tsx b/app/src/App.tsx index d0b004e..e0d3179 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -34,12 +34,6 @@ function App({ children }: AppProps) { sx={{ backgroundColor: "#181818", boxShadow: "0 2px 8px rgba(0, 0, 0, 0.3)", - // display: 'flex', - // justifyContent: 'space-between', - // alignItems: 'center', - // gap: 3, - // px: 3, - // minHeight: '64px', }} > {children} diff --git a/app/src/features/detail/components/AbiContent.tsx b/app/src/features/detail/components/AbiContent.tsx index a737fc8..2f90013 100644 --- a/app/src/features/detail/components/AbiContent.tsx +++ b/app/src/features/detail/components/AbiContent.tsx @@ -2,10 +2,6 @@ import React from "react"; import { useAbiContent } from "../hooks/useAbiContent"; import { CircularProgress, Alert, Box } from "@mui/material"; import ReactJsonView from "@microlink/react-json-view"; -// import AceEditor from 'react-ace'; -// import 'ace-builds/src-noconflict/mode-json'; -// import 'ace-builds/src-noconflict/theme-chrome'; -// import 'ace-builds/src-noconflict/ext-language_tools'; interface AbiContentProps { abiUrl: string; @@ -58,31 +54,6 @@ export const AbiContent: React.FC = ({ abiUrl }) => { displayDataTypes={false} enableClipboard={false} /> - - {/* */}
); From fffda30be0f2c90e84ced530cdf62f92f2c26092 Mon Sep 17 00:00:00 2001 From: Sophie <47993817+sdankel@users.noreply.github.com> Date: Thu, 17 Apr 2025 00:23:10 -0700 Subject: [PATCH 07/10] require token name --- app/src/pages/ApiTokens.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/pages/ApiTokens.tsx b/app/src/pages/ApiTokens.tsx index 27e6293..d51b497 100644 --- a/app/src/pages/ApiTokens.tsx +++ b/app/src/pages/ApiTokens.tsx @@ -24,6 +24,7 @@ function ApiTokens() { />