Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platforms/marketplace/assets/blabsy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added platforms/marketplace/assets/charter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added platforms/marketplace/assets/eid-w3ds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added platforms/marketplace/assets/evoting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions platforms/marketplace/assets/pictique.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions platforms/marketplace/assets/w3dslogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions platforms/marketplace/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { QueryClientProvider } from "@tanstack/react-query";
import { Toaster } from "@/components/ui/toaster";
import { TooltipProvider } from "@/components/ui/tooltip";
import { AuthProvider } from "@/hooks/use-auth";
import { ProtectedRoute } from "@/lib/protected-route";
import HomePage from "@/pages/home-page";
import AppDetailPage from "@/pages/app-detail";
import AdminDashboard from "@/pages/admin-dashboard";
Expand All @@ -16,7 +15,7 @@ function Router() {
<Switch>
<Route path="/" component={HomePage} />
<Route path="/app/:id" component={AppDetailPage} />
<ProtectedRoute path="/admin" component={AdminDashboard} />
<Route path="/admin" component={AdminDashboard} />
<Route path="/admin/auth" component={AuthPage} />
<Route component={NotFound} />
</Switch>
Expand Down
56 changes: 9 additions & 47 deletions platforms/marketplace/client/src/components/ObjectUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,29 @@
import { useState } from "react";
import type { ReactNode } from "react";
import Uppy from "@uppy/core";
import { DashboardModal } from "@uppy/react";
import "@uppy/core/dist/style.min.css";
import "@uppy/dashboard/dist/style.min.css";
import AwsS3 from "@uppy/aws-s3";
import type { UploadResult } from "@uppy/core";
import { Button } from "@/components/ui/button";

interface ObjectUploaderProps {
maxNumberOfFiles?: number;
maxFileSize?: number;
onGetUploadParameters: () => Promise<{
onGetUploadParameters?: () => Promise<{
method: "PUT";
url: string;
}>;
onComplete?: (
result: UploadResult<Record<string, unknown>, Record<string, unknown>>
) => void;
onComplete?: (result: any) => void;
buttonClassName?: string;
children: ReactNode;
}

export function ObjectUploader({
maxNumberOfFiles = 1,
maxFileSize = 10485760, // 10MB default
onGetUploadParameters,
onComplete,
buttonClassName,
children,
}: ObjectUploaderProps) {
const [showModal, setShowModal] = useState(false);
const [uppy] = useState(() =>
new Uppy({
restrictions: {
maxNumberOfFiles,
maxFileSize,
allowedFileTypes: ['image/*'],
},
autoProceed: false,
})
.use(AwsS3, {
shouldUseMultipart: false,
getUploadParameters: onGetUploadParameters,
})
.on("complete", (result) => {
onComplete?.(result);
setShowModal(false);
})
);

return (
<div>
<Button onClick={() => setShowModal(true)} className={buttonClassName} type="button">
{children}
</Button>

<DashboardModal
uppy={uppy}
open={showModal}
onRequestClose={() => setShowModal(false)}
proudlyDisplayPoweredByUppy={false}
/>
</div>
<Button
onClick={() => alert('Upload functionality requires backend database')}
className={buttonClassName}
type="button"
>
{children}
</Button>
);
}
51 changes: 51 additions & 0 deletions platforms/marketplace/client/src/data/apps.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[
{
"id": "eid-wallet",
"name": "eID for W3DS",
"description": "Secure digital identity wallet for W3DS. Maintain sovereign control over your digital identity.",
"category": "Identity",
"logoUrl": "/eid-w3ds.png",
"appStoreUrl": "https://apps.apple.com/in/app/eid-for-w3ds/id6747748667",
"playStoreUrl": "https://play.google.com/store/apps/details?id=foundation.metastate.eid_wallet"
},
{
"id": "blabsy",
"name": "Blabsy",
"description": "Micro blogging first style application for sharing thoughts across the W3DS ecosystem.",
"category": "Social",
"logoUrl": "/blabsy.svg",
"url": "https://blabsy.w3ds.metastate.foundation"
},
{
"id": "pictique",
"name": "Pictique",
"description": "Photo sharing first style application for sharing moments across the W3DS ecosystem.",
"category": "Social",
"logoUrl": "/pictique.svg",
"url": "https://pictique.w3ds.metastate.foundation"
},
{
"id": "evoting",
"name": "eVoting",
"description": "Secure, transparent, and verifiable electronic voting platform with cryptographic guarantees.",
"category": "Governance",
"logoUrl": "/evoting.png",
"url": "https://evoting.w3ds.metastate.foundation"
},
{
"id": "group-charter",
"name": "Charter Manager",
"description": "Define rules, manage memberships, and ensure transparent governance for your communities.",
"category": "Governance",
"logoUrl": "/charter.png",
"url": "https://charter.w3ds.metastate.foundation"
},
{
"id": "dreamsync",
"name": "DreamSync",
"description": "Individual discovery platform, find people of interest across the W3DS ecosystem.",
"category": "Wellness",
"logoUrl": null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify null logoUrl is handled gracefully.

The DreamSync app has logoUrl: null. Ensure all components that render app logos handle null values correctly (e.g., showing a fallback icon or placeholder).

Run this script to check logo rendering logic:


🏁 Script executed:

#!/bin/bash
# Search for logo rendering code
echo "Checking logo rendering logic:"
rg -n 'logoUrl|app\.logo' --type=tsx --type=ts platforms/marketplace/client/src/ -C 3

Length of output: 58


🏁 Script executed:

#!/bin/bash
echo "Re-checking logo rendering logic by matching file extensions directly:"
rg -n 'logoUrl|app\.logo' -g '*.tsx' -g '*.ts' platforms/marketplace/client/src/ -C 3

Length of output: 7185


Add fallback UI for null logoUrl

  • In home-page.tsx (around line 119) and app-detail.tsx (around line 73), the {app.logoUrl ? <img …/> : null} branches render nothing when logoUrl is null. Provide a default icon or placeholder in the “else” branch.
🤖 Prompt for AI Agents
In platforms/marketplace/client/src/data/apps.json around line 48 and in the
components home-page.tsx (≈line 119) and app-detail.tsx (≈line 73), the UI
renders nothing when app.logoUrl is null; update those components to render a
consistent fallback (e.g., a default SVG/icon component or styled placeholder
div with accessible alt/title) in the else branch instead of null, ensure the
placeholder respects existing sizing/CSS and includes an aria-label or alt text
for accessibility; keep the conditional as {app.logoUrl ? <img .../> :
<PlaceholderIcon />} and import or create a small reusable PlaceholderIcon
component so both files use the same fallback.

"url": "https://dreamsync.w3ds.metastate.foundation"
}
]
Loading
Loading