- 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>
77 lines
No EOL
2.5 KiB
TypeScript
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
|
|
});
|
|
}
|
|
} |