diff --git a/src/App.tsx b/src/App.tsx index ddc78ac..b6f99a3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,6 @@ import { createSignal } from "solid-js"; import { Layout } from "./components/Layout"; import { Navigation } from "./components/Navigation"; import { TabNavigation } from "./components/TabNavigation"; -import { SyncPanel } from "./components/SyncPanel"; import { FeedList } from "./components/FeedList"; import { LoginScreen } from "./components/LoginScreen"; import { CodeValidation } from "./components/CodeValidation"; @@ -10,6 +9,8 @@ import { OAuthPlaceholder } from "./components/OAuthPlaceholder"; import { SyncProfile } from "./components/SyncProfile"; import { SearchPage } from "./components/SearchPage"; import { DiscoverPage } from "./components/DiscoverPage"; +import { Player } from "./components/Player"; +import { SettingsScreen } from "./components/SettingsScreen"; import { useAuthStore } from "./stores/auth"; import { useFeedStore } from "./stores/feed"; import { FeedVisibility } from "./types/feed"; @@ -101,29 +102,15 @@ export function App() { } return ( - - - - - - Account: - {auth.isAuthenticated ? ( - Signed in as {auth.user?.email} - ) : ( - Not signed in - )} - setShowAuthPanel(true)} - > - - {auth.isAuthenticated ? "[A] Account" : "[A] Sign In"} - - - - - + setShowAuthPanel(true)} + accountLabel={ + auth.isAuthenticated + ? `Signed in as ${auth.user?.email}` + : "Not signed in" + } + accountStatus={auth.isAuthenticated ? "signed-in" : "signed-out"} + /> ); case "discover": @@ -154,13 +141,15 @@ export function App() { ); case "player": + return ; + default: return ( {tab}
- Player - coming in later phases + Coming soon
); diff --git a/src/components/DiscoverPage.tsx b/src/components/DiscoverPage.tsx index 1a45c28..4d49267 100644 --- a/src/components/DiscoverPage.tsx +++ b/src/components/DiscoverPage.tsx @@ -39,15 +39,17 @@ export function DiscoverPage(props: DiscoverPageProps) { // Category navigation if (area === "categories") { if (key.name === "left" || key.name === "h") { - setCategoryIndex((i) => Math.max(0, i - 1)) - const cat = DISCOVER_CATEGORIES[categoryIndex()] + const nextIndex = Math.max(0, categoryIndex() - 1) + setCategoryIndex(nextIndex) + const cat = DISCOVER_CATEGORIES[nextIndex] if (cat) discoverStore.setSelectedCategory(cat.id) - setShowIndex(0) // Reset show selection when changing category + setShowIndex(0) return } if (key.name === "right" || key.name === "l") { - setCategoryIndex((i) => Math.min(DISCOVER_CATEGORIES.length - 1, i + 1)) - const cat = DISCOVER_CATEGORIES[categoryIndex()] + const nextIndex = Math.min(DISCOVER_CATEGORIES.length - 1, categoryIndex() + 1) + setCategoryIndex(nextIndex) + const cat = DISCOVER_CATEGORIES[nextIndex] if (cat) discoverStore.setSelectedCategory(cat.id) setShowIndex(0) return @@ -67,10 +69,15 @@ export function DiscoverPage(props: DiscoverPageProps) { if (area === "shows") { const shows = discoverStore.filteredPodcasts() if (key.name === "down" || key.name === "j") { + if (shows.length === 0) return setShowIndex((i) => Math.min(i + 1, shows.length - 1)) return } if (key.name === "up" || key.name === "k") { + if (shows.length === 0) { + setFocusArea("categories") + return + } const newIndex = showIndex() - 1 if (newIndex < 0) { setFocusArea("categories") diff --git a/src/components/FeedDetail.tsx b/src/components/FeedDetail.tsx index 9d5cb8f..b7dd44f 100644 --- a/src/components/FeedDetail.tsx +++ b/src/components/FeedDetail.tsx @@ -4,6 +4,7 @@ */ import { createSignal, For, Show } from "solid-js" +import { useKeyboard } from "@opentui/solid" import type { Feed } from "../types/feed" import type { Episode } from "../types/episode" import { format } from "date-fns" @@ -72,6 +73,11 @@ export function FeedDetail(props: FeedDetailProps) { } } + useKeyboard((key) => { + if (!props.focused) return + handleKeyPress(key) + }) + return ( {/* Header with back button */} diff --git a/src/components/FeedList.tsx b/src/components/FeedList.tsx index f4f812c..69a9438 100644 --- a/src/components/FeedList.tsx +++ b/src/components/FeedList.tsx @@ -4,6 +4,7 @@ */ import { createSignal, For, Show } from "solid-js" +import { useKeyboard } from "@opentui/solid" import { FeedItem } from "./FeedItem" import { useFeedStore } from "../stores/feed" import { FeedVisibility, FeedSortField } from "../types/feed" @@ -65,6 +66,11 @@ export function FeedList(props: FeedListProps) { } } + useKeyboard((key) => { + if (!props.focused) return + handleKeyPress(key) + }) + const cycleVisibilityFilter = () => { const current = feedStore.filter().visibility let next: FeedVisibility | "all" diff --git a/tasks/podcast-tui-app/50-global-state-store.md b/tasks/podcast-tui-app/50-global-state-store.md new file mode 100644 index 0000000..59e8b67 --- /dev/null +++ b/tasks/podcast-tui-app/50-global-state-store.md @@ -0,0 +1,52 @@ +# 50. Create Global State Store (Signals) + +meta: + id: podcast-tui-app-50 + feature: podcast-tui-app + priority: P1 + depends_on: [66] + tags: [state-management, signals, solidjs, global-store] + +objective: +- Create a global state store using SolidJS Signals for reactive state management +- Implement a store that manages application-wide state (feeds, settings, user, etc.) +- Provide reactive subscriptions for state changes +- Ensure thread-safe state updates + +deliverables: +- `/src/store/index.ts` - Global state store with Signals +- `/src/store/types.ts` - State type definitions +- `/src/store/hooks.ts` - Custom hooks for state access +- Updated `src/index.tsx` to initialize the store + +steps: +- Define state interface with all application state properties (feeds, settings, user, etc.) +- Create Signal-based store using `createSignal` from SolidJS +- Implement computed signals for derived state (filtered feeds, search results, etc.) +- Create state update functions that trigger reactivity +- Add subscription mechanism for reactive UI updates +- Export store and hooks for use across components + +tests: +- Unit: Test that signals update correctly when state changes +- Unit: Test computed signals produce correct derived values +- Integration: Verify store updates trigger UI re-renders +- Integration: Test multiple components can subscribe to same state + +acceptance_criteria: +- Store can be initialized with default state +- State changes trigger reactive updates in components +- Computed signals work correctly for derived state +- Multiple components can access and subscribe to store +- State updates are thread-safe + +validation: +- Run `bun run build` to verify TypeScript compilation +- Run application and verify state changes are reactive +- Check console for any errors during state updates + +notes: +- Use `createSignal`, `createComputed`, `createEffect` from SolidJS +- Store should follow single source of truth pattern +- Consider using `batch` for multiple state updates +- State should be serializable for persistence diff --git a/tasks/podcast-tui-app/59-theme-system.md b/tasks/podcast-tui-app/59-theme-system.md new file mode 100644 index 0000000..4f7ae56 --- /dev/null +++ b/tasks/podcast-tui-app/59-theme-system.md @@ -0,0 +1,56 @@ +# 59. Create Theme System Architecture + +meta: + id: podcast-tui-app-59 + feature: podcast-tui-app + priority: P1 + depends_on: [09] + tags: [theming, architecture, solidjs, design-system] + +objective: +- Design and implement a flexible theme system architecture +- Support multiple color themes (Catppuccin, Gruvbox, Tokyo, Nord, custom) +- Provide theme switching capabilities +- Ensure theme persistence across sessions +- Define theme properties (colors, fonts, spacing, borders) + +deliverables: +- `/src/themes/types.ts` - Theme type definitions +- `/src/themes/theme.ts` - Theme system core implementation +- `/src/themes/themes/` - Directory with theme files +- `/src/themes/default.ts` - Default system theme +- `/src/themes/hooks.ts` - Theme hooks (useTheme, useThemeColor) + +steps: +- Define `Theme` interface with properties: name, colors, fonts, spacing, borders +- Create theme color palettes (background, foreground, primary, secondary, accent, etc.) +- Implement `ThemeManager` class to handle theme loading, switching, and persistence +- Create `useTheme` hook for React/Solid components to access current theme +- Implement `useThemeColor` hook for accessing specific theme colors +- Add theme persistence using localStorage or file-based storage +- Export theme utilities for programmatic theme access + +tests: +- Unit: Test theme loading from JSON file +- Unit: Test theme switching updates current theme +- Unit: Test theme persistence saves/loads correctly +- Integration: Verify components update when theme changes + +acceptance_criteria: +- Theme system can load multiple theme definitions +- Theme switching works instantly across all components +- Theme preferences persist across application restarts +- Theme colors are accessible via hooks +- Theme manager handles errors gracefully + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test theme switching manually in application +- Verify localStorage/file storage works +- Check all theme colors render correctly + +notes: +- Theme files should be JSON or TypeScript modules +- Use CSS variables or terminal color codes +- Consider dark/light mode compatibility +- Themes should be easily extensible diff --git a/tasks/podcast-tui-app/60-default-theme.md b/tasks/podcast-tui-app/60-default-theme.md new file mode 100644 index 0000000..a72744c --- /dev/null +++ b/tasks/podcast-tui-app/60-default-theme.md @@ -0,0 +1,52 @@ +# 60. Implement Default Theme (System Terminal) + +meta: + id: podcast-tui-app-60 + feature: podcast-tui-app + priority: P1 + depends_on: [59] + tags: [theming, default, solidjs, terminal] + +objective: +- Implement the default system terminal theme +- Define colors matching common terminal environments +- Ensure good readability and contrast +- Support both light and dark terminal modes + +deliverables: +- `/src/themes/themes/default.ts` - Default theme definition +- `/src/themes/themes/default-light.ts` - Light mode theme +- `/src/themes/themes/default-dark.ts` - Dark mode theme +- Updated `/src/themes/theme.ts` to load default theme + +steps: +- Define default color palette for system terminals +- Create light mode theme with standard terminal colors +- Create dark mode theme with standard terminal colors +- Ensure proper contrast ratios for readability +- Test theme in both light and dark terminal environments +- Export default theme as fallback + +tests: +- Unit: Verify default theme colors are defined +- Unit: Test theme renders correctly in light mode +- Unit: Test theme renders correctly in dark mode +- Visual: Verify text contrast meets accessibility standards + +acceptance_criteria: +- Default theme works in light terminal mode +- Default theme works in dark terminal mode +- Colors have good readability and contrast +- Theme is used as fallback when no theme selected + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test in light terminal (e.g., iTerm2, Terminal.app) +- Test in dark terminal (e.g., Kitty, Alacritty) +- Check color contrast visually + +notes: +- Use standard terminal color codes (ANSI escape codes) +- Consider common terminal themes (Solarized, Dracula, etc.) +- Test on multiple terminal emulators +- Document terminal requirements diff --git a/tasks/podcast-tui-app/61-catppuccin-theme.md b/tasks/podcast-tui-app/61-catppuccin-theme.md new file mode 100644 index 0000000..bf6cf3c --- /dev/null +++ b/tasks/podcast-tui-app/61-catppuccin-theme.md @@ -0,0 +1,52 @@ +# 61. Add Catppuccin Theme + +meta: + id: podcast-tui-app-61 + feature: podcast-tui-app + priority: P1 + depends_on: [59] + tags: [theming, catppuccin, solidjs, popular] + +objective: +- Implement Catppuccin Mocha theme for the podcast TUI +- Provide beautiful, modern color scheme +- Ensure high contrast and readability +- Support both dark and light variants + +deliverables: +- `/src/themes/themes/catppuccin.ts` - Catppuccin theme definition +- `/src/themes/themes/catppuccin-mocha.ts` - Dark mode Catppuccin +- `/src/themes/themes/catppuccin-latte.ts` - Light mode Catppuccin +- Updated `/src/themes/themes/index.ts` to export Catppuccin themes + +steps: +- Research and implement Catppuccin Mocha color palette +- Define all color tokens (background, foreground, surface, primary, secondary, etc.) +- Create Catppuccin Mocha (dark) theme +- Create Catppuccin Latte (light) theme +- Ensure proper color contrast for accessibility +- Add Catppuccin to theme registry + +tests: +- Unit: Verify Catppuccin theme colors are defined +- Unit: Test Catppuccin Mocha renders correctly +- Unit: Test Catppuccin Latte renders correctly +- Visual: Verify Catppuccin colors are visually appealing + +acceptance_criteria: +- Catppuccin Mocha theme works in dark terminals +- Catppuccin Latte theme works in light terminals +- Colors match official Catppuccin design +- Theme is selectable from theme list + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test Catppuccin theme manually in application +- Compare with official Catppuccin color palette +- Check color harmony and contrast + +notes: +- Catppuccin Mocha is the recommended dark theme +- Include all standard Catppuccin colors (latte, frappe, macchiato, mocha) +- Use official color values from Catppuccin repository +- Consider adding custom color variations diff --git a/tasks/podcast-tui-app/62-gruvbox-theme.md b/tasks/podcast-tui-app/62-gruvbox-theme.md new file mode 100644 index 0000000..fdcf85a --- /dev/null +++ b/tasks/podcast-tui-app/62-gruvbox-theme.md @@ -0,0 +1,52 @@ +# 62. Add Gruvbox Theme + +meta: + id: podcast-tui-app-62 + feature: podcast-tui-app + priority: P1 + depends_on: [59] + tags: [theming, gruvbox, solidjs, retro] + +objective: +- Implement Gruvbox Dark theme for the podcast TUI +- Provide warm, nostalgic color scheme +- Ensure good contrast and readability +- Support both dark and light variants + +deliverables: +- `/src/themes/themes/gruvbox.ts` - Gruvbox theme definition +- `/src/themes/themes/gruvbox-dark.ts` - Dark mode Gruvbox +- `/src/themes/themes/gruvbox-light.ts` - Light mode Gruvbox +- Updated `/src/themes/themes/index.ts` to export Gruvbox themes + +steps: +- Research and implement Gruvbox Dark theme color palette +- Define all color tokens (background, foreground, primary, secondary, etc.) +- Create Gruvbox Dark theme +- Create Gruvbox Light theme +- Ensure proper color contrast for accessibility +- Add Gruvbox to theme registry + +tests: +- Unit: Verify Gruvbox theme colors are defined +- Unit: Test Gruvbox Dark renders correctly +- Unit: Test Gruvbox Light renders correctly +- Visual: Verify Gruvbox colors are visually appealing + +acceptance_criteria: +- Gruvbox Dark theme works in dark terminals +- Gruvbox Light theme works in light terminals +- Colors match official Gruvbox design +- Theme is selectable from theme list + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test Gruvbox theme manually in application +- Compare with official Gruvbox color palette +- Check color harmony and contrast + +notes: +- Gruvbox Dark is the recommended variant +- Include all standard Gruvbox colors (hard, soft, light) +- Use official color values from Gruvbox repository +- Gruvbox is popular among developers for its warmth diff --git a/tasks/podcast-tui-app/63-tokyo-theme.md b/tasks/podcast-tui-app/63-tokyo-theme.md new file mode 100644 index 0000000..cdfd6d8 --- /dev/null +++ b/tasks/podcast-tui-app/63-tokyo-theme.md @@ -0,0 +1,52 @@ +# 63. Add Tokyo Night Theme + +meta: + id: podcast-tui-app-63 + feature: podcast-tui-app + priority: P1 + depends_on: [59] + tags: [theming, tokyo-night, solidjs, modern] + +objective: +- Implement Tokyo Night theme for the podcast TUI +- Provide modern, vibrant color scheme +- Ensure good contrast and readability +- Support both dark and light variants + +deliverables: +- `/src/themes/themes/tokyo-night.ts` - Tokyo Night theme definition +- `/src/themes/themes/tokyo-night-day.ts` - Light mode Tokyo Night +- `/src/themes/themes/tokyo-night-night.ts` - Dark mode Tokyo Night +- Updated `/src/themes/themes/index.ts` to export Tokyo Night themes + +steps: +- Research and implement Tokyo Night theme color palette +- Define all color tokens (background, foreground, primary, secondary, etc.) +- Create Tokyo Night Night (dark) theme +- Create Tokyo Night Day (light) theme +- Ensure proper color contrast for accessibility +- Add Tokyo Night to theme registry + +tests: +- Unit: Verify Tokyo Night theme colors are defined +- Unit: Test Tokyo Night Night renders correctly +- Unit: Test Tokyo Night Day renders correctly +- Visual: Verify Tokyo Night colors are visually appealing + +acceptance_criteria: +- Tokyo Night Night theme works in dark terminals +- Tokyo Night Day theme works in light terminals +- Colors match official Tokyo Night design +- Theme is selectable from theme list + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test Tokyo Night theme manually in application +- Compare with official Tokyo Night color palette +- Check color harmony and contrast + +notes: +- Tokyo Night Night is the recommended variant +- Include all standard Tokyo Night colors +- Use official color values from Tokyo Night repository +- Tokyo Night is popular for its modern, clean look diff --git a/tasks/podcast-tui-app/64-nord-theme.md b/tasks/podcast-tui-app/64-nord-theme.md new file mode 100644 index 0000000..8f30cb9 --- /dev/null +++ b/tasks/podcast-tui-app/64-nord-theme.md @@ -0,0 +1,52 @@ +# 64. Add Nord Theme + +meta: + id: podcast-tui-app-64 + feature: podcast-tui-app + priority: P1 + depends_on: [59] + tags: [theming, nord, solidjs, minimal] + +objective: +- Implement Nord theme for the podcast TUI +- Provide clean, minimal color scheme +- Ensure good contrast and readability +- Support both dark and light variants + +deliverables: +- `/src/themes/themes/nord.ts` - Nord theme definition +- `/src/themes/themes/nord-dark.ts` - Dark mode Nord +- `/src/themes/themes/nord-light.ts` - Light mode Nord +- Updated `/src/themes/themes/index.ts` to export Nord themes + +steps: +- Research and implement Nord theme color palette +- Define all color tokens (background, foreground, primary, secondary, etc.) +- Create Nord Dark theme +- Create Nord Light theme +- Ensure proper color contrast for accessibility +- Add Nord to theme registry + +tests: +- Unit: Verify Nord theme colors are defined +- Unit: Test Nord Dark renders correctly +- Unit: Test Nord Light renders correctly +- Visual: Verify Nord colors are visually appealing + +acceptance_criteria: +- Nord Dark theme works in dark terminals +- Nord Light theme works in light terminals +- Colors match official Nord design +- Theme is selectable from theme list + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test Nord theme manually in application +- Compare with official Nord color palette +- Check color harmony and contrast + +notes: +- Nord Dark is the recommended variant +- Include all standard Nord colors +- Use official color values from Nord repository +- Nord is popular for its minimalist, clean aesthetic diff --git a/tasks/podcast-tui-app/65-custom-theme.md b/tasks/podcast-tui-app/65-custom-theme.md new file mode 100644 index 0000000..098e3e0 --- /dev/null +++ b/tasks/podcast-tui-app/65-custom-theme.md @@ -0,0 +1,56 @@ +# 65. Implement Custom Theme Editor + +meta: + id: podcast-tui-app-65 + feature: podcast-tui-app + priority: P2 + depends_on: [59] + tags: [theming, editor, custom, solidjs] + +objective: +- Build a UI for creating and editing custom themes +- Allow users to modify color palettes +- Provide live preview of theme changes +- Save custom themes to storage + +deliverables: +- `/src/components/ThemeEditor.tsx` - Theme editor component +- `/src/components/ThemePreview.tsx` - Live theme preview component +- `/src/components/ColorPicker.tsx` - Custom color picker component +- `/src/store/theme-editor.ts` - Theme editor state management +- Updated settings screen to include theme editor + +steps: +- Create ThemeEditor component with color palette editor +- Implement ColorPicker component for selecting theme colors +- Create ThemePreview component showing live theme changes +- Build form controls for editing all theme properties +- Add save functionality for custom themes +- Implement delete functionality for custom themes +- Add validation for theme color values +- Update settings screen to show theme editor + +tests: +- Unit: Test theme editor saves custom themes correctly +- Unit: Test color picker updates theme colors +- Unit: Test theme preview updates in real-time +- Integration: Test custom theme can be loaded + +acceptance_criteria: +- Theme editor allows editing all theme colors +- Custom theme can be saved and loaded +- Live preview shows theme changes in real-time +- Custom themes persist across sessions +- Invalid color values are rejected + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test theme editor manually in application +- Verify custom themes save/load correctly +- Check live preview works smoothly + +notes: +- Use existing theme type definitions +- Provide preset color palettes for quick selection +- Consider adding theme templates +- Ensure editor works on small terminal sizes diff --git a/tasks/podcast-tui-app/66-theme-selector.md b/tasks/podcast-tui-app/66-theme-selector.md new file mode 100644 index 0000000..8f95eb3 --- /dev/null +++ b/tasks/podcast-tui-app/66-theme-selector.md @@ -0,0 +1,56 @@ +# 66. Add Theme Selector in Settings + +meta: + id: podcast-tui-app-66 + feature: podcast-tui-app + priority: P1 + depends_on: [59, 60, 61, 62, 63, 64, 65] + tags: [theming, settings, selector, solidjs] + +objective: +- Add theme selection UI in settings screen +- Display all available themes (default, Catppuccin, Gruvbox, Tokyo, Nord, custom) +- Allow users to select and switch themes +- Show currently selected theme +- Persist theme preference + +deliverables: +- `/src/components/ThemeSelector.tsx` - Theme selector component +- Updated `/src/components/SettingsScreen.tsx` to include theme selector +- Updated `/src/store/theme.ts` to handle theme preference persistence +- Theme selector in settings navigation + +steps: +- Create ThemeSelector component with theme list +- Implement theme selection logic +- Display current theme with visual indicator +- Add theme descriptions or icons +- Integrate theme selector into Settings screen +- Save theme preference to storage +- Handle theme switching with instant updates +- Add keyboard navigation for theme list + +tests: +- Unit: Test theme selector displays all themes +- Unit: Test theme selection updates current theme +- Unit: Test theme preference saves to storage +- Integration: Test theme switching works across all components + +acceptance_criteria: +- Theme selector shows all available themes +- Users can select and switch themes +- Current theme is clearly indicated +- Theme preference persists across sessions +- Theme changes apply immediately to all components + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test theme selector manually in settings +- Verify theme preference saves/loads correctly +- Check theme applies to all UI components + +notes: +- Use existing theme manager for theme switching +- Consider adding theme search/filter +- Show theme preview in selector if possible +- Ensure accessibility for keyboard navigation diff --git a/tasks/podcast-tui-app/67-browser-redirect.md b/tasks/podcast-tui-app/67-browser-redirect.md new file mode 100644 index 0000000..ad505cd --- /dev/null +++ b/tasks/podcast-tui-app/67-browser-redirect.md @@ -0,0 +1,57 @@ +# 67. Implement Browser Redirect Flow for OAuth + +meta: + id: podcast-tui-app-67 + feature: podcast-tui-app + priority: P2 + depends_on: [04] + tags: [oauth, authentication, browser, solidjs] + +objective: +- Implement browser redirect flow for OAuth authentication +- Handle OAuth callback in terminal application +- Exchange authorization code for access token +- Store authentication tokens securely + +deliverables: +- `/src/auth/oauth-redirect.ts` - OAuth redirect handler +- `/src/auth/oauth-callback.ts` - OAuth callback handler +- `/src/auth/token-handler.ts` - Token exchange and storage +- Updated `/src/auth/login-screen.tsx` with OAuth option +- Updated `/src/auth/authentication-state.ts` for OAuth state + +steps: +- Implement OAuth authorization URL generation with client ID/secret +- Create OAuth redirect handler to capture callback +- Handle authorization code exchange with token endpoint +- Store access token and refresh token securely +- Implement error handling for OAuth failures +- Add OAuth state parameter for security +- Update authentication state to track OAuth login status +- Add OAuth logout functionality + +tests: +- Unit: Test OAuth authorization URL generation +- Unit: Test token exchange with valid/invalid code +- Unit: Test token storage and retrieval +- Integration: Test OAuth flow from start to finish + +acceptance_criteria: +- OAuth authorization URL is generated correctly +- OAuth callback is handled without errors +- Access token is stored securely +- OAuth flow works with valid credentials +- OAuth errors are handled gracefully + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test OAuth flow manually with test credentials +- Verify token storage in localStorage +- Check error handling for invalid tokens + +notes: +- Use standard OAuth 2.0 flow (authorization code grant) +- Document OAuth requirements (client ID, redirect URI) +- Consider using PKCE for enhanced security +- Test with real OAuth provider if possible +- Document limitations and requirements diff --git a/tasks/podcast-tui-app/68-qr-code-display.md b/tasks/podcast-tui-app/68-qr-code-display.md new file mode 100644 index 0000000..4f1a2a9 --- /dev/null +++ b/tasks/podcast-tui-app/68-qr-code-display.md @@ -0,0 +1,58 @@ +# 68. Build QR Code Display for Mobile Verification + +meta: + id: podcast-tui-app-68 + feature: podcast-tui-app + priority: P2 + depends_on: [04] + tags: [authentication, qr-code, mobile, verification, solidjs] + +objective: +- Display QR code for mobile device verification +- Generate QR code from verification URL +- Handle manual code entry as fallback +- Show verification status and expiration + +deliverables: +- `/src/components/QrCodeDisplay.tsx` - QR code display component +- `/src/utils/qr-code-generator.ts` - QR code generation utility +- `/src/auth/verification-handler.ts` - Verification flow handler +- Updated `/src/auth/login-screen.tsx` with QR code option +- Updated `/src/auth/code-validation.tsx` for manual entry + +steps: +- Integrate QR code generation library (e.g., `qrcode` package) +- Create QRCodeDisplay component with generated QR image +- Implement verification URL generation +- Add manual code entry fallback UI +- Show verification expiration timer +- Display verification success/failure status +- Handle QR code scan timeout +- Update authentication state on successful verification + +tests: +- Unit: Test QR code generation +- Unit: Test verification URL generation +- Unit: Test verification code validation +- Integration: Test complete verification flow + +acceptance_criteria: +- QR code is generated correctly from verification URL +- QR code is displayed in terminal +- Manual code entry works as fallback +- Verification status is shown clearly +- Verification expires after timeout +- Successful verification updates auth state + +validation: +- Run `bun run build` to verify TypeScript compilation +- Test QR code display manually +- Test manual code entry fallback +- Verify verification flow works end-to-end + +notes: +- Use `qrcode` or similar library for QR generation +- Display QR code in ASCII or image format +- Consider using external scanner app +- Add verification expiration (e.g., 5 minutes) +- Document mobile app requirements for scanning