Add codebase cleanup and SVG report
This commit is contained in:
parent
a04d48e549
commit
d4caad10a3
2 changed files with 404 additions and 0 deletions
186
SVG_ANALYSIS_REPORT.md
Normal file
186
SVG_ANALYSIS_REPORT.md
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
# SVG Usage Analysis Report
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This analysis examines SVG usage patterns in the Svelte 5 codebase to identify optimization opportunities, inconsistencies, and unused assets.
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
### 1. Inline SVGs vs. Imported SVGs
|
||||||
|
|
||||||
|
**Inline SVGs Found:**
|
||||||
|
- **Close/X buttons**: Found in 7+ components with identical SVG code
|
||||||
|
- `admin/Modal.svelte`
|
||||||
|
- `admin/UnifiedMediaModal.svelte`
|
||||||
|
- `admin/MediaInput.svelte`
|
||||||
|
- `admin/AlbumSelectorModal.svelte`
|
||||||
|
- `admin/GalleryManager.svelte`
|
||||||
|
- `admin/MediaDetailsModal.svelte`
|
||||||
|
- `Lightbox.svelte`
|
||||||
|
|
||||||
|
- **Loading spinners**: Found in 2+ components
|
||||||
|
- `admin/Button.svelte`
|
||||||
|
- `admin/ImageUploader.svelte`
|
||||||
|
- `admin/GalleryUploader.svelte`
|
||||||
|
|
||||||
|
- **Navigation arrows**: Found in `PhotoLightbox.svelte`
|
||||||
|
- **Lock icon**: Found in `LabCard.svelte`
|
||||||
|
- **External link icon**: Found in `LabCard.svelte`
|
||||||
|
|
||||||
|
### 2. SVG Import Patterns
|
||||||
|
|
||||||
|
**Consistent patterns using aliases:**
|
||||||
|
```svelte
|
||||||
|
// Good - using $icons alias
|
||||||
|
import ArrowLeft from '$icons/arrow-left.svg'
|
||||||
|
import ChevronDownIcon from '$icons/chevron-down.svg'
|
||||||
|
|
||||||
|
// Component imports with ?component
|
||||||
|
import PhotosIcon from '$icons/photos.svg?component'
|
||||||
|
import ViewSingleIcon from '$icons/view-single.svg?component'
|
||||||
|
|
||||||
|
// Raw imports
|
||||||
|
import ChevronDownIcon from '$icons/chevron-down.svg?raw'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Unused SVG Files
|
||||||
|
|
||||||
|
**Unused icons in `/src/assets/icons/`:**
|
||||||
|
- `dashboard.svg`
|
||||||
|
- `metadata.svg`
|
||||||
|
|
||||||
|
**Unused illustrations in `/src/assets/illos/`:**
|
||||||
|
- `jedmund-blink.svg`
|
||||||
|
- `jedmund-headphones.svg`
|
||||||
|
- `jedmund-listening-downbeat.svg`
|
||||||
|
- `jedmund-listening.svg`
|
||||||
|
- `jedmund-open.svg`
|
||||||
|
- `jedmund-signing-downbeat.svg`
|
||||||
|
- `jedmund-singing.svg`
|
||||||
|
- `logo-figma.svg`
|
||||||
|
- `logo-maitsu.svg`
|
||||||
|
- `logo-pinterest.svg`
|
||||||
|
- `logo-slack.svg`
|
||||||
|
|
||||||
|
### 4. Duplicate SVG Definitions
|
||||||
|
|
||||||
|
**Close/X Button SVG** (appears 7+ times):
|
||||||
|
```svg
|
||||||
|
<path d="M6 6L18 18M6 18L18 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Loading Spinner SVG** (appears 3+ times):
|
||||||
|
```svg
|
||||||
|
<svg class="spinner" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-dasharray="25" stroke-dashoffset="25" stroke-linecap="round">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" from="0 12 12" to="360 12 12" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. SVGs That Could Be Componentized
|
||||||
|
|
||||||
|
1. **Close Button**: Used across multiple modals and components
|
||||||
|
2. **Loading Spinner**: Used in buttons and upload components
|
||||||
|
3. **Navigation Arrows**: Used in lightbox and potentially other navigation
|
||||||
|
4. **Status Icons**: Lock, external link, eye icons in LabCard
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
### 1. Create Reusable Icon Components
|
||||||
|
|
||||||
|
**Option A: Create individual icon components**
|
||||||
|
```svelte
|
||||||
|
<!-- $lib/components/icons/CloseIcon.svelte -->
|
||||||
|
<script>
|
||||||
|
let { size = 24, class: className = '' } = $props()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" class={className}>
|
||||||
|
<path d="M6 6L18 18M6 18L18 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option B: Create an Icon component with name prop**
|
||||||
|
```svelte
|
||||||
|
<!-- $lib/components/Icon.svelte -->
|
||||||
|
<script>
|
||||||
|
import CloseIcon from '$icons/close.svg'
|
||||||
|
import LoadingIcon from '$icons/loading.svg'
|
||||||
|
// ... other imports
|
||||||
|
|
||||||
|
let { name, size = 24, class: className = '' } = $props()
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
close: CloseIcon,
|
||||||
|
loading: LoadingIcon,
|
||||||
|
// ... other icons
|
||||||
|
}
|
||||||
|
|
||||||
|
const IconComponent = $derived(icons[name])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if IconComponent}
|
||||||
|
<IconComponent {size} class={className} />
|
||||||
|
{/if}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Extract Inline SVGs to Files
|
||||||
|
|
||||||
|
Create new SVG files for commonly used inline SVGs:
|
||||||
|
- `/src/assets/icons/close.svg`
|
||||||
|
- `/src/assets/icons/loading.svg`
|
||||||
|
- `/src/assets/icons/external-link.svg`
|
||||||
|
- `/src/assets/icons/lock.svg`
|
||||||
|
- `/src/assets/icons/eye-off.svg`
|
||||||
|
|
||||||
|
### 3. Clean Up Unused Assets
|
||||||
|
|
||||||
|
Remove the following unused files to reduce bundle size:
|
||||||
|
- All unused illustration files (11 files)
|
||||||
|
- Unused icon files (2 files)
|
||||||
|
|
||||||
|
### 4. Standardize Import Methods
|
||||||
|
|
||||||
|
Establish a consistent pattern:
|
||||||
|
- Use `?component` for SVGs used as Svelte components
|
||||||
|
- Use direct imports for SVGs used as images
|
||||||
|
- Avoid `?raw` imports unless necessary
|
||||||
|
|
||||||
|
### 5. Create a Loading Component
|
||||||
|
|
||||||
|
```svelte
|
||||||
|
<!-- $lib/components/LoadingSpinner.svelte -->
|
||||||
|
<script>
|
||||||
|
let { size = 24, class: className = '' } = $props()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg class="loading-spinner {className}" width={size} height={size} viewBox="0 0 24 24">
|
||||||
|
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"
|
||||||
|
stroke-dasharray="25" stroke-dashoffset="25" stroke-linecap="round">
|
||||||
|
<animateTransform attributeName="transform" type="rotate"
|
||||||
|
from="0 12 12" to="360 12 12" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.loading-spinner {
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits of These Changes
|
||||||
|
|
||||||
|
1. **Reduced code duplication**: Eliminate 20+ duplicate SVG definitions
|
||||||
|
2. **Smaller bundle size**: Remove 13 unused SVG files
|
||||||
|
3. **Better maintainability**: Centralized icon management
|
||||||
|
4. **Consistent styling**: Easier to apply consistent styles to all icons
|
||||||
|
5. **Type safety**: With proper component props
|
||||||
|
6. **Performance**: Less inline SVG parsing, better caching
|
||||||
|
|
||||||
|
## Implementation Priority
|
||||||
|
|
||||||
|
1. **High Priority**: Extract and componentize duplicate inline SVGs (close button, loading spinner)
|
||||||
|
2. **Medium Priority**: Remove unused SVG files
|
||||||
|
3. **Low Priority**: Standardize all import patterns and create comprehensive icon system
|
||||||
218
prd/PRD-codebase-cleanup-refactoring.md
Normal file
218
prd/PRD-codebase-cleanup-refactoring.md
Normal file
|
|
@ -0,0 +1,218 @@
|
||||||
|
# PRD: Codebase Cleanup and Refactoring
|
||||||
|
|
||||||
|
**Date**: December 26, 2025
|
||||||
|
**Author**: Claude Code
|
||||||
|
**Status**: Draft
|
||||||
|
**Priority**: High
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
This PRD outlines a comprehensive cleanup and refactoring plan for the jedmund-svelte Svelte 5 codebase. The analysis has identified significant opportunities to reduce code complexity, eliminate duplication, and improve maintainability through systematic refactoring.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
1. **Simplify overengineered components** - Break down complex components into smaller, focused units
|
||||||
|
2. **Eliminate dead code** - Remove unused components, functions, and imports
|
||||||
|
3. **Reduce code duplication** - Extract common patterns into reusable components and utilities
|
||||||
|
4. **Standardize styling** - Convert hardcoded values to CSS variables and create consistent patterns
|
||||||
|
5. **Optimize SVG usage** - Remove unused SVGs and create reusable icon components
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
### 1. Overengineered Components
|
||||||
|
- **EnhancedComposer** (1,347 lines) - Handles too many responsibilities
|
||||||
|
- **LastFM Stream Server** (625 lines) - Complex data transformations that could be simplified
|
||||||
|
- **Multiple Media Modals** - Overlapping functionality across 3+ modal components
|
||||||
|
- **Complex State Management** - Components with 10-20 state variables
|
||||||
|
|
||||||
|
### 2. Unused Code
|
||||||
|
- 5 unused components (Squiggly, PhotoLightbox, Pill, SVGHoverEffect, MusicPreview)
|
||||||
|
- 13 unused SVG files (2 icons, 11 illustrations)
|
||||||
|
- Minimal commented-out code (good!)
|
||||||
|
- 1 potentially unused API endpoint (/api/health)
|
||||||
|
|
||||||
|
### 3. DRY Violations
|
||||||
|
- **Photo Grid Components** - 3 nearly identical components
|
||||||
|
- **Modal Components** - Duplicate backdrop and positioning logic
|
||||||
|
- **Dropdown Components** - Repeated dropdown patterns
|
||||||
|
- **Form Components** - Overlapping FormField and FormFieldWrapper
|
||||||
|
- **Segmented Controllers** - Duplicate animation and positioning logic
|
||||||
|
|
||||||
|
### 4. Hardcoded Values
|
||||||
|
- **Colors**: 200+ hardcoded hex/rgba values instead of using existing variables
|
||||||
|
- **Spacing**: 1,000+ hardcoded pixel values instead of using `$unit` system
|
||||||
|
- **Z-indexes**: 60+ hardcoded z-index values without consistent scale
|
||||||
|
- **Animations**: Hardcoded durations instead of using constants
|
||||||
|
- **Border radius**: Not using existing `$corner-radius-*` variables
|
||||||
|
|
||||||
|
### 5. SVG Issues
|
||||||
|
- 7+ duplicate inline close button SVGs
|
||||||
|
- 3+ duplicate loading spinner SVGs
|
||||||
|
- Inconsistent import patterns
|
||||||
|
- Inline SVGs that should be componentized
|
||||||
|
|
||||||
|
## Implementation Timeline
|
||||||
|
|
||||||
|
### Phase 1: Quick Wins (Week 1)
|
||||||
|
Focus on low-risk, high-impact changes that don't require architectural modifications.
|
||||||
|
|
||||||
|
- [ ] **Remove unused components** (5 components)
|
||||||
|
- [ ] Delete `/src/lib/components/Squiggly.svelte`
|
||||||
|
- [ ] Delete `/src/lib/components/PhotoLightbox.svelte`
|
||||||
|
- [ ] Delete `/src/lib/components/Pill.svelte`
|
||||||
|
- [ ] Delete `/src/lib/components/SVGHoverEffect.svelte`
|
||||||
|
- [ ] Delete `/src/lib/components/MusicPreview.svelte`
|
||||||
|
|
||||||
|
- [ ] **Remove unused SVG files** (13 files)
|
||||||
|
- [ ] Delete unused icons: `close.svg`, `music.svg`
|
||||||
|
- [ ] Delete unused illustrations (11 files - see SVG analysis report)
|
||||||
|
|
||||||
|
- [ ] **Clean up dead code**
|
||||||
|
- [ ] Remove commented `getWeeklyAlbumChart` line in `/src/routes/api/lastfm/+server.ts`
|
||||||
|
- [ ] Address TODO in `/src/lib/server/api-utils.ts` about authentication
|
||||||
|
|
||||||
|
### Phase 2: CSS Variable Standardization (Week 2)
|
||||||
|
Create a consistent design system by extracting hardcoded values.
|
||||||
|
|
||||||
|
- [ ] **Create z-index system**
|
||||||
|
- [ ] Create `src/assets/styles/_z-index.scss` with constants
|
||||||
|
- [ ] Replace 60+ hardcoded z-index values
|
||||||
|
|
||||||
|
- [ ] **Extract color variables**
|
||||||
|
- [ ] Add missing color variables for frequently used colors
|
||||||
|
- [ ] Replace 200+ hardcoded hex/rgba values
|
||||||
|
- [ ] Create shadow/overlay variables for rgba values
|
||||||
|
|
||||||
|
- [ ] **Standardize spacing**
|
||||||
|
- [ ] Add missing unit multipliers (`$unit-1.75x`, etc.)
|
||||||
|
- [ ] Replace 1,000+ hardcoded pixel values with unit variables
|
||||||
|
|
||||||
|
- [ ] **Define animation constants**
|
||||||
|
- [ ] Create transition/animation duration variables
|
||||||
|
- [ ] Replace hardcoded duration values
|
||||||
|
|
||||||
|
### Phase 3: Component Refactoring (Weeks 3-4)
|
||||||
|
Refactor components to reduce duplication and complexity.
|
||||||
|
|
||||||
|
- [ ] **Create base components**
|
||||||
|
- [ ] Extract `BaseModal` component for shared modal logic
|
||||||
|
- [ ] Create `BaseDropdown` for dropdown patterns
|
||||||
|
- [ ] Merge `FormField` and `FormFieldWrapper`
|
||||||
|
- [ ] Create `BaseSegmentedController` for shared logic
|
||||||
|
|
||||||
|
- [ ] **Refactor photo grids**
|
||||||
|
- [ ] Create unified `PhotoGrid` component with `columns` prop
|
||||||
|
- [ ] Remove 3 duplicate grid components
|
||||||
|
- [ ] Use composition for layout variations
|
||||||
|
|
||||||
|
- [ ] **Componentize inline SVGs**
|
||||||
|
- [ ] Create `CloseButton` icon component
|
||||||
|
- [ ] Create `LoadingSpinner` component
|
||||||
|
- [ ] Create `NavigationArrow` components
|
||||||
|
- [ ] Extract other repeated inline SVGs
|
||||||
|
|
||||||
|
### Phase 4: Complex Refactoring (Weeks 5-6)
|
||||||
|
Tackle the most complex components and patterns.
|
||||||
|
|
||||||
|
- [ ] **Refactor EnhancedComposer**
|
||||||
|
- [ ] Split into focused sub-components
|
||||||
|
- [ ] Extract toolbar component
|
||||||
|
- [ ] Separate media management
|
||||||
|
- [ ] Create dedicated link editor
|
||||||
|
- [ ] Reduce state variables from 20+ to <10
|
||||||
|
|
||||||
|
- [ ] **Simplify LastFM Stream Server**
|
||||||
|
- [ ] Extract data transformation utilities
|
||||||
|
- [ ] Simplify "now playing" detection algorithm
|
||||||
|
- [ ] Reduce state tracking duplication
|
||||||
|
- [ ] Create separate modules for complex logic
|
||||||
|
|
||||||
|
- [ ] **Consolidate media modals**
|
||||||
|
- [ ] Create single flexible MediaModal component
|
||||||
|
- [ ] Use composition for different modes
|
||||||
|
- [ ] Eliminate prop drilling with stores
|
||||||
|
|
||||||
|
### Phase 5: Architecture & Utilities (Week 7)
|
||||||
|
Improve overall architecture and create shared utilities.
|
||||||
|
|
||||||
|
- [ ] **Create shared utilities**
|
||||||
|
- [ ] API client with consistent error handling
|
||||||
|
- [ ] CSS mixins for common patterns
|
||||||
|
- [ ] Media handling utilities
|
||||||
|
- [ ] Form validation utilities
|
||||||
|
|
||||||
|
- [ ] **Standardize patterns**
|
||||||
|
- [ ] Create middleware for API routes
|
||||||
|
- [ ] Implement consistent error handling
|
||||||
|
- [ ] Standardize data fetching patterns
|
||||||
|
- [ ] Create shared animation definitions
|
||||||
|
|
||||||
|
### Phase 6: Testing & Documentation (Week 8)
|
||||||
|
Ensure changes don't break functionality and document new patterns.
|
||||||
|
|
||||||
|
- [ ] **Testing**
|
||||||
|
- [ ] Run full build and type checking
|
||||||
|
- [ ] Test all refactored components
|
||||||
|
- [ ] Verify no regressions in functionality
|
||||||
|
- [ ] Check bundle size improvements
|
||||||
|
|
||||||
|
- [ ] **Documentation**
|
||||||
|
- [ ] Update component documentation
|
||||||
|
- [ ] Document new patterns and utilities
|
||||||
|
- [ ] Update Storybook stories for new components
|
||||||
|
- [ ] Create migration guide for team
|
||||||
|
|
||||||
|
## Success Metrics
|
||||||
|
|
||||||
|
1. **Code Reduction**
|
||||||
|
- Target: 20-30% reduction in total lines of code
|
||||||
|
- Eliminate 1,000+ instances of code duplication
|
||||||
|
|
||||||
|
2. **Component Simplification**
|
||||||
|
- No component larger than 500 lines
|
||||||
|
- Average component size under 200 lines
|
||||||
|
|
||||||
|
3. **Design System Consistency**
|
||||||
|
- Zero hardcoded colors in components
|
||||||
|
- All spacing using design tokens
|
||||||
|
- Consistent z-index scale
|
||||||
|
|
||||||
|
4. **Bundle Size**
|
||||||
|
- 10-15% reduction in JavaScript bundle size
|
||||||
|
- Removal of unused assets
|
||||||
|
|
||||||
|
5. **Developer Experience**
|
||||||
|
- Faster build times
|
||||||
|
- Easier component discovery
|
||||||
|
- Reduced cognitive load
|
||||||
|
|
||||||
|
## Risk Mitigation
|
||||||
|
|
||||||
|
1. **Regression Testing**
|
||||||
|
- Test each phase thoroughly before moving to next
|
||||||
|
- Keep backups of original components during refactoring
|
||||||
|
- Use feature flags for gradual rollout if needed
|
||||||
|
|
||||||
|
2. **Performance Impact**
|
||||||
|
- Monitor bundle size after each phase
|
||||||
|
- Profile component render performance
|
||||||
|
- Ensure no performance regressions
|
||||||
|
|
||||||
|
3. **Team Coordination**
|
||||||
|
- Communicate changes clearly
|
||||||
|
- Update documentation as you go
|
||||||
|
- Create clear migration paths
|
||||||
|
|
||||||
|
## Rollback Plan
|
||||||
|
|
||||||
|
Each phase should be implemented as a separate git branch with the ability to revert if issues arise. Keep the old components available until the new ones are fully tested and stable.
|
||||||
|
|
||||||
|
## Appendix
|
||||||
|
|
||||||
|
- [SVG Analysis Report](/Users/justin/Developer/Personal/jedmund-svelte/SVG_ANALYSIS_REPORT.md) - Detailed SVG usage analysis
|
||||||
|
- [Component Analysis](#) - Detailed breakdown of component complexity
|
||||||
|
- [CSS Variable Audit](#) - Complete list of hardcoded values to replace
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Next Steps**: Review this PRD and approve the implementation timeline. Each phase can be tracked using the checkboxes above.
|
||||||
Loading…
Reference in a new issue