diff --git a/README.md b/README.md index c38d313..d16311e 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,8 @@ with a direct call to action to the [submission guide](./CONTRIBUTING.md). | Path | Purpose | | --- | --- | -| `src/pages/index.astro` | Storefront (search, filters, cards, detail drawer) | +| `src/pages/index.astro` | Storefront (search, filters, cards); `?ext=`/`?id=` redirect to the detail page | +| `src/pages/plugin/[id].astro` | Server-rendered plugin details (README, routes, install, manifest) | | `src/pages/dashboard.astro` | Signed-in publisher dashboard (create + list publishers) | | `src/pages/dashboard/settings.astro` | Account settings (display name + avatar upload) | | `src/pages/dashboard/publisher/[id].astro` | Owner-only publisher profile editor | @@ -47,7 +48,7 @@ with a direct call to action to the [submission guide](./CONTRIBUTING.md). | `src/pages/api/user/profile.ts` | `PATCH` the signed-in user's display name + avatar | | `src/pages/api/publishers/create.ts` | Creates a publisher owned by the signed-in user | | `src/pages/api/publishers/[id].ts` | `GET` a publisher profile + stats; `PATCH` the owner's branding | -| `src/components/` | `Navbar`, `Card`, `DetailDrawer`, `CategoryFilter`, `Icon`, `ImageField` | +| `src/components/` | `Navbar`, `Card`, `CategoryFilter`, `Icon`, `ImageField` | | `src/lib/db.ts` | Typed D1 access layer for the catalog | | `src/lib/session.ts` | HMAC-signed session token (sign/verify) | | `src/lib/auth.ts` | Session helpers shared by pages and API routes | diff --git a/src/components/Card.astro b/src/components/Card.astro index 7722262..d18b0b8 100644 --- a/src/components/Card.astro +++ b/src/components/Card.astro @@ -42,7 +42,14 @@ const cli = `openrom-core --install-plugin ${plugin.id}`;
-

{plugin.name}

+

+ + {plugin.name} + +

