Fix all ESLint errors and improve code quality

- Fix unused variable errors by removing unused parameters or using proper destructuring
- Fix 'prefer-const' violations by replacing 'let' with 'const' where appropriate
- Fix lexical declaration errors in switch cases by adding proper block scoping
- Replace explicit 'any' type with proper TypeScript interface for DOMPurify config
- Fix React hooks dependency warnings in useDialog hook
- Remove unused imports and variables throughout codebase

Specific fixes:
- Replace '_' parameters with proper destructuring syntax ([, value])
- Add block scopes to switch case statements in templateRenderer.ts
- Improve type safety in htmlSanitizer.ts with explicit DOMPurify interface
- Fix useCallback dependencies in useDialog hook
- Remove unused 'placeholder' parameter in generateSampleDataForSlot

All 15 ESLint errors have been resolved, improving code maintainability and consistency.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Michael Mainguy 2025-08-20 17:50:23 -05:00
parent d0e70f81e7
commit d88ae6dcc3
9 changed files with 26 additions and 15 deletions

View File

@ -29,7 +29,6 @@ export const PresentationEditor: React.FC = () => {
alertOptions,
confirmOptions,
showAlert,
showConfirm,
closeAlert,
closeConfirm,
handleConfirm,

View File

@ -92,7 +92,7 @@ export const SlideEditor: React.FC = () => {
useEffect(() => {
if (theme) {
const themeStyleId = 'slide-editor-theme-style';
let existingStyle = document.getElementById(themeStyleId);
const existingStyle = document.getElementById(themeStyleId);
if (existingStyle) {
existingStyle.remove();

View File

@ -27,7 +27,7 @@ export const ThemeSelector: React.FC<ThemeSelectorProps> = ({
{/* Color palette preview */}
<div className="color-preview-strip">
{theme.variables && Object.entries(theme.variables)
.filter(([_, value]) => value.startsWith('#') || value.includes('rgb') || value.includes('hsl'))
.filter(([, value]) => value.startsWith('#') || value.includes('rgb') || value.includes('hsl'))
.slice(0, 4)
.map(([key, value]) => (
<div
@ -38,7 +38,7 @@ export const ThemeSelector: React.FC<ThemeSelectorProps> = ({
/>
))
}
{(!theme.variables || Object.entries(theme.variables).filter(([_, value]) =>
{(!theme.variables || Object.entries(theme.variables).filter(([, value]) =>
value.startsWith('#') || value.includes('rgb') || value.includes('hsl')
).length === 0) && (
<div className="no-colors">No colors defined</div>

View File

@ -56,7 +56,7 @@ export const LayoutPreviewPage: React.FC = () => {
if (theme) {
// Dynamically load theme CSS
const themeStyleId = 'theme-preview-style';
let existingStyle = document.getElementById(themeStyleId);
const existingStyle = document.getElementById(themeStyleId);
if (existingStyle) {
existingStyle.remove();

View File

@ -118,7 +118,7 @@ export const ThemeBrowser: React.FC = () => {
<div className="theme-preview">
<div className="color-palette">
{Object.entries(theme.variables)
.filter(([_, value]) => value.startsWith('#') || value.includes('rgb') || value.includes('hsl'))
.filter(([, value]) => value.startsWith('#') || value.includes('rgb') || value.includes('hsl'))
.slice(0, 6) // Show max 6 color swatches to avoid overcrowding
.map(([key, value]) => (
<div

View File

@ -87,7 +87,7 @@ export const ThemeDetailPage: React.FC = () => {
<h2>Color Palette</h2>
<div className="color-palette-large">
{Object.entries(theme.variables)
.filter(([_, value]) => value.startsWith('#') || value.includes('rgb') || value.includes('hsl'))
.filter(([, value]) => value.startsWith('#') || value.includes('rgb') || value.includes('hsl'))
.map(([key, value]) => (
<div key={key} className="color-swatch-large">
<div

View File

@ -72,7 +72,7 @@ export function useDialog() {
state.confirmCallback();
}
closeConfirm();
}, [state.confirmCallback, closeConfirm]);
}, [state, closeConfirm]);
const handleConfirmCancel = useCallback(() => {
closeConfirm();

View File

@ -69,7 +69,14 @@ export function sanitizeHtml(html: string, config: SanitizeConfig = {}): string
const finalConfig = { ...DEFAULT_SLIDE_CONFIG, ...config };
// Build DOMPurify configuration
const purifyConfig: any = {
const purifyConfig: {
ALLOWED_TAGS: string[];
ALLOWED_ATTR: string[];
FORBID_TAGS: string[];
FORBID_ATTR: string[];
KEEP_CONTENT: boolean;
ALLOW_DATA_ATTR: boolean;
} = {
ALLOWED_TAGS: finalConfig.allowedTags,
ALLOWED_ATTR: finalConfig.allowedAttributes,
// Remove any scripts or dangerous content

View File

@ -66,7 +66,7 @@ const SAMPLE_CONTENT = {
* Generates sample data for a slot based on its configuration
*/
export const generateSampleDataForSlot = (slot: SlotConfig): string => {
const { id, type, placeholder, defaultContent } = slot;
const { id, type, defaultContent } = slot;
// Use default content if available
if (defaultContent && defaultContent.trim()) {
@ -81,21 +81,25 @@ export const generateSampleDataForSlot = (slot: SlotConfig): string => {
case 'image':
return createImageSVG(slotDisplayName);
case 'title':
case 'title': {
const titleSamples = SAMPLE_CONTENT.title;
return titleSamples[Math.floor(Math.random() * titleSamples.length)];
}
case 'subtitle':
case 'subtitle': {
const subtitleSamples = SAMPLE_CONTENT.subtitle;
return subtitleSamples[Math.floor(Math.random() * subtitleSamples.length)];
}
case 'heading':
case 'heading': {
const headingSamples = SAMPLE_CONTENT.heading;
return headingSamples[Math.floor(Math.random() * headingSamples.length)];
}
case 'text':
case 'text': {
const textSamples = SAMPLE_CONTENT.text;
return textSamples[Math.floor(Math.random() * textSamples.length)];
}
case 'video':
return createImageSVG(`${slotDisplayName} (Video)`, 640, 360);
@ -103,9 +107,10 @@ export const generateSampleDataForSlot = (slot: SlotConfig): string => {
case 'audio':
return `[${slotDisplayName} Audio]`;
case 'list':
case 'list': {
const listSamples = SAMPLE_CONTENT.list;
return listSamples[Math.floor(Math.random() * listSamples.length)];
}
case 'code':
return `// ${slotDisplayName}\nfunction ${id.replace(/-/g, '')}() {\n return "${slotDisplayName}";\n}`;