mirror of
https://github.com/lbr77/SideImpactor.git
synced 2026-05-06 11:14:01 -04:00
refactor: migrate frontend to React + Tailwind, add Docker + tests
Replace the vanilla-TS innerHTML frontend with a type-checked React component tree (React 19 + Tailwind v4 + Vite). Frontend: - 14 components: Header, Stepper, LoginPage, LoginModal, SignPage, DropZone, DevicePicker, ProgressCard, SavedAccountsList, TrustModal, TwoFactorModal, Button, Field, Chip, Modal - lib/ extracts: storage (10 localStorage keys preserved), pair-record, account-session, log-parser, ids, use-log hook - flows/ encapsulate async pair/login/sign/install with dependency injection - Accounts page as main view with Add Account modal - Fullscreen progress overlay during sign/install - Account selector + device picker on Sign page - Security notice in login modal (server trust warning) - All addLog calls mirrored to console.log for devtools debugging Build: - bun run dev: submodule init + install + wasm dist + vite + wrangler - bun run setup: one-shot project bootstrap - Docker: multi-stage bun build → nginx on :3000 - build:wasm:dist copies pre-built src→dist (no Rust/Emscripten needed) - jszip/node-forge/fflate pre-bundled for CJS→ESM conversion Tests: - 163 vitest tests (happy-dom): all lib, components, App integration, WASM dist artifact checks, libcurl Apple connectivity, anisette init error handling Cleanup: - Delete yarn.lock (bun.lock canonical), expand .gitignore - Remove README.zh.md, rewrite README.md + AGENTS.md - Update libcurl.js submodule to f65d440 (CI build artifacts)
This commit is contained in:
55
frontend/src/components/LoginPage.tsx
Normal file
55
frontend/src/components/LoginPage.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Button } from './ui/Button';
|
||||
import { SavedAccountsList } from './SavedAccountsList';
|
||||
import type { StoredAccountSummary } from '../lib/account-session';
|
||||
|
||||
interface LoginPageProps {
|
||||
loggedIn: boolean;
|
||||
savedAccounts: StoredAccountSummary[];
|
||||
activeAccountKey: string | null;
|
||||
cachedAccountKeys: Set<string>;
|
||||
onSwitchAccount: (summary: StoredAccountSummary) => void;
|
||||
onDeleteAccount: (summary: StoredAccountSummary) => void;
|
||||
onAddAccount: () => void;
|
||||
onGoToSignPage: () => void;
|
||||
}
|
||||
|
||||
export function LoginPage({
|
||||
loggedIn,
|
||||
savedAccounts,
|
||||
activeAccountKey,
|
||||
cachedAccountKeys,
|
||||
onSwitchAccount,
|
||||
onDeleteAccount,
|
||||
onAddAccount,
|
||||
onGoToSignPage,
|
||||
}: LoginPageProps) {
|
||||
return (
|
||||
<section className="space-y-6 anim-in">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h1 className="text-[clamp(1.75rem,3.5vw,2.1rem)] font-semibold tracking-tight text-ink">Accounts</h1>
|
||||
<p className="mt-1 text-[14px] text-muted">Add your Apple Developer account here to sign and install apps.</p>
|
||||
</div>
|
||||
<Button variant="primary" onClick={onAddAccount} className="shrink-0">
|
||||
Add Account
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<SavedAccountsList
|
||||
accounts={savedAccounts}
|
||||
activeKey={activeAccountKey}
|
||||
cachedKeys={cachedAccountKeys}
|
||||
onSwitch={onSwitchAccount}
|
||||
onDelete={onDeleteAccount}
|
||||
/>
|
||||
|
||||
{loggedIn && (
|
||||
<div className="flex justify-end">
|
||||
<Button variant="ghost" onClick={onGoToSignPage}>
|
||||
Sign & Install →
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user