{ plugin.publisherVerified && ( @@ -54,7 +61,7 @@ const cli = `openrom-core --install-plugin ${plugin.id}`; plugin.publisherId ? ( {plugin.publisherName} @@ -106,7 +113,7 @@ const cli = `openrom-core --install-plugin ${plugin.id}`;
-
+
- + { published ? ( `openrom-core --install-plugin ${id}`; - -function manifestFor(plugin: Plugin) { - return { - id: plugin.id, - name: plugin.name, - version: plugin.version, - min_core_version: plugin.minCoreVersion, - publisher: { name: plugin.publisherName, verified: plugin.publisherVerified }, - category: plugin.category, - description: plugin.description, - routes: plugin.routes, - platforms: plugin.platforms, - download_url: plugin.downloadUrl, - sha256: plugin.sha256 || null, - icon: plugin.icon, - downloads: plugin.downloads, - created_at: plugin.createdAt, - }; -} ---- - - - - -{ - plugins.map((plugin) => { - const published = Boolean(plugin.sha256); - const readmeHtml = - renderMarkdown(plugin.readme) || - '

No README has been published for this extension yet.

'; - - return ( - - ); - }) -} - - - diff --git a/src/components/Icon.astro b/src/components/Icon.astro index 7e124ed..0f86e9a 100644 --- a/src/components/Icon.astro +++ b/src/components/Icon.astro @@ -30,6 +30,7 @@ const ICONS: Record = { cpu: '', sparkles: '', + zap: '', monitor: '', terminal: '', apple: '', diff --git a/src/pages/index.astro b/src/pages/index.astro index 6700ac8..0764512 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -2,13 +2,20 @@ import Layout from '../layouts/Layout.astro'; import CategoryFilter from '../components/CategoryFilter.astro'; import Card from '../components/Card.astro'; -import DetailDrawer from '../components/DetailDrawer.astro'; import Icon from '../components/Icon.astro'; import { getDB, listPlugins, type Plugin } from '../lib/db'; import { EMPTY_STATE, SITE, orderCategories } from '../lib/site'; export const prerender = false; +// Plugin details used to open in a client-side drawer keyed by ?ext=/?id=. Those +// deep links now belong to the dedicated /plugin/[id] page, so send them there +// instead of rendering the catalog with a query nothing acts on. +const legacyId = Astro.url.searchParams.get('ext') ?? Astro.url.searchParams.get('id'); +if (legacyId) { + return Astro.redirect(`/plugin/${encodeURIComponent(legacyId)}`, 301); +} + let plugins: Plugin[] = []; let dbError: string | null = null; try { @@ -136,8 +143,6 @@ const total = plugins.length; ) } - - + ) : ( +
+ + + Back to Marketplace + + + {/* Hero */} +
+
+ + + + +
+
+

{plugin.name}

+ + v{plugin.version} + + + {plugin.category} + +
+ +

+ by + {plugin.publisherId ? ( + + {plugin.publisherName} + {plugin.publisherVerified && ( + + )} + + ) : ( + + {plugin.publisherName} + {plugin.publisherVerified && ( + + )} + + )} + + min core {plugin.minCoreVersion} +

+ +

+ {plugin.description} +

+
+
+ + {/* Actions */} +
+ {published ? ( + + + Install in OpenROM + + ) : ( + + + Bundle not published yet + + )} + + {published && ( + + + Download .orplug + + )} + + +
+ + { + published && ( +

+ One-click install needs OpenROM Core installed. If nothing happens, use{' '} + + the .orplug download + {' '} + or the CLI command above. +

+ ) + } + + {/* Quick facts */} +
+
+ + {plugin.downloads.toLocaleString()} + downloads +
+
+ {plugin.platforms.map((platform) => ( + + + {platform} + + ))} +
+
+
+ +
+ {/* Main column */} +
+
+

Overview

+
+
+ +
+

+ Supported Routes +

+ {plugin.routes.length > 0 ? ( +
+ {plugin.routes.map((route) => ( + + + {route.replace(/\s*->\s*/, ' ➔ ')} + + ))} +
+ ) : ( +

No conversion routes declared.

+ )} +
+ +
+

+ Installation +

+ +
+

Command line

+

+ Install with OpenROM Core. This fetches the bundle and verifies its SHA-256 + before installing. +

+
+ {cli} + +
+
+ +
+

Desktop app

+
    +
  1. + 1. + + Download the .orplug bundle + above. + +
  2. +
  3. + 2. + + Drag the file onto the OpenROM window, or use Install from file…. + +
  4. +
  5. + 3. + OpenROM checks the checksum and installs it automatically. +
  6. +
+
+
+
+ + {/* Sidebar */} + +
+
+ + ) + } + diff --git a/src/pages/publisher/[id].astro b/src/pages/publisher/[id].astro index 79638e1..233adad 100644 --- a/src/pages/publisher/[id].astro +++ b/src/pages/publisher/[id].astro @@ -1,7 +1,6 @@ --- import Layout from '../../layouts/Layout.astro'; import Card from '../../components/Card.astro'; -import DetailDrawer from '../../components/DetailDrawer.astro'; import Icon from '../../components/Icon.astro'; import { getDB } from '../../lib/db'; import { loadPublisherProfile } from '../../lib/publisher-profile'; @@ -270,5 +269,4 @@ const fallbackBody = dbError ) } - {publisher && } diff --git a/src/styles/global.css b/src/styles/global.css index 540e612..9c772f1 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -88,14 +88,6 @@ body { margin: 1em 0; } -/* Details drawer transitions. */ -[data-drawer] { - transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1), opacity 200ms ease; -} -[data-drawer-backdrop] { - transition: opacity 200ms ease; -} - ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: #09090b; } ::-webkit-scrollbar-thumb { background: #27272a; border-radius: 999px; }