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:
parent
d0e70f81e7
commit
d88ae6dcc3
@ -29,7 +29,6 @@ export const PresentationEditor: React.FC = () => {
|
|||||||
alertOptions,
|
alertOptions,
|
||||||
confirmOptions,
|
confirmOptions,
|
||||||
showAlert,
|
showAlert,
|
||||||
showConfirm,
|
|
||||||
closeAlert,
|
closeAlert,
|
||||||
closeConfirm,
|
closeConfirm,
|
||||||
handleConfirm,
|
handleConfirm,
|
||||||
|
@ -92,7 +92,7 @@ export const SlideEditor: React.FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (theme) {
|
if (theme) {
|
||||||
const themeStyleId = 'slide-editor-theme-style';
|
const themeStyleId = 'slide-editor-theme-style';
|
||||||
let existingStyle = document.getElementById(themeStyleId);
|
const existingStyle = document.getElementById(themeStyleId);
|
||||||
|
|
||||||
if (existingStyle) {
|
if (existingStyle) {
|
||||||
existingStyle.remove();
|
existingStyle.remove();
|
||||||
|
@ -27,7 +27,7 @@ export const ThemeSelector: React.FC<ThemeSelectorProps> = ({
|
|||||||
{/* Color palette preview */}
|
{/* Color palette preview */}
|
||||||
<div className="color-preview-strip">
|
<div className="color-preview-strip">
|
||||||
{theme.variables && Object.entries(theme.variables)
|
{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)
|
.slice(0, 4)
|
||||||
.map(([key, value]) => (
|
.map(([key, value]) => (
|
||||||
<div
|
<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')
|
value.startsWith('#') || value.includes('rgb') || value.includes('hsl')
|
||||||
).length === 0) && (
|
).length === 0) && (
|
||||||
<div className="no-colors">No colors defined</div>
|
<div className="no-colors">No colors defined</div>
|
||||||
|
@ -56,7 +56,7 @@ export const LayoutPreviewPage: React.FC = () => {
|
|||||||
if (theme) {
|
if (theme) {
|
||||||
// Dynamically load theme CSS
|
// Dynamically load theme CSS
|
||||||
const themeStyleId = 'theme-preview-style';
|
const themeStyleId = 'theme-preview-style';
|
||||||
let existingStyle = document.getElementById(themeStyleId);
|
const existingStyle = document.getElementById(themeStyleId);
|
||||||
|
|
||||||
if (existingStyle) {
|
if (existingStyle) {
|
||||||
existingStyle.remove();
|
existingStyle.remove();
|
||||||
|
@ -118,7 +118,7 @@ export const ThemeBrowser: React.FC = () => {
|
|||||||
<div className="theme-preview">
|
<div className="theme-preview">
|
||||||
<div className="color-palette">
|
<div className="color-palette">
|
||||||
{Object.entries(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, 6) // Show max 6 color swatches to avoid overcrowding
|
.slice(0, 6) // Show max 6 color swatches to avoid overcrowding
|
||||||
.map(([key, value]) => (
|
.map(([key, value]) => (
|
||||||
<div
|
<div
|
||||||
|
@ -87,7 +87,7 @@ export const ThemeDetailPage: React.FC = () => {
|
|||||||
<h2>Color Palette</h2>
|
<h2>Color Palette</h2>
|
||||||
<div className="color-palette-large">
|
<div className="color-palette-large">
|
||||||
{Object.entries(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'))
|
||||||
.map(([key, value]) => (
|
.map(([key, value]) => (
|
||||||
<div key={key} className="color-swatch-large">
|
<div key={key} className="color-swatch-large">
|
||||||
<div
|
<div
|
||||||
|
@ -72,7 +72,7 @@ export function useDialog() {
|
|||||||
state.confirmCallback();
|
state.confirmCallback();
|
||||||
}
|
}
|
||||||
closeConfirm();
|
closeConfirm();
|
||||||
}, [state.confirmCallback, closeConfirm]);
|
}, [state, closeConfirm]);
|
||||||
|
|
||||||
const handleConfirmCancel = useCallback(() => {
|
const handleConfirmCancel = useCallback(() => {
|
||||||
closeConfirm();
|
closeConfirm();
|
||||||
|
@ -69,7 +69,14 @@ export function sanitizeHtml(html: string, config: SanitizeConfig = {}): string
|
|||||||
const finalConfig = { ...DEFAULT_SLIDE_CONFIG, ...config };
|
const finalConfig = { ...DEFAULT_SLIDE_CONFIG, ...config };
|
||||||
|
|
||||||
// Build DOMPurify configuration
|
// 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_TAGS: finalConfig.allowedTags,
|
||||||
ALLOWED_ATTR: finalConfig.allowedAttributes,
|
ALLOWED_ATTR: finalConfig.allowedAttributes,
|
||||||
// Remove any scripts or dangerous content
|
// Remove any scripts or dangerous content
|
||||||
|
@ -66,7 +66,7 @@ const SAMPLE_CONTENT = {
|
|||||||
* Generates sample data for a slot based on its configuration
|
* Generates sample data for a slot based on its configuration
|
||||||
*/
|
*/
|
||||||
export const generateSampleDataForSlot = (slot: SlotConfig): string => {
|
export const generateSampleDataForSlot = (slot: SlotConfig): string => {
|
||||||
const { id, type, placeholder, defaultContent } = slot;
|
const { id, type, defaultContent } = slot;
|
||||||
|
|
||||||
// Use default content if available
|
// Use default content if available
|
||||||
if (defaultContent && defaultContent.trim()) {
|
if (defaultContent && defaultContent.trim()) {
|
||||||
@ -81,21 +81,25 @@ export const generateSampleDataForSlot = (slot: SlotConfig): string => {
|
|||||||
case 'image':
|
case 'image':
|
||||||
return createImageSVG(slotDisplayName);
|
return createImageSVG(slotDisplayName);
|
||||||
|
|
||||||
case 'title':
|
case 'title': {
|
||||||
const titleSamples = SAMPLE_CONTENT.title;
|
const titleSamples = SAMPLE_CONTENT.title;
|
||||||
return titleSamples[Math.floor(Math.random() * titleSamples.length)];
|
return titleSamples[Math.floor(Math.random() * titleSamples.length)];
|
||||||
|
}
|
||||||
|
|
||||||
case 'subtitle':
|
case 'subtitle': {
|
||||||
const subtitleSamples = SAMPLE_CONTENT.subtitle;
|
const subtitleSamples = SAMPLE_CONTENT.subtitle;
|
||||||
return subtitleSamples[Math.floor(Math.random() * subtitleSamples.length)];
|
return subtitleSamples[Math.floor(Math.random() * subtitleSamples.length)];
|
||||||
|
}
|
||||||
|
|
||||||
case 'heading':
|
case 'heading': {
|
||||||
const headingSamples = SAMPLE_CONTENT.heading;
|
const headingSamples = SAMPLE_CONTENT.heading;
|
||||||
return headingSamples[Math.floor(Math.random() * headingSamples.length)];
|
return headingSamples[Math.floor(Math.random() * headingSamples.length)];
|
||||||
|
}
|
||||||
|
|
||||||
case 'text':
|
case 'text': {
|
||||||
const textSamples = SAMPLE_CONTENT.text;
|
const textSamples = SAMPLE_CONTENT.text;
|
||||||
return textSamples[Math.floor(Math.random() * textSamples.length)];
|
return textSamples[Math.floor(Math.random() * textSamples.length)];
|
||||||
|
}
|
||||||
|
|
||||||
case 'video':
|
case 'video':
|
||||||
return createImageSVG(`${slotDisplayName} (Video)`, 640, 360);
|
return createImageSVG(`${slotDisplayName} (Video)`, 640, 360);
|
||||||
@ -103,9 +107,10 @@ export const generateSampleDataForSlot = (slot: SlotConfig): string => {
|
|||||||
case 'audio':
|
case 'audio':
|
||||||
return `[${slotDisplayName} Audio]`;
|
return `[${slotDisplayName} Audio]`;
|
||||||
|
|
||||||
case 'list':
|
case 'list': {
|
||||||
const listSamples = SAMPLE_CONTENT.list;
|
const listSamples = SAMPLE_CONTENT.list;
|
||||||
return listSamples[Math.floor(Math.random() * listSamples.length)];
|
return listSamples[Math.floor(Math.random() * listSamples.length)];
|
||||||
|
}
|
||||||
|
|
||||||
case 'code':
|
case 'code':
|
||||||
return `// ${slotDisplayName}\nfunction ${id.replace(/-/g, '')}() {\n return "${slotDisplayName}";\n}`;
|
return `// ${slotDisplayName}\nfunction ${id.replace(/-/g, '')}() {\n return "${slotDisplayName}";\n}`;
|
||||||
|
Loading…
Reference in New Issue
Block a user