ice/src/frontend/components/SharedFooter.ts
Claude Code f8802232c6 Fix TypeScript linting issues and test failures
- Replace 37 instances of 'any' type with proper TypeScript types
- Fix trailing spaces in i18n.test.ts
- Add proper interfaces for profanity analysis and matches
- Extend Express Request interface with custom properties
- Fix error handling in ProfanityFilterService for constraint violations
- Update test mocks to satisfy TypeScript strict checking
- All 147 tests now pass with 0 linting errors

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-07 21:14:54 -04:00

77 lines
No EOL
2.5 KiB
TypeScript

/**
* Shared footer component for consistent footers across pages
*/
export interface SharedFooterConfig {
containerId?: string;
showSafetyNotice?: boolean;
showDisclaimer?: boolean;
}
export class SharedFooter {
private config: Required<SharedFooterConfig>;
constructor(config: SharedFooterConfig = {}) {
this.config = {
containerId: config.containerId || 'footer-container',
showSafetyNotice: config.showSafetyNotice !== false,
showDisclaimer: config.showDisclaimer !== false
};
}
public render(): void {
const container = document.getElementById(this.config.containerId);
if (!container) {
console.error(`Container with id "${this.config.containerId}" not found`);
return;
}
const footer = document.createElement('footer');
footer.innerHTML = `
${this.config.showSafetyNotice ? `
<p>
<span data-i18n="footer.safetyNotice">Safety Notice: This is a community tool for awareness. Stay safe and</span>
<a href="https://www.aclu.org/know-your-rights/immigrants-rights"
target="_blank"
rel="noopener noreferrer"
style="color: #007bff; text-decoration: underline;"
data-i18n="footer.knowRights">know your rights</a>.
</p>
` : ''}
${this.config.showDisclaimer ? `
<div class="disclaimer">
<small>
<span data-i18n="footer.disclaimer">This website is for informational purposes only. Verify information independently. Reports are automatically deleted after 48 hours. •</span>
<a href="/privacy"
style="color: #007bff; text-decoration: underline;"
data-i18n="common.privacyPolicy">Privacy Policy</a>
</small>
</div>
` : ''}
`;
container.appendChild(footer);
// Update translations if i18n is available
if ((window as Window & typeof globalThis & { i18n?: { updatePageTranslations: () => void } }).i18n?.updatePageTranslations) {
(window as Window & typeof globalThis & { i18n?: { updatePageTranslations: () => void } }).i18n.updatePageTranslations();
}
}
// Factory method for standard footer
public static createStandardFooter(): SharedFooter {
return new SharedFooter({
showSafetyNotice: true,
showDisclaimer: true
});
}
// Factory method for minimal footer (e.g., admin pages)
public static createMinimalFooter(): SharedFooter {
return new SharedFooter({
showSafetyNotice: false,
showDisclaimer: true
});
}
}