Skip to content

Optimize Legal Components (Copyrights, Privacy & Security, Terms of Use) #1

@danieldanielecki

Description

@danieldanielecki

Please find below of what Cursor Pro has been recommended (with Auto agent mode).

Legal Components Refactoring - Technical Analysis

Current Components

  • src/app/components/copyrights/copyrights.component.ts
  • src/app/components/terms-of-use/terms-of-use.component.ts
  • src/app/components/privacy-and-security/privacy-and-security.component.ts

Identical Code Patterns

Imports & Dependencies

import * as AOS from "aos";
import { Component, OnInit } from "@angular/core";
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { MatCardModule } from '@angular/material/card';
import { Legal } from '../../interfaces';

Component Configuration

@Component({
  selector: "app-[component-name]",
  templateUrl: "./[component-name].component.html",
  styleUrls: ["./[component-name].component.scss"],
  standalone: true,
  imports: [CommonModule, RouterModule, MatCardModule]
})

Data Structure

sections: Legal[] = [
  {
    title: string,
    content: string,
    ariaLabel: string,
    delay: number,
    hasLinks: boolean
  }
  // ... more sections
];

Lifecycle Method

public ngOnInit() {
  AOS.init(); // Initialize Animate on Scroll (AOS) library.
}

Interface Definition

// src/app/interfaces/legal.interface.ts
export interface Legal {
  ariaLabel: string;
  content: string;
  delay: number;
  hasLinks?: boolean;
  title: string;
}

HTML Template Structure

All components share identical HTML structure:

<section [attr.aria-label]="page-specific-aria-label">
  <mat-card class="mat-elevation-z24" role="region">
    <mat-card-title aria-level="1" role="heading">{{ pageTitle }}</mat-card-title>
    <mat-card-subtitle aria-level="3" role="heading">{{ pageSubtitle }}</mat-card-subtitle>
    <mat-card-content role="complementary">
      <div *ngFor="let section of sections">
        <h3 [attr.aria-label]="section.ariaLabel"
            data-aos="fade-up"
            [attr.data-aos-delay]="section.delay"
            data-aos-duration="1500">
          {{ section.title }}
        </h3>
        <div data-aos="fade-up"
             [attr.data-aos-delay]="section.delay"
             data-aos-duration="1500"
             role="region">
          <ng-container *ngIf="section.hasLinks; else regularContent">
            <!-- Component-specific content with ngSwitch -->
          </ng-container>
          <ng-template #regularContent>
            <p [innerHTML]="section.content"></p>
          </ng-template>
        </div>
      </div>
    </mat-card-content>
  </mat-card>
</section>

Content Complexity Analysis

hasLinks: true Sections

  • NOT simple links - contain complex, unique HTML content
  • Use ngSwitch based on section.title
  • Each component has different content for the same section titles
  • Include routing links, formatted text, and component-specific information

hasLinks: false Sections

  • Simple content stored in section.content
  • Rendered via [innerHTML] binding

Proposed Solutions

Option 1: Abstract Base Class (Recommended)

import * as AOS from "aos";
import { Component, OnInit } from "@angular/core";
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { MatCardModule } from '@angular/material/card';
import { Legal } from '../../interfaces';

export abstract class BaseLegalComponent implements OnInit {
  abstract sections: Legal[];
  abstract pageTitle: string;
  abstract pageSubtitle: string;
  abstract pageAriaLabel: string;

  ngOnInit() {
    AOS.init();
  }
}

Then each component extends it:

@Component({
  // ... existing component config ...
})
export class CopyrightsComponent extends BaseLegalComponent {
  override sections: Legal[] = [
    // ... existing sections ...
  ];
  
  override pageTitle = 'Copyrights';
  override pageSubtitle = 'Before you copy anything from us kindly please read it carefully.';
  override pageAriaLabel = 'This is a copyrights page to inform your about our copyrights.';
}

Option 2: Shared Service + Component Composition

@Component({
  selector: 'app-legal-content',
  template: `
    <section [attr.aria-label]="pageAriaLabel">
      <mat-card [attr.aria-label]="cardAriaLabel" class="mat-elevation-z24" role="region">
        <mat-card-title aria-level="1" [title]="pageTitle" role="heading">
          {{ pageTitle }}
        </mat-card-title>
        <mat-card-subtitle aria-level="3" role="heading">
          {{ pageSubtitle }}
        </mat-card-subtitle>
        <mat-card-content role="complementary">
          <!-- ... rest of the template ... -->
        </mat-card-content>
      </mat-card>
    </section>
  `,
  standalone: true,
  imports: [CommonModule, RouterModule, MatCardModule]
})
export class LegalContentComponent {
  @Input() sections: Legal[] = [];
  @Input() pageTitle = '';
  @Input() pageSubtitle = '';
  @Input() pageAriaLabel = '';
  @Input() cardAriaLabel = '';
}

Option 3: Template Inheritance with ng-content

<!-- src/app/components/shared/base-legal.component.html -->
<section [attr.aria-label]="pageAriaLabel">
  <mat-card [attr.aria-label]="cardAriaLabel" class="mat-elevation-z24" role="region">
    <mat-card-title aria-level="1" [title]="pageTitle" role="heading">
      {{ pageTitle }}
    </mat-card-title>
    <mat-card-subtitle aria-level="3" role="heading">
      {{ pageSubtitle }}
    </mat-card-subtitle>
    <mat-card-content role="complementary">
      <ng-content></ng-content>
    </mat-card-content>
  </mat-card>
</section>

Refactoring Impact Assessment

What CAN be shared:

  • AOS initialization
  • Basic component setup
  • Common imports
  • HTML template structure
  • Animation attributes

What CANNOT be shared:

  • Section content arrays
  • hasLinks: true content (component-specific)
  • Page titles, subtitles, and aria-labels
  • Routing logic within content

Technical Constraints

  • Components are standalone (Angular 17+)
  • Use Material Design components
  • AOS library integration
  • Complex conditional rendering with ngSwitch
  • HTML content with routing links

Estimated Refactoring Effort

  • Low: Create base abstract class
  • Medium: Refactor existing components
  • High: Maintain unique content for each component
  • Risk: Breaking existing functionality during refactoring

Files to Create/Modify

  • New: src/app/components/shared/base-legal.component.ts
  • Modify: All three legal component files
  • No changes: HTML templates, component logic, or interfaces

Testing Considerations

  • Verify AOS animations still work
  • Ensure routing links function correctly
  • Test accessibility attributes
  • Validate component-specific content rendering

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions