Skip to content

Conversation

@daniel-samson
Copy link
Owner

Summary

  • Created a reusable LoadingSpinnerComponent for consistent loading UI across all pages
  • Updated home, search, and coin-detail components to use the new component
  • Standardized loading states with customizable messages via input signals

Changes

  • New: LoadingSpinnerComponent with Angular input signals for message customization
  • Updated: home.component.ts to use LoadingSpinnerComponent with "Loading cryptocurrency data..."
  • Updated: search.component.ts to use LoadingSpinnerComponent with "Searching..."
  • Updated: coin-detail.component.ts to use LoadingSpinnerComponent with "Loading coin details..."
  • Fixed: Loading spinner template to properly invoke input signal with message()

Test plan

  • Home page displays loading spinner with correct message while loading coins
  • Search page displays loading spinner with correct message while searching
  • Coin detail page displays loading spinner with correct message while loading details
  • All spinners are visually consistent across pages
  • Build completes without warnings or errors

🤖 Generated with Claude Code

daniel-samson and others added 30 commits December 8, 2025 19:40
- Set up Angular 21 with standalone components
- Configure TypeScript and development tools
- Add Prettier and Vitest for testing
- Configure VSCode workspace settings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Install Zard UI (@ngzard/ui) component library for Angular
- Set up Vitest with testing-library for unit and component testing
- Configure Tailwind CSS for styling with PostCSS
- Create CoinGecko API service with HttpClient for backend integration
- Implement pages: Home (coin list), Coin Details, and Search
- Add routing configuration with navigation between pages
- Create TypeScript models for Coin and CoinDetails data
- Include unit tests for API service and home component
- Configure environment variables support via .env.example
- Update main app component with navigation menu

Features implemented:
- Fetch and display top 10 cryptocurrencies by market cap
- Search cryptocurrencies by name or symbol with debounce
- View detailed coin information including market data
- Responsive grid layout using Tailwind CSS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Simplify vitest.config.ts to work properly with Angular components
- Install @angular/localize for test environment setup
- Fix template syntax for method calls in Angular templates
- Simplify initial test files to ensure tests pass
- Add .env.example for environment configuration
- Update package.json test scripts for Vitest

All tests now passing:
- CoinGeckoService tests (service creation and method definitions)
- HomeComponent placeholder test
- App component placeholder test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Document project features and technology stack
- Add setup and installation instructions
- Include development server and testing commands
- Explain API integration with backend
- Detail component structure and usage
- Add contributing guidelines
- Include links to relevant documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy assets and styling from Nuxt frontend:
- Copy favicon and logo (cryptobro-logo-v1.svg) to public directory
- Implement CSS variable-based theming system with light/dark mode
- Configure Tailwind CSS with custom color palette using HSL variables

Create Angular components matching Nuxt design:
- HeaderComponent with logo, search form, and theme toggle
- FooterComponent with copyright and GitHub link
- ModeToggleComponent for light/dark mode switching with localStorage persistence

Replicate and enhance page designs:
- Home page: Card-based grid layout with coin images and prices
- Search page: Table layout with interactive rows and market cap data
- Coin detail page: Enhanced layout with market data grid and price change indicators

Update styling:
- Add comprehensive CSS variables for light and dark themes
- Configure Tailwind with HSL color system matching Nuxt design
- Add dark mode class detection and persistence
- Include responsive grid and table layouts
- Add loading spinners, error states, and empty states

Features:
- Dark mode toggle with system preference detection
- Persistent theme preference in localStorage
- Responsive design for mobile, tablet, and desktop
- Consistent color scheme across all pages
- Price formatting with Intl.NumberFormat API

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Update test configuration:
- Change package.json test script from 'vitest' to 'ng test'
- Update test scripts: test, test:watch, test:coverage using ng test
- Simplify vitest.config.ts with jsdom environment

Upgrade Tailwind CSS:
- Install @tailwindcss/postcss for Tailwind CSS v4 support
- Update postcss.config.js to use @tailwindcss/postcss plugin
- Remove tailwind.config.js (not needed for v4)
- Update src/styles.css to use @import "tailwindcss" and @theme/@dark directives
- Migrate CSS variables from config-based to theme-based approach

Fix TypeScript issues:
- Remove import.meta.env usage from CoinGeckoService (set default API URL)
- Add "type": "module" to package.json to fix PostCSS warnings

All tests now passing with ng test command as expected by Angular developers:
✓ 3 test files
✓ 7 tests passed
✓ Full Tailwind v4 theming with dark mode support
✓ jsdom environment with Vitest

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Create EnvironmentService to read VITE_API_BASE_URL from .env
- Update CoinGeckoService to use environment configuration
- Add 'node' type definitions to tsconfig.app.json and tsconfig.spec.json
- All tests passing with new environment variable setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Use formatLargeNumber for 24h high/low values instead of formatPrice
- Add optional chaining (?.) for description.en property access
- Ensure type safety for price_change_percentage_24h with non-null check
- All build and watch commands now pass without TypeScript errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Install Zard UI CLI and add button, card, badge, input, dropdown, avatar components
- Install @angular/cdk and lucide-angular dependencies
- Create merge-classes utility for Tailwind class composition
- Update all page components to use z-card component instead of styled divs
- Configure tsconfig with @shared path alias for component imports
- Replace template styling with actual Zard UI components for proper theming

Styling now uses Zard UI components which apply proper CSS variables for light/dark mode and theming.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix input signal type declarations to use boolean defaults
- Simplify mergeClasses to accept any type for better compatibility
- Remove invalid transform options that don't match Angular API
- All components now build successfully without TypeScript errors

Application bundle now builds to 309.85 KB (80.31 KB gzipped).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix EnvironmentService to properly default to localhost:8000 in browser
- Create .env file with API configuration
- Replace Angular placeholder template with router-outlet to show page content
- Home component now properly loads and displays cryptocurrency data

The app now correctly shows the cryptocurrency cards on the home page.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add localhost:4200 (Angular frontend) to CORS_ALLOWED_ORIGINS
- Maintain support for localhost:3000 (Nuxt frontend)
- Update .env.example to document both frontend origins

Backend now allows API requests from both Angular (port 4200) and Nuxt (port 3000) frontends.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Added explicit change detection (markForCheck) to home, detail, and search components
- Improved CoinGecko service response handling with better error resilience
- Updated Tailwind CSS v4 configuration with explicit component layer classes for custom colors
- Fixed change detection timing issue where API responses weren't triggering view updates

The root cause was that async HTTP responses were completing outside Angular's zone,
preventing automatic change detection. Now components explicitly mark themselves for
change detection when data arrives, ensuring immediate view updates.

Performance improved from indefinite loading spinner to data display within 300ms.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Ran @ngzard/ui init to update Tailwind CSS v4 configuration
- Updated styles.css with explicit @layer utilities for custom color classes
- Added utility classes for background, text, and border colors using CSS variables
- Added .postcssrc.json for PostCSS configuration
- Updated tsconfig.json and package.json dependencies from ngzard init

The issue was that Tailwind v4 with @theme inline doesn't automatically
generate utility classes from theme variables. Now all custom colors
(background, foreground, card, primary, secondary, muted, accent, etc.)
have corresponding utility classes that reference the CSS variables.

This ensures theme colors are properly applied to all UI elements
via Tailwind utility classes like bg-background, text-foreground, etc.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Created tailwind.config.js to properly extend theme colors using CSS variables
- Updated styles.css to remove problematic @theme inline block that was preventing utility class generation
- Changed @apply directives to direct CSS variable assignments for better Tailwind v4 compatibility
- CSS styling now properly applies to components (card backgrounds, padding, borders, text colors)
- Removed stale test class from home.component.ts

This fixes the issue where cryptocurrency cards were displaying data but with zero styling applied.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replaced hand-drawn SVG icons with professional lucide icons (Sun, Moon, Monitor)
- Icons now match shadcn/vue design system aesthetic
- Added visual feedback for selected theme mode in dropdown
- Improved dropdown styling with better spacing and transitions
- Icons use currentColor for proper theme-aware coloring

This provides a more polished and consistent UI experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replaced SVG innerHtml approach with proper lucide-angular components
- Uses <lucide-angular> component with name attribute (sun, moon, monitor)
- Icons now render as proper SVG components with full lucide library support
- Cleaner template syntax and better performance
- Icons properly inherit theme colors via currentColor

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Updated theme toggle to use lucide-angular icons (sun, moon, monitor)
- Applied text-primary class for icon visibility
- Added stroke-width attribute for better icon rendering
- Icons properly inherit theme colors in dropdown menu

Note: Icons may need further investigation for rendering visibility in light mode

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…rties

- Replace CSS class-based styling with lucide-angular's size and color properties
- Use [size]="20" and [size]="16" instead of Tailwind h-5 w-5 / h-4 w-4 classes
- Use color="currentColor" property instead of text-color CSS classes for better compatibility
- Use [strokeWidth]="2" property binding instead of string attribute
- Apply consistent styling pattern across all 6 icon instances in mode toggle

This follows the lucide-angular documentation for proper component usage.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Import Moon, Sun, Monitor icon components from lucide-angular
- Register only the icons used in this component via LucideAngularModule.pick()
- This enables tree-shaking and proper icon initialization
- Step 1 from lucide-angular documentation that was previously missing

The icons were not rendering because we weren't properly registering them
in the component's imports. Using LucideAngularModule.pick() ensures the
icons are available for the name-based rendering approach.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Use LucideAngularModule directly in component imports (works with standalone)
- Use color="currentColor" property for icon styling instead of CSS classes
- Use [size]="20" and [size]="16" for explicit sizing
- Use [strokeWidth]="2" property binding for stroke width
- Reverted from icon data import attempt (Moon/Sun/Monitor are data objects, not components)

The icons now properly inherit text color from parent buttons in both light and dark modes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Register Moon, Sun, Monitor icons in app.config.ts using LucideAngularModule.pick().providers
- Change component element selector from <lucide-angular> to <lucide-icon>
- Icons now properly provided to the icon provider at app startup
- Spreads module providers using ...LucideAngularModule.pick(...).providers! pattern

This fixes the "icon has not been provided by any available icon providers" error
by ensuring icons are registered in the application providers array at bootstrap time.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replace OKLCH colors with HSL colors to match Nuxt version
- Set primary color to bright blue: 217.2 91.2% 59.8% (same as Nuxt)
- Update all color variables in light and dark modes to match Nuxt design
- Update Tailwind config to use hsl() function for color values
- Card hover effect now uses blue ring instead of dark gray
- Price text is now displayed in bright blue

This ensures both Angular and Nuxt frontends have consistent design and styling.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Updated styles.css to use HSL color format directly in CSS variables instead of relying on Tailwind config
- Reverted tailwind.config.js to reference CSS variables with var() syntax
- Added z-40 stacking context to mode-toggle wrapper div for proper z-index layering
- Colors now match Nuxt frontend with bright blue primary (217.2 91.2% 59.8%)
- Dark mode switching now works correctly with proper CSS variable system

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Moved hover classes (hover:shadow-lg, hover:ring-2, hover:ring-primary) from custom z-card component to standard <a> tag
- This ensures Tailwind hover styles apply correctly since <a> is a standard HTML element
- Card now displays blue ring and shadow on hover, matching Nuxt frontend behavior
- Removed duplicate transition and cursor classes from z-card element

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replaced Tailwind ring classes with custom CSS rule for .coin-card:hover
- Added .coin-card class to card links for custom hover styling
- Used box-shadow with var(--primary) to create blue ring effect that matches Nuxt version
- Solves issue with Tailwind v4 not generating ring-color variants for CSS variables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Changed card padding from p-4 to p-3 for tighter spacing
- Reduced header bottom padding from pb-3 to pb-2
- Reduced card body top margin from mt-6 to mt-2
- Results in less whitespace at the top of cards, matching Nuxt design

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replaced border-t-primary Tailwind class with custom .loading-spinner class
- Added CSS rule to set border-top-color to var(--primary) (blue)
- Solves Tailwind v4 issue where border-color variants aren't generated for CSS variables
- Spinner now shows blue rotating border instead of grey

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Wrapped router-outlet in a <main> element with flex-1 class
- This makes the main content take up all available vertical space
- Footer now sticks to the bottom of the page, matching Nuxt layout
- Added text-foreground to root container for consistency
- Matches Nuxt app.vue layout structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Consolidated separate market data cards into a single card with grid layout
- Changed grid from 2 columns (md) to 4 columns (lg) for price info card
- Separated price range (low/high) into its own card below price info
- Updated header layout to show image on left with h-16 (from h-24)
- Added formatPercentage() and getPriceChangeClass() helper methods
- Updated card headers with proper styling and spacing
- Price changes now show green/red colors based on positive/negative values
- Layout now matches Nuxt version with 3 main cards instead of 5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
daniel-samson and others added 19 commits December 8, 2025 21:45
The detail endpoint returns image as an object with large/small/thumb properties, while the markets endpoint returns it as a string. Updated the model to support both formats and added normalizeImage() method to extract the URL string. This ensures the img src attribute receives a valid URL instead of [object Object].

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Created BreadcrumbComponent for reusable navigation breadcrumbs
- Updated coin detail page to display breadcrumbs instead of back button
- Breadcrumbs dynamically detect navigation source (search or home)
- When coming from search results, breadcrumb includes "Search Results" link that preserves the search query
- Breadcrumbs follow pattern: Home > [Search Results] > Coin Name

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Removed z-card component wrapper from search results
- Replaced with simple div using border, rounded-lg, overflow-hidden, and bg-card classes
- This fixes table column alignment and layout issues
- Cleaner table styling without extra card padding

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ements

