add developer portal planning documentation (M01-M12)
This commit is contained in:
464
DEV_PORTAL_M05_FRONTEND.md
Normal file
464
DEV_PORTAL_M05_FRONTEND.md
Normal file
@@ -0,0 +1,464 @@
|
||||
# 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
|
||||
|
||||
```typescript
|
||||
// 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
|
||||
|
||||
```typescript
|
||||
// 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
|
||||
|
||||
```typescript
|
||||
// Recharts example
|
||||
<LineChart data={downloads}>
|
||||
<XAxis dataKey="date" />
|
||||
<YAxis />
|
||||
<Tooltip />
|
||||
<Line type="monotone" dataKey="count" stroke="#8884d8" />
|
||||
</LineChart>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## State Management
|
||||
|
||||
### Server State (React Query)
|
||||
|
||||
```typescript
|
||||
// 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)
|
||||
|
||||
```typescript
|
||||
// UI state
|
||||
const useStore = create((set) => ({
|
||||
sidebarOpen: true,
|
||||
toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
|
||||
}));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication Flow
|
||||
|
||||
### Login Page
|
||||
|
||||
```tsx
|
||||
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
|
||||
|
||||
```tsx
|
||||
// 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
|
||||
|
||||
```tsx
|
||||
// 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
- [shadcn/ui](https://ui.shadcn.com/)
|
||||
- [Next.js App Router](https://nextjs.org/docs/app)
|
||||
- [Tailwind CSS](https://tailwindcss.com/)
|
||||
- [React Query](https://tanstack.com/query/latest)
|
||||
Reference in New Issue
Block a user