Files
MosisService/DEV_PORTAL_M05_FRONTEND.md

14 KiB

Milestone 5: Developer Portal Frontend

Status: Planning Goal: Web interface for developer account and app management.


Overview

The developer portal is the primary interface for developers to manage their accounts, create apps, submit versions, and view analytics.


Pages Required

Public Pages

Page URL Purpose
Landing / Marketing, sign up CTA
Sign In /login OAuth + password login
Sign Up /register Create account
Docs /docs/* Documentation (separate site?)

Authenticated Pages

Page URL Purpose
Dashboard /dashboard App list, quick stats
App Details /apps/:id Single app overview
App Settings /apps/:id/settings Edit app metadata
App Versions /apps/:id/versions Version history
Submit Version /apps/:id/versions/new Upload new version
App Analytics /apps/:id/analytics Telemetry dashboard
Create App /apps/new New app wizard
API Keys /settings/keys Manage API keys
Signing Keys /settings/signing Manage signing keys
Profile /settings/profile Account settings

Wireframes

Dashboard

┌─────────────────────────────────────────────────────────────┐
│  [Logo]  Dashboard   Apps   Docs   Settings   [Avatar ▼]    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Welcome back, Developer!                                   │
│                                                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │ Total Apps  │  │  Downloads  │  │ Active Users│         │
│  │     12      │  │   45,230    │  │    1,234    │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
│                                                             │
│  Your Apps                                    [+ New App]   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ [Icon] My Calculator    v1.2.0   Published   1.2K ↓  │  │
│  │ [Icon] Notes App        v2.0.1   Published   5.4K ↓  │  │
│  │ [Icon] Weather Widget   v0.9.0   In Review   ---     │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

App Details

┌─────────────────────────────────────────────────────────────┐
│  ← Back to Apps                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [Icon]  My Calculator                                      │
│          com.developer.calculator                           │
│          ● Published                                        │
│                                                             │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │ Overview │ │ Versions │ │Analytics │ │ Settings │       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘       │
│                                                             │
│  Latest Version: 1.2.0                [Submit New Version]  │
│  Published: Jan 15, 2024                                    │
│  Downloads: 1,234                                           │
│                                                             │
│  ┌────────────────────────────────────────┐                │
│  │  Downloads over time                   │                │
│  │  [Chart: line graph]                   │                │
│  └────────────────────────────────────────┘                │
│                                                             │
│  Recent Crashes                           [View All →]      │
│  • attempt to index nil (v1.2.0) - 23 reports              │
│  • memory limit exceeded (v1.1.0) - 5 reports              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Submit Version

┌─────────────────────────────────────────────────────────────┐
│  Submit New Version - My Calculator                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Step 2 of 3: Upload Package                                │
│  ○ Details  ● Upload  ○ Review                              │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                                     │   │
│  │     ┌─────────┐                                     │   │
│  │     │  .mosis │   Drop your package here            │   │
│  │     │   📦    │   or click to browse                │   │
│  │     └─────────┘                                     │   │
│  │                                                     │   │
│  │     Max size: 50 MB                                 │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ✓ Package validated                                        │
│  ✓ Signature verified                                       │
│  ✓ Permissions: storage, network                            │
│                                                             │
│                              [Back]  [Continue to Review]   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Tech Stack Options

Option A: Next.js 14

Framework:  Next.js 14 (App Router)
UI:         shadcn/ui + Tailwind CSS
State:      React Query + Zustand
Forms:      React Hook Form + Zod
Charts:     Recharts or Tremor
Auth:       NextAuth.js
Pros Cons
SSR for SEO landing page Complexity
Great developer experience React knowledge required
Full-stack capability Heavier bundle
Large ecosystem

Option B: SvelteKit

Framework:  SvelteKit
UI:         Skeleton UI or custom
State:      Svelte stores
Forms:      Superforms
Charts:     Chart.js or LayerCake
Auth:       Lucia
Pros Cons
Fast, small bundles Smaller ecosystem
Simple state management Fewer UI libraries
Great DX Less hiring pool

Option C: Astro + React Islands

Framework:  Astro
UI:         React components (islands)
State:      Nanostores
Forms:      React Hook Form
Charts:     Recharts
Auth:       Custom
Pros Cons
Ultra-fast static pages More setup
Partial hydration Newer approach
Use React where needed Less documented patterns

Option D: htmx + Go Templates

Framework:  Go templates + htmx
UI:         Tailwind CSS
State:      Server-side
Forms:      Native HTML
Charts:     Chart.js
Auth:       Server sessions
Pros Cons
Simple, fast Limited interactivity
No JS framework Less polished UX
Server-rendered Complex UI harder

UI Component Library

Option A: shadcn/ui

Base:       Radix UI primitives
Styling:    Tailwind CSS
Approach:   Copy-paste components
Pros Cons
High quality React only
Full control Manual updates
Accessible

Option B: Tailwind UI

Base:       Headless UI
Styling:    Tailwind CSS
Approach:   Copy-paste templates
Pros Cons
Beautiful designs Paid ($299)
Production-ready Templates, not components

Option C: Mantine

Base:       Custom components
Styling:    CSS-in-JS or CSS
Approach:   npm package
Pros Cons
Complete solution Opinionated
Many components Larger bundle
Good docs

Key Features

File Upload

// Drag and drop with progress
<DropZone
  accept=".mosis"
  maxSize={50 * 1024 * 1024}
  onDrop={handleUpload}
  onProgress={setProgress}
>
  <UploadIcon />
  <p>Drop your package here</p>
</DropZone>

Real-time Validation

// Validate package client-side before upload
async function validatePackage(file: File) {
  const zip = await JSZip.loadAsync(file);

  // Check manifest
  const manifest = await zip.file('manifest.json')?.async('text');
  if (!manifest) throw new Error('Missing manifest.json');

  const parsed = JSON.parse(manifest);
  ManifestSchema.parse(parsed);

  // Check required files
  const entry = parsed.entry;
  if (!zip.file(entry)) {
    throw new Error(`Entry file not found: ${entry}`);
  }

  return parsed;
}

Analytics Dashboard

// Recharts example
<LineChart data={downloads}>
  <XAxis dataKey="date" />
  <YAxis />
  <Tooltip />
  <Line type="monotone" dataKey="count" stroke="#8884d8" />
</LineChart>

State Management

Server State (React Query)

// Fetch apps
const { data: apps, isLoading } = useQuery({
  queryKey: ['apps'],
  queryFn: () => api.get('/apps'),
});

// Create app mutation
const createApp = useMutation({
  mutationFn: (data) => api.post('/apps', data),
  onSuccess: () => {
    queryClient.invalidateQueries(['apps']);
  },
});

Client State (Zustand)

// UI state
const useStore = create((set) => ({
  sidebarOpen: true,
  toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
}));

Authentication Flow

Login Page

export default function LoginPage() {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <Card className="w-96">
        <CardHeader>
          <h1>Sign in to Mosis</h1>
        </CardHeader>
        <CardContent className="space-y-4">
          <Button onClick={() => signIn('github')} className="w-full">
            <GitHubIcon /> Continue with GitHub
          </Button>
          <Button onClick={() => signIn('google')} className="w-full">
            <GoogleIcon /> Continue with Google
          </Button>
          <Separator />
          <form onSubmit={handleEmailLogin}>
            <Input type="email" placeholder="Email" />
            <Input type="password" placeholder="Password" />
            <Button type="submit">Sign in</Button>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}

Protected Routes

// Middleware (Next.js)
export function middleware(request: NextRequest) {
  const token = request.cookies.get('token');

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
}

Responsive Design

Breakpoints

Size Width Target
sm 640px Mobile landscape
md 768px Tablet
lg 1024px Desktop
xl 1280px Large desktop

Mobile Navigation

// Hamburger menu for mobile
<Sheet>
  <SheetTrigger className="md:hidden">
    <MenuIcon />
  </SheetTrigger>
  <SheetContent side="left">
    <Navigation />
  </SheetContent>
</Sheet>

Accessibility

Requirements

  • Keyboard navigation
  • Screen reader support
  • Color contrast (WCAG AA)
  • Focus indicators
  • Alt text for images
  • Form labels
  • Error announcements

Testing

# Lighthouse audit
npx lighthouse http://localhost:3000 --view

# axe-core
npm install @axe-core/react

Deliverables

  • Framework selection
  • UI component library selection
  • Design system (colors, typography)
  • Page wireframes
  • Authentication flow
  • Dashboard implementation
  • App management pages
  • Version submission flow
  • Settings pages
  • Responsive design
  • Accessibility audit

Open Questions

  1. Dark mode support?
  2. Internationalization (i18n)?
  3. Custom domain for docs vs integrated?
  4. Email notifications UI?

References