--- phase: 13-add-remaining-rclone-remotes plan: 02 type: execute wave: 2 depends_on: [13-01] files_modified: - src/components/wizard/OAuthInstructions.tsx - src/components/wizard/OAuthInstructions.test.tsx - src/components/wizard/GdriveAuthToggle.tsx - src/components/icons/BackendIcons.tsx autonomous: true requirements: [REMOTE-04] must_haves: truths: - "OAuthInstructions renders collapsed by default and expands on click" - "OAuthInstructions shows backend-specific rclone authorize command" - "GdriveAuthToggle switches between OAuth Token and Service Account tabs" - "Backend icons are inline SVGs with no external dependency" artifacts: - path: "src/components/wizard/OAuthInstructions.tsx" provides: "Collapsible OAuth step-by-step guide" exports: ["OAuthInstructions"] - path: "src/components/wizard/GdriveAuthToggle.tsx" provides: "Google Drive dual-auth toggle (OAuth vs Service Account)" exports: ["GdriveAuthToggle"] - path: "src/components/icons/BackendIcons.tsx" provides: "Inline SVG icon map keyed by BackendType" exports: ["BACKEND_ICONS"] - path: "src/components/wizard/OAuthInstructions.test.tsx" provides: "Tests for collapsed/expanded behavior" key_links: - from: "src/components/wizard/GdriveAuthToggle.tsx" to: "src/components/wizard/OAuthInstructions.tsx" via: "import and render" pattern: "OAuthInstructions" - from: "src/components/icons/BackendIcons.tsx" to: "src/schemas/registry.ts" via: "BackendType key mapping" pattern: "Record.*BackendType" --- Build the three new components needed by Phase 13: OAuthInstructions (collapsible guide for OAuth token-paste backends), GdriveAuthToggle (dual-auth toggle for Google Drive), and BackendIcons (inline SVG icon map). Purpose: These components are consumed by plans 03 (BackendSelectionStep) and 04 (RemoteConfigStep). Building them in isolation ensures clean interfaces and testability. Output: Three new component files with tests for OAuthInstructions. @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/13-add-remaining-rclone-remotes/13-CONTEXT.md @.planning/phases/13-add-remaining-rclone-remotes/13-RESEARCH.md @.planning/phases/13-add-remaining-rclone-remotes/13-01-SUMMARY.md From src/components/wizard/AzureAuthToggle.tsx (AuthToggle pattern): ```typescript interface AzureAuthToggleProps { register: UseFormRegister; errors: { key?: FieldError; sas_url?: FieldError; }; } // Uses useState for tab, segmented control buttons, CSS hidden/block for inactive/active ``` From src/components/ui/PasswordField.tsx (used for token fields): ```typescript // PasswordField wraps TextFieldMD3 with show/hide toggle // Used for all password/token inputs ``` From src/components/ui/BackendCard.tsx (icon will be added here): ```typescript interface BackendCardProps { name: string; description: string; selected?: boolean; onClick: () => void; } ``` MD3 styling tokens used throughout: - bg-surface, bg-surface-container, bg-primary - text-on-surface, text-on-surface-variant, text-on-primary - border-outline, rounded-xl, shadow Task 1: OAuthInstructions component with tests src/components/wizard/OAuthInstructions.tsx, src/components/wizard/OAuthInstructions.test.tsx - Test 1: Renders collapsed by default (instructions not visible) - Test 2: Expands when user clicks the toggle button, showing numbered steps - Test 3: Shows the backend-specific `authorizeCommand` in the expanded content - Test 4: Shows backend name in the toggle button text Create OAuthInstructions component with these props: ```typescript interface OAuthInstructionsProps { backendName: string; // e.g. "Google Drive" authorizeCommand: string; // e.g. 'rclone authorize "drive"' steps?: string[]; // optional custom steps (defaults to generic OAuth flow) } ``` Implementation: - Use `useState(false)` for expanded state - Render a button/disclosure that reads "How to get your OAuth token" (or similar with backendName) - When expanded, show numbered steps: (1) Install rclone on a machine with a browser, (2) Run the authorize command (show in a code block), (3) Authenticate in the browser, (4) Copy the JSON token from terminal, (5) Paste it in the field above - Use `steps` prop to override default steps if provided - Style with MD3 tokens: bg-surface-container, text-on-surface, border-outline, rounded-xl - Use an expand/collapse chevron icon (inline SVG, simple caret) - Collapse transition is optional (CSS-only if added) Write tests first (RED), then implement (GREEN). npx vitest run src/components/wizard/OAuthInstructions.test.tsx --reporter=verbose OAuthInstructions renders collapsed by default, expands on click, shows backend-specific command and steps. All 4 tests pass. Task 2: GdriveAuthToggle and BackendIcons components src/components/wizard/GdriveAuthToggle.tsx, src/components/icons/BackendIcons.tsx 1. Create GdriveAuthToggle following the exact same pattern as AzureAuthToggle: ```typescript interface GdriveAuthToggleProps { register: UseFormRegister; errors: { token?: FieldError; service_account_credentials?: FieldError; }; } ``` - Two tabs: "OAuth Token" and "Service Account" - Tab 1 (OAuth Token): OAuthInstructions component (backendName="Google Drive", authorizeCommand='rclone authorize "drive"') + PasswordField for token - Tab 2 (Service Account): PasswordField for service_account_credentials with helpText about JSON key file - Both fields always registered (CSS hidden/block), same as Azure/SFTP pattern - Use same segmented control styling as AzureAuthToggle 2. Create BackendIcons.tsx with inline SVG icons for all 17 backends: - Export `BACKEND_ICONS: Partial>>` where `IconProps = { className?: string }` - Each icon is a simple monochrome SVG using `fill="currentColor"` for MD3 dark mode compatibility - Icons should be recognizable at 24x24px size (viewBox="0 0 24 24") - Use simplified/stylized versions of brand icons (cloud shape for generic cloud storage, drive icon for Google Drive, folder for file-based, server for protocol-based, etc.) - For backends where a distinctive icon is hard to create (swift, seafile), use a generic category icon (cloud, server, globe) - The icon map is Partial — missing entries just mean no icon rendered on the card Create the icons directory: src/components/icons/ npx tsc --noEmit 2>&1 | tail -20 && npx vitest run src/components/wizard/ --reporter=verbose 2>&1 | tail -30 GdriveAuthToggle renders two-tab auth toggle with OAuthInstructions in OAuth tab. BackendIcons exports BACKEND_ICONS map with inline SVG icons for backends. TypeScript compiles, existing tests pass. - `npx vitest run` — full suite green - `npx tsc --noEmit` — no type errors - OAuthInstructions test file passes all 4 behavior tests - GdriveAuthToggle follows AzureAuthToggle pattern exactly - OAuthInstructions component: collapsed by default, expands on click, shows authorize command - GdriveAuthToggle: two-tab toggle (OAuth Token + Service Account), both fields always registered - BackendIcons: inline SVG map keyed by BackendType, monochrome, no external dependency - All tests pass After completion, create `.planning/phases/13-add-remaining-rclone-remotes/13-02-SUMMARY.md`