Athena — mahmoud-consultancy/archive/old-docs/sprints/SPRINT4_DETAILED_EXECUTION_PLAN.md


title: Sprint 4 - Detailed Execution Plan date: 2025-10-15 status: Active tags: [sprint4, execution, tasks, implementation]

Sprint 4: Detailed Execution Plan

Duration: 2 weeks (Oct 16 - Nov 1, 2025) Goal: Production-ready UI with all critical issues fixed


Week 1: Critical Fixes (Oct 16-18)

Day 1 - Wednesday, Oct 16: SCSS Optimization

Goal: Fix all SCSS budget issues (CRITICAL - blocking production build)

Morning Session (4 hours)

Task 1.1: Optimize dashboard.scss (1 hour)

  • Current: 7.25 kB (exceeds 4 kB by 3.25 kB)
  • Target: <4 kB

Steps:

  1. Add imports for shared styles:
@import '../../../styles/shared/buttons';
@import '../../../styles/shared/cards';
  1. Remove duplicate button styles (lines 150-250)

  2. Remove duplicate card styles (lines 50-100)

  3. Extract chart styles to separate file:

    • Create _charts.scss in shared folder
    • Move bar chart, line chart styles
  4. Optimize stat-card styles:

    • Use CSS variables for repeated values
    • Combine similar media queries
  5. Test component still renders correctly

Task 1.2: Optimize application-form.scss (1.5 hours)

  • Current: 7.45 kB (exceeds 4 kB by 3.45 kB)
  • Target: <4 kB

Steps:

  1. Add import for shared forms:
@import '../../../styles/shared/forms';
@import '../../../styles/shared/buttons';
  1. Remove duplicate form-group styles (lines 20-80)

  2. Remove duplicate button styles (lines 300-400)

  3. Extract file upload styles to shared:

    • Create _file-upload.scss
    • Reusable for CV uploads
  4. Optimize validation error styles

  5. Combine media queries

  6. Test form validation still works

Task 1.3: Optimize job-detail.component.scss (1 hour)

  • Current: 6.16 kB (exceeds 4 kB by 2.16 kB)
  • Target: <4 kB

Steps:

  1. Add shared imports
  2. Remove duplicate card styles
  3. Remove duplicate button styles
  4. Extract job-meta styles to shared
  5. Optimize responsive layouts
  6. Test detail page renders correctly

Task 1.4: Optimize register.scss and job-list.scss (30 min each)

register.scss:

  • Current: 4.68 kB (exceeds by 683 bytes)
  • Target: <4 kB
  • Steps: Import shared forms, remove duplicate password strength styles

job-list.scss:

  • Current: 4.26 kB (exceeds by 264 bytes)
  • Target: <4 kB
  • Steps: Import shared cards, extract filter styles

Afternoon Session (4 hours)

Task 1.5: Create additional shared styles (1 hour)

Files to create:

src/styles/shared/
  _charts.scss          (for dashboard charts)
  _file-upload.scss     (for file uploads)
  _filters.scss         (for filter panels)
  _job-meta.scss        (for job metadata)
  _modals.scss          (for modal dialogs)

Task 1.6: Update angular.json for SCSS compression (30 min)

{
  "styles": {
    "input": "src/styles.scss",
    "bundleName": "styles",
    "inject": true
  },
  "stylePreprocessorOptions": {
    "includePaths": ["src/styles/shared"]
  }
}

Task 1.7: Build and verify (1 hour)

cd frontend/recruitment-portal
npm run build

Expected output:

✅ Compilation: SUCCESS
✅ SCSS Budgets: 0 warnings
✅ TypeScript: No errors

Task 1.8: Visual regression testing (1.5 hours)

  • Test all pages still look correct
  • Check all components
  • Verify responsive layouts
  • Test on Chrome, Firefox, Safari

End of Day 1 Deliverables:

  • ✅ All SCSS files under budget
  • ✅ Build succeeds without warnings
  • ✅ All components render correctly
  • ✅ Shared style library complete

Day 2 - Thursday, Oct 17: CV Upload Button

Goal: Add CV upload functionality to homepage

Morning Session (4 hours)

Task 2.1: Create cv-upload-button component (1.5 hours)

Generate component:

cd frontend/recruitment-portal/src/app/components/shared
ng generate component cv-upload-button --standalone

cv-upload-button.component.ts:

import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AuthService } from '../../../services/auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-cv-upload-button',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './cv-upload-button.component.html',
  styleUrl: './cv-upload-button.component.scss'
})
export class CvUploadButtonComponent {
  private authService = inject(AuthService);
  private router = inject(Router);

  onUploadClick(): void {
    if (this.authService.isAuthenticated()) {
      // Open CV upload modal
      // TODO: Implement modal
    } else {
      // Redirect to register with return URL
      this.router.navigate(['/register'], {
        queryParams: { returnUrl: '/profile', action: 'upload-cv' }
      });
    }
  }
}

cv-upload-button.component.html:

<button
  class="cv-upload-btn"
  (click)="onUploadClick()"
  type="button">
  <svg class="upload-icon" width="20" height="20" viewBox="0 0 20 20">
    <path d="M10 0L6 4h3v8h2V4h3L10 0z"/>
    <path d="M2 14h16v2H2v-2z"/>
  </svg>
  <span>Upload CV</span>
</button>

cv-upload-button.component.scss:

.cv-upload-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1.5rem;
  background: linear-gradient(135deg, #0d6efd 0%, #0a58ca 100%);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(13, 110, 253, 0.3);
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(13, 110, 253, 0.4);
  }

  .upload-icon {
    flex-shrink: 0;
    fill: currentColor;
  }
}

Task 2.2: Create cv-upload-modal component (2 hours)

Generate component:

ng generate component cv-upload-modal --standalone

cv-upload-modal.component.ts:

import { Component, EventEmitter, Output, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-cv-upload-modal',
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule],
  templateUrl: './cv-upload-modal.component.html',
  styleUrl: './cv-upload-modal.component.scss'
})
export class CvUploadModalComponent {
  @Output() close = new EventEmitter<void>();
  @Output() uploaded = new EventEmitter<void>();

  private fb = inject(FormBuilder);
  private http = inject(HttpClient);

  uploadForm = this.fb.group({
    file: [null, Validators.required],
    name: ['', Validators.required],
    email: ['', [Validators.required, Validators.email]],
    phone: ['']
  });

  selectedFile: File | null = null;
  uploading = false;
  uploadProgress = 0;

  onFileSelected(event: any): void {
    const file = event.target.files[0];
    if (file && this.isValidFile(file)) {
      this.selectedFile = file;
      this.uploadForm.patchValue({ file });
    }
  }

  isValidFile(file: File): boolean {
    const validTypes = ['application/pdf', 'application/msword',
                       'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
    const maxSize = 5 * 1024 * 1024; // 5MB

    return validTypes.includes(file.type) && file.size <= maxSize;
  }

  onSubmit(): void {
    if (this.uploadForm.valid && this.selectedFile) {
      this.uploading = true;
      const formData = new FormData();
      formData.append('cv', this.selectedFile);
      formData.append('name', this.uploadForm.value.name!);
      formData.append('email', this.uploadForm.value.email!);
      if (this.uploadForm.value.phone) {
        formData.append('phone', this.uploadForm.value.phone);
      }

      // TODO: Replace with actual API endpoint
      this.http.post('/api/cv/upload', formData, {
        reportProgress: true,
        observe: 'events'
      }).subscribe({
        next: (event: any) => {
          if (event.type === 1) { // UploadProgress
            this.uploadProgress = Math.round(100 * event.loaded / event.total);
          } else if (event.type === 4) { // Response
            this.uploaded.emit();
            this.onClose();
          }
        },
        error: (error) => {
          console.error('Upload failed:', error);
          this.uploading = false;
        }
      });
    }
  }

  onClose(): void {
    this.close.emit();
  }
}

Task 2.3: Integrate with job-list component (30 min)

job-list.component.html (add near search bar):

<div class="header-actions">
  <div class="search-bar">
    <!-- Existing search -->
  </div>
  <app-cv-upload-button></app-cv-upload-button>
</div>

<!-- Add modal -->
<app-cv-upload-modal
  *ngIf="showCvModal"
  (close)="showCvModal = false"
  (uploaded)="onCvUploaded()">
</app-cv-upload-modal>

job-list.component.ts:

// Add imports
import { CvUploadButtonComponent } from '../shared/cv-upload-button/cv-upload-button.component';
import { CvUploadModalComponent } from '../shared/cv-upload-modal/cv-upload-modal.component';

// Add to imports array
imports: [
  // ... existing imports
  CvUploadButtonComponent,
  CvUploadModalComponent
]

// Add property
showCvModal = false;

// Add method
onCvUploaded(): void {
  this.toastService.show('CV succesvol geüpload!', 'success');
}

Afternoon Session (4 hours)

Task 2.4: Style CV upload modal (1 hour)

  • Responsive design
  • File drop zone
  • Progress bar
  • Error states
  • Success message

Task 2.5: Add validation and error handling (1 hour)

  • File type validation (PDF, DOC, DOCX)
  • File size validation (max 5MB)
  • Network error handling
  • User-friendly error messages

Task 2.6: Testing (2 hours)

  • Test authenticated user flow
  • Test unauthenticated user flow
  • Test file validation
  • Test upload progress
  • Test error scenarios
  • Mobile responsive testing

End of Day 2 Deliverables:

  • ✅ CV upload button visible on homepage
  • ✅ CV upload modal functional
  • ✅ Authentication flow working
  • ✅ File validation working
  • ✅ Mobile responsive

Day 3 - Friday, Oct 18: Testing & Verification

Goal: Comprehensive testing of all Sprint 4 Week 1 work

Morning Session (4 hours)

Task 3.1: Build verification (1 hour)

# Clean build
npm run build

# Check bundle sizes
# Verify no warnings
# Test production build locally

Task 3.2: Cross-browser testing (2 hours)

Browsers to test:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Test checklist per browser:

  • [ ] Homepage loads correctly
  • [ ] CV upload button visible
  • [ ] CV upload modal opens
  • [ ] File selection works
  • [ ] Form validation works
  • [ ] Upload progress shows
  • [ ] All components render correctly
  • [ ] No console errors

Task 3.3: Mobile device testing (1 hour)

Devices:

  • iPhone (Safari)
  • Android (Chrome)
  • Tablet (iPad)

Test:

  • [ ] CV upload button touch-friendly
  • [ ] Modal fits on screen
  • [ ] File selection works on mobile
  • [ ] Forms usable on mobile

Afternoon Session (4 hours)

Task 3.4: Regression testing (2 hours)

Test all major flows:

  • [ ] User registration
  • [ ] User login
  • [ ] Job browsing
  • [ ] Job search/filter
  • [ ] Job application
  • [ ] Application history
  • [ ] Admin dashboard (if admin role)

Task 3.5: Performance testing (1 hour)

  • Lighthouse audit
  • Bundle size analysis
  • Page load times
  • Time to interactive

Task 3.6: Documentation updates (1 hour)

  • Update README with new features
  • Document CV upload flow
  • Update user guide
  • Create admin guide for CV management

End of Day 3 Deliverables:

  • ✅ All tests passing
  • ✅ Build successful
  • ✅ Cross-browser compatible
  • ✅ Mobile responsive verified
  • ✅ Documentation updated

Week 2: Polish & Enhancement (Oct 21-25)

Day 4 - Monday, Oct 21: Admin Navigation

Goal: Create comprehensive admin navigation component

Morning Session (4 hours)

Task 4.1: Create admin-nav component (2 hours)

Generate:

ng generate component components/admin/admin-nav --standalone

admin-nav.component.ts:

import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Router } from '@angular/router';
import { AuthService } from '../../../services/auth.service';

interface NavItem {
  label: string;
  route: string;
  icon: string;
}

@Component({
  selector: 'app-admin-nav',
  standalone: true,
  imports: [CommonModule, RouterModule],
  templateUrl: './admin-nav.component.html',
  styleUrl: './admin-nav.component.scss'
})
export class AdminNavComponent {
  private authService = inject(AuthService);
  private router = inject(Router);

  menuOpen = false;

  navItems: NavItem[] = [
    { label: 'Dashboard', route: '/admin/dashboard', icon: '📊' },
    { label: 'Gebruikers', route: '/admin/users', icon: '👥' },
    { label: 'Vacatures', route: '/admin/jobs', icon: '💼' },
    { label: 'Sollicitaties', route: '/admin/applications', icon: '📝' }
  ];

  get currentUser() {
    return this.authService.currentUser();
  }

  toggleMenu(): void {
    this.menuOpen = !this.menuOpen;
  }

  logout(): void {
    this.authService.logout();
    this.router.navigate(['/login']);
  }
}

Task 4.2: Add breadcrumb navigation (1 hour)

Create breadcrumb service:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

export interface Breadcrumb {
  label: string;
  url: string;
}

@Injectable({ providedIn: 'root' })
export class BreadcrumbService {
  private breadcrumbsSubject = new BehaviorSubject<Breadcrumb[]>([]);
  breadcrumbs$ = this.breadcrumbsSubject.asObservable();

  setBreadcrumbs(breadcrumbs: Breadcrumb[]): void {
    this.breadcrumbsSubject.next(breadcrumbs);
  }
}

Task 4.3: Style admin navigation (1 hour)

  • Sidebar design
  • Active route highlighting
  • User menu dropdown
  • Mobile hamburger menu
  • Smooth animations

Afternoon Session (4 hours)

Task 4.4: Integrate with all admin pages (2 hours)

  • Add to dashboard
  • Add to users page
  • Add to jobs page
  • Add to applications page
  • Test navigation between pages

Task 4.5: Mobile responsive admin nav (1 hour)

  • Collapsible sidebar on mobile
  • Touch-friendly menu items
  • Proper z-index layering

Task 4.6: Testing (1 hour)

  • Test all navigation links
  • Test user menu
  • Test logout
  • Test breadcrumbs
  • Test mobile menu

Day 5 - Tuesday, Oct 22: Mobile Responsiveness

Goal: Fix all mobile responsive issues

All Day (8 hours)

Task 5.1: Admin Dashboard Mobile (2 hours)

  • Statistics cards stack properly
  • Charts readable on small screens
  • Tables scroll horizontally
  • Actions accessible

Task 5.2: Job Listings Mobile (2 hours)

  • Filter panel collapsible
  • Job cards optimized for mobile
  • Search bar full-width
  • Pagination usable

Task 5.3: Forms Mobile (2 hours)

  • Application form single column
  • File upload works on mobile
  • Validation messages visible
  • Submit button accessible

Task 5.4: Modal Dialogs Mobile (1 hour)

  • Modals fit viewport
  • Scroll within modal
  • Close button accessible
  • Actions visible

Task 5.5: Final Mobile Testing (1 hour)

  • Test on real devices
  • Test landscape orientation
  • Test various screen sizes
  • Fix any remaining issues

Day 6 - Wednesday, Oct 23: Accessibility

Goal: WCAG 2.1 AA compliance

All Day (8 hours)

Task 6.1: Alt text and labels (2 hours)

  • Add alt text to all images
  • Add aria-labels to icons
  • Add labels to all form inputs
  • Add descriptions to links

Task 6.2: Keyboard navigation (2 hours)

  • Test tab order
  • Add focus indicators
  • Ensure all actions keyboard-accessible
  • Add skip links

Task 6.3: Color contrast (2 hours)

  • Audit all text colors
  • Fix low-contrast combinations
  • Test with color blindness simulator
  • Ensure sufficient contrast ratios

Task 6.4: Screen reader testing (2 hours)

  • Test with NVDA (Windows)
  • Test with VoiceOver (Mac)
  • Fix semantic HTML issues
  • Add ARIA attributes where needed

Day 7 - Thursday, Oct 24: Performance

Goal: Optimize performance

All Day (8 hours)

Task 7.1: Bundle size optimization (3 hours)

  • Run webpack-bundle-analyzer
  • Remove unused dependencies
  • Enable tree shaking
  • Code splitting
  • Lazy load admin routes

Task 7.2: Image optimization (2 hours)

  • Compress all images
  • Add responsive images
  • Implement lazy loading
  • Add loading placeholders

Task 7.3: Caching strategy (2 hours)

  • Add service worker (optional)
  • Configure HTTP caching headers
  • Implement browser caching
  • Test offline capability

Task 7.4: Performance testing (1 hour)

  • Run Lighthouse audits
  • Measure Core Web Vitals
  • Test on slow network
  • Optimize based on results

Day 8 - Friday, Oct 25: Final Testing & Documentation

Goal: Complete Sprint 4

Morning Session (4 hours)

Task 8.1: Final bug fixes (2 hours)

  • Review and fix all known bugs
  • Test edge cases
  • Regression testing

Task 8.2: Final cross-browser testing (2 hours)

  • Chrome, Firefox, Safari, Edge
  • Test all critical flows
  • Document any browser-specific issues

Afternoon Session (4 hours)

Task 8.3: Documentation (3 hours)

Update:

  • README.md (new features)
  • User guide (CV upload, navigation)
  • Admin guide (new navigation)
  • Developer guide (shared styles, components)
  • Deployment guide

Task 8.4: Sprint 4 retrospective (1 hour)

  • What went well
  • What could be improved
  • Lessons learned
  • Prepare for Sprint 5

Deliverables Summary

Week 1 Deliverables

  • ✅ SCSS budget fixed (all files <4 kB)
  • ✅ Shared style library
  • ✅ CV upload button on homepage
  • ✅ CV upload modal functional
  • ✅ Build successful without warnings
  • ✅ Cross-browser tested
  • ✅ Mobile responsive

Week 2 Deliverables

  • ✅ Admin navigation component
  • ✅ Breadcrumb navigation
  • ✅ Mobile responsive (all pages)
  • ✅ WCAG 2.1 AA compliant
  • ✅ Performance optimized
  • ✅ Documentation complete
  • ✅ All bugs fixed

Success Criteria

Sprint 4 is complete when:

  • ✅ npm run build succeeds with 0 warnings
  • ✅ All Lighthouse scores > 90
  • ✅ Mobile responsive (320px - 1920px)
  • ✅ WCAG 2.1 AA compliant
  • ✅ Cross-browser compatible
  • ✅ All critical bugs fixed
  • ✅ Documentation updated
  • ✅ Ready for Sprint 5

Estimated Total Hours: 80 hours (2 weeks × 40 hours) Actual Timeline: Oct 16 - Nov 1, 2025 Next: Sprint 5 (Knowledge Base) starts Nov 4, 2025

Reacties

Nog geen reacties