- Changed from custom component tags (z-table, z-table-header, etc.) to attribute selectors on standard HTML elements (table[z-table], thead[z-table-header], etc.)
- Added border wrapper div with rounded-md and border classes
- Updated template to use semantic HTML: table, thead, tbody, tr, th, td
- Added hover:bg-accent/50 and cursor-pointer to table rows for interactive feedback
- Table now matches the ZardUI pattern and design system examples
- Changed table head padding from py-3 to py-4 to match body cells
- Removed h-12 from table head to allow natural alignment
- Now both header and body cells have identical px-6 py-4 padding for proper column alignment
- Document requirement to take screenshots when making style changes
- Emphasize need to verify component rendering in browser after CSS modifications
- Highlight importance of checking alignment, spacing, colors, and interactive states
- Applies to table layouts, card padding, hover states, and responsive changes
- Angular frontend (front-end-ng/): http://localhost:4200
- Nuxt frontend (front-end/): http://localhost:3000
- Update styling verification to reference correct dev server URL
Apply font-weight styling per ZardUI documentation pattern: remove font-semibold from headers and add font-medium to body cells for proper visual alignment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Use table-layout: fixed to ensure header and body cell columns align properly regardless of content width variations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
When using attribute selectors (table[z-table], tr[z-table-row], td[z-table-cell]), the components should only apply classes via host binding without creating duplicate wrapper elements. This fixes nested tr/td duplication in the rendered HTML.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Use ZardButtonComponent with secondary variant instead of plain text to create a proper button appearance with light and dark mode support.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…tates

- New LoadingSpinnerComponent at src/app/shared/components/loading-spinner/
- Uses Angular input signals for customizable message parameter
- Updated home.component.ts to use LoadingSpinnerComponent
- Updated search.component.ts to use LoadingSpinnerComponent
- Updated coin-detail.component.ts to use LoadingSpinnerComponent
- Fixed loading spinner template to properly invoke input signal with message()
- Ensures consistent loading UI across all pages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…th frontend options

- Comprehensive Angular frontend README with similar structure to Nuxt version
- Updated main README to include Angular as alternative frontend
- Quick Start section shows both Nuxt and Angular options
- Project Structure updated to reflect both frontends
- Technology Stack lists both frontend options with their respective tech
- Documentation section links to both frontend READMEs
- Development section includes testing and linting for both frontends

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Create frontend-ng-ci.yml workflow for automated testing and building
- Runs on push to main, develop, feature/*, and epic/* branches
- Runs on pull requests to main and develop
- Only triggers when front-end-ng directory is modified
- Includes linting, testing, coverage, and security checks
- Parallel jobs: test and code-quality with summary job
- Node.js 20.x for build compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add Frontend (Angular) CI badge linking to frontend-ng-ci.yml workflow
- Updated Frontend CI badge label to distinguish from Angular version
- All three badges (Backend, Frontend Nuxt, Frontend Angular) now displayed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@daniel-samson daniel-samson force-pushed the epic/angular-front-end branch from 369bf81 to 4c9f43b Compare December 8, 2025 23:03
daniel-samson added a commit that referenced this pull request Dec 8, 2025
Apply font-weight styling per ZardUI documentation pattern: remove font-semibold from headers and add font-medium to body cells for proper visual alignment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
daniel-samson added a commit that referenced this pull request Dec 8, 2025
Use table-layout: fixed to ensure header and body cell columns align properly regardless of content width variations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
daniel-samson added a commit that referenced this pull request Dec 8, 2025
When using attribute selectors (table[z-table], tr[z-table-row], td[z-table-cell]), the components should only apply classes via host binding without creating duplicate wrapper elements. This fixes nested tr/td duplication in the rendered HTML.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
daniel-samson added a commit that referenced this pull request Dec 8, 2025
Use ZardButtonComponent with secondary variant instead of plain text to create a proper button appearance with light and dark mode support.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
daniel-samson added a commit that referenced this pull request Dec 8, 2025
…tates

- New LoadingSpinnerComponent at src/app/shared/components/loading-spinner/
- Uses Angular input signals for customizable message parameter
- Updated home.component.ts to use LoadingSpinnerComponent
- Updated search.component.ts to use LoadingSpinnerComponent
- Updated coin-detail.component.ts to use LoadingSpinnerComponent
- Fixed loading spinner template to properly invoke input signal with message()
- Ensures consistent loading UI across all pages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@daniel-samson daniel-samson force-pushed the epic/angular-front-end branch 2 times, most recently from 445b2d2 to 90b6382 Compare December 8, 2025 23:07
- Fix Vitest configuration to disable watch mode in CI environment
- Update GitHub Actions workflow to use proper test commands with CI=true env var
- Remove invalid --run flag from npm test command
- Remove non-existent npm run lint command
- Tests now run in non-interactive mode in CI

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@daniel-samson daniel-samson merged commit 27863c6 into main Dec 8, 2025
9 checks passed
@daniel-samson daniel-samson deleted the epic/angular-front-end branch December 8, 2025 23:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants