:root { --background-dark: #0d1117; --background-light: #161b22; --border-color: #30363d; --text-primary: #c9d1d9; --text-secondary: #8b949e; --accent-blue: #3b82f6; --accent-blue-hover: #2563eb; --font-family: 'Inter', sans-serif; } *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } body { background-color: var(--background-dark); color: var(--text-primary); font-family: var(--font-family); line-height: 1.6; } #root { display: flex; flex-direction: column; min-height: 100vh; } main { flex-grow: 1; padding: 2rem 1rem; } .container { max-width: 1200px; margin: 0 auto; padding: 0 1rem; } /* Header */ .app-header { background-color: var(--background-light); border-bottom: 1px solid var(--border-color); padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; z-index: 1000; } .logo { display: flex; align-items: center; gap: 0.5rem; font-size: 1.5rem; font-weight: 700; color: var(--text-primary); text-decoration: none; cursor: pointer; } .logo svg { width: 32px; height: 32px; fill: var(--accent-blue); } .main-nav { display: none; } .main-nav a { color: var(--text-secondary); text-decoration: none; padding: 0.5rem 1rem; transition: color 0.2s; font-weight: 500; } .main-nav a:hover, .main-nav a.active { color: var(--text-primary); } .mobile-menu-button { display: block; background: none; border: none; cursor: pointer; } .mobile-menu-button svg { width: 32px; height: 32px; fill: var(--text-primary); } .mobile-nav { position: fixed; top: 0; left: -100%; width: 80%; max-width: 300px; height: 100%; background-color: var(--background-light); box-shadow: 2px 0 10px rgba(0,0,0,0.5); transition: left 0.3s ease-in-out; padding: 2rem; display: flex; flex-direction: column; gap: 1rem; z-index: 1001; } .mobile-nav.open { left: 0; } .mobile-nav a { color: var(--text-primary); text-decoration: none; font-size: 1.2rem; padding: 0.5rem; } .mobile-nav .close-button { position: absolute; top: 1rem; right: 1rem; background: none; border: none; cursor: pointer; } .mobile-nav .close-button svg { width: 24px; height: 24px; fill: var(--text-primary); } /* Home Page */ .home-hero { text-align: center; padding: 4rem 1rem; } .home-hero h1 { font-size: 2.5rem; font-weight: 700; margin-bottom: 1rem; line-height: 1.2; } .home-hero h1 span { color: var(--accent-blue); } .home-hero p { font-size: 1.1rem; color: var(--text-secondary); max-width: 600px; margin: 0 auto 2rem; } .upload-area { border: 2px dashed var(--border-color); border-radius: 8px; padding: 3rem 1rem; background-color: var(--background-light); cursor: pointer; transition: border-color 0.2s; max-width: 700px; margin: 0 auto; } .upload-area:hover { border-color: var(--accent-blue); } .upload-area p { color: var(--text-secondary); margin-top: 1rem; } .features-grid { display: grid; gap: 1.5rem; margin-top: 4rem; } .feature-card { background-color: var(--background-light); border: 1px solid var(--border-color); border-radius: 8px; padding: 2rem; text-align: left; } .feature-card h3 { font-size: 1.2rem; margin-bottom: 0.5rem; } .feature-card p { color: var(--text-secondary); } .content-section { margin-top: 4rem; padding-top: 2rem; border-top: 1px solid var(--border-color); } .content-section h2 { font-size: 1.8rem; margin-bottom: 1rem; text-align: center; } .content-section p, .content-section ul { max-width: 800px; margin: 0 auto 1rem; color: var(--text-secondary); } /* Editor Page */ .editor-workspace { display: flex; flex-direction: column; gap: 2rem; } .editor-main { flex-grow: 1; display: flex; justify-content: center; align-items: center; background-color: #000; padding: 1rem; border-radius: 8px; } .editor-main canvas { max-width: 100%; max-height: 70vh; object-fit: contain; } .editor-sidebar { background-color: var(--background-light); padding: 1.5rem; border-radius: 8px; border: 1px solid var(--border-color); } .editor-controls { margin-top: 1rem; } .tool-tabs { display: flex; gap: 0.5rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--border-color); } .tool-tabs button { background: none; border: none; color: var(--text-secondary); padding: 0.5rem 1rem; cursor: pointer; font-size: 1rem; font-weight: 500; border-bottom: 2px solid transparent; transition: all 0.2s; } .tool-tabs button.active { color: var(--accent-blue); border-bottom-color: var(--accent-blue); } .control-group label { display: block; margin-bottom: 0.5rem; font-weight: 500; } .control-group input[type="range"] { width: 100%; } .control-group { margin-bottom: 1rem; } .filters-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 1rem; } .filter-item { cursor: pointer; text-align: center; } .filter-item img { width: 100%; border-radius: 4px; border: 2px solid transparent; transition: border-color 0.2s; } .filter-item.active img { border-color: var(--accent-blue); } .filter-item p { font-size: 0.8rem; margin-top: 0.25rem; } .editor-actions { margin-top: 2rem; display: flex; gap: 1rem; flex-wrap: wrap; } /* Tool Pages */ .tool-page { max-width: 900px; margin: 0 auto; text-align: center; } .tool-page h1 { font-size: 2.2rem; margin-bottom: 1rem; } .tool-page p.description { color: var(--text-secondary); font-size: 1.1rem; max-width: 700px; margin: 0 auto 2rem; } .tool-container { background-color: var(--background-light); border: 1px solid var(--border-color); border-radius: 8px; padding: 2rem; margin-bottom: 3rem; } .tool-output { margin-top: 2rem; } .tool-output img, .tool-output video { max-width: 100%; border-radius: 8px; margin: 0 auto; display: block; } .tool-output p { margin-top: 1rem; color: var(--text-secondary); } .tools-grid { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); } .tool-card { background-color: var(--background-light); border: 1px solid var(--border-color); border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; } .tool-card-img { width: 100%; height: 150px; background-color: #000; display: flex; align-items: center; justify-content: center; } .tool-card-img svg { width: 50px; height: 50px; fill: var(--accent-blue); } .tool-card-content { padding: 1.5rem; flex-grow: 1; display: flex; flex-direction: column; } .tool-card-content h3 { font-size: 1.2rem; margin-bottom: auto; padding-bottom: 1rem; } /* Footer */ .app-footer { background-color: var(--background-light); border-top: 1px solid var(--border-color); padding: 2rem; margin-top: auto; text-align: center; color: var(--text-secondary); } .footer-links { display: flex; justify-content: center; gap: 1.5rem; margin-top: 1rem; flex-wrap: wrap; } .footer-links a { color: var(--text-secondary); text-decoration: none; } .footer-links a:hover { color: var(--text-primary); } /* General Components */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.75rem 1.5rem; border-radius: 6px; font-weight: 600; cursor: pointer; text-decoration: none; border: 1px solid transparent; transition: all 0.2s; } .btn-primary { background-color: var(--accent-blue); color: #fff; } .btn-primary:hover { background-color: var(--accent-blue-hover); } .btn-secondary { background-color: var(--background-light); color: var(--text-primary); border-color: var(--border-color); } .btn-secondary:hover { background-color: var(--border-color); } .input-field { width: 100%; padding: 0.75rem 1rem; background-color: var(--background-dark); border: 1px solid var(--border-color); border-radius: 6px; color: var(--text-primary); font-size: 1rem; } .loader { border: 4px solid var(--border-color); border-top: 4px solid var(--accent-blue); border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 2rem auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Desktop Styles */ @media (min-width: 768px) { .mobile-menu-button, .mobile-nav { display: none; } .main-nav { display: flex; align-items: center; gap: 1rem; } .home-hero h1 { font-size: 3.5rem; } .features-grid { grid-template-columns: repeat(3, 1fr); } .editor-workspace { flex-direction: row; align-items: flex-start; } .editor-sidebar { width: 350px; flex-shrink: 0; } } import React, { useState, useEffect, useRef, useCallback } from 'react'; import { createRoot } from 'react-dom/client'; import { GoogleGenAI, Modality } from "@google/genai"; // --- HELPERS --- // FIX: Added type for 'file' parameter and specified Promise to resolve 'unknown' type error for base64 data, which fixes the error on line 399. const fileToGenerativePart = async (file: File) => { const base64EncodedDataPromise = new Promise((resolve) => { const reader = new FileReader(); // FIX: Cast reader.result to string to access 'split' method, correcting the error on line 9. reader.onloadend = () => resolve((reader.result as string).split(',')[1]); reader.readAsDataURL(file); }); return { inlineData: { data: await base64EncodedDataPromise, mimeType: file.type }, }; }; const ai = new GoogleGenAI({ apiKey: process.env.API_KEY }); // --- SVG ICONS --- const LogoIcon = () => ( ); const HamburgerIcon = () => ( ); const CloseIcon = () => ( ); const UploadIcon = () => ( ); const ToolIcon = () => ( ); // --- COMPONENTS --- const Header = ({ setPage }) => { const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); const navigate = (page) => { setPage(page); setIsMobileMenuOpen(false); }; const NavLinks = () => ( <> { e.preventDefault(); navigate('home'); }}>Home { e.preventDefault(); navigate('backgroundRemover'); }}>AI Background Remover { e.preventDefault(); navigate('avatarMaker'); }}>AI Avatar Maker { e.preventDefault(); navigate('imageGenerator'); }}>AI Image Generator { e.preventDefault(); navigate('tools'); }}>Tools ); return (
{ e.preventDefault(); navigate('home'); }}> Pixshop {isMobileMenuOpen && (
)}
); }; const Footer = () => ( ); const Loader = () =>
; // FIX: Added explicit prop types to make 'children' optional, resolving the error on line 324. // Also added types for refs, event handlers, and used optional chaining for safer file access. const ImageUploader = ({ onUpload, buttonText = "Upload an Image", children }: { onUpload: (file: File) => void; buttonText?: string; children?: React.ReactNode; }) => { const inputRef = useRef(null); const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { onUpload(file); } }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); const file = e.dataTransfer.files?.[0]; if (file) { onUpload(file); } }; const handleClick = () => inputRef.current?.click(); return (
e.preventDefault()}> {children}
); }; const HomePage = ({ setPage, setOriginalImage }) => { const handleImageUpload = (file) => { setOriginalImage(file); setPage('editor'); }; return (

AI-Powered Photo Editing, Simplified.

Retouch photos, apply creative filters, or make professional adjustments using simple text prompts. No complex tools needed.

or drag and drop a file

Precise Retouching

Click any point on your image to remove blemishes, change colors, or add elements with pinpoint accuracy.

Creative Filters

Transform photos with looks from vintage to futuristic glows, find or create the perfect filter.

Pro Adjustments

Enhance lighting, blur backgrounds, or change the mood. Get studio-quality results without complex tools.

The Future of Image Editing is Here

Welcome to Pixshop, your all-in-one solution for intelligent photo enhancement. We leverage the power of Google's Gemini API to bring you cutting-edge tools that are both powerful and incredibly easy to use. Whether you're a professional photographer or just want to make your social media posts stand out, our suite of AI-driven features will revolutionize your creative workflow.

This is a placeholder for the 800-word plagiarism-free content. You can expand on topics like the benefits of AI in photo editing, how to get started, tutorials for specific features, and comparisons to traditional editing software. You can break this down into the 20 sections you require, covering everything from basic adjustments to advanced AI manipulations.

); }; const EditorPage = ({ imageFile, setPage }) => { const canvasRef = useRef(null); const [activeTool, setActiveTool] = useState('adjust'); const [adjustments, setAdjustments] = useState({ brightness: 100, contrast: 100, saturate: 100 }); const [activeFilter, setActiveFilter] = useState('none'); const filters = { none: '', grayscale: 'grayscale(1)', sepia: 'sepia(1)', invert: 'invert(1)', 'vintage': 'sepia(0.6) contrast(0.9) brightness(1.1) saturate(1.2)', 'lomo': 'contrast(1.4) saturate(1.1) hue-rotate(-10deg)', 'clarity': 'contrast(1.2) saturate(1.1)', 'noir': 'grayscale(1) contrast(1.3)', 'sunny': 'brightness(1.2) contrast(1.1) saturate(1.2)', 'cool': 'contrast(1.1) brightness(1.1) hue-rotate(-15deg)', 'warm': 'sepia(0.4) saturate(1.3)' }; const drawImage = useCallback(() => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const img = new Image(); img.src = URL.createObjectURL(imageFile); img.onload = () => { canvas.width = img.width; canvas.height = img.height; ctx.filter = `${filters[activeFilter]} brightness(${adjustments.brightness}%) contrast(${adjustments.contrast}%) saturate(${adjustments.saturate}%)`; ctx.drawImage(img, 0, 0); }; }, [imageFile, adjustments, activeFilter]); useEffect(() => { drawImage(); }, [drawImage]); const handleAdjustmentChange = (e) => { setAdjustments({ ...adjustments, [e.target.name]: e.target.value }); }; const handleFilterClick = (filterName) => { setActiveFilter(filterName); }; const handleDownload = () => { const canvas = canvasRef.current; const link = document.createElement('a'); link.download = `edited-${imageFile.name}`; link.href = canvas.toDataURL(); link.click(); }; const handleCrop = () => { alert("Crop functionality coming soon! For now, you can use adjustments and filters."); }; const reset = () => { setAdjustments({ brightness: 100, contrast: 100, saturate: 100 }); setActiveFilter('none'); } return (
); }; const AIToolPage = ({ tool }) => { // FIX: Add explicit types for useState hooks for better type safety. const [imageFile, setImageFile] = useState(null); const [prompt, setPrompt] = useState(''); const [result, setResult] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(''); const handleSubmit = async () => { if (!imageFile && tool.requiresImage) { setError('Please upload an image.'); return; } if (!prompt && tool.requiresPrompt) { setError('Please enter a prompt.'); return; } setError(''); setIsLoading(true); setResult(null); try { const response = await tool.apiCall({ imageFile, prompt }); setResult(response); } catch (e) { console.error(e); setError('An error occurred. Please try again.'); } finally { setIsLoading(false); } }; return (

{tool.name}

{tool.description}

{tool.requiresImage && !imageFile && ( )} {imageFile && Uploaded preview} {tool.requiresPrompt && (
setPrompt(e.target.value)} placeholder={tool.promptPlaceholder} />
)} {error &&

{error}

}
{isLoading && } {result && tool.renderResult(result)}

How to Use {tool.name}

Placeholder content explaining how to use this specific tool. Describe the steps, offer tips for best results, and showcase some examples.

Benefits

Placeholder content about the benefits of using this tool.

FAQ

Placeholder for frequently asked questions regarding this tool.

); }; const ToolsListPage = ({ setPage }) => { const tools = [ { name: 'AI Background Remover', page: 'backgroundRemover' }, { name: 'AI Avatar Maker', page: 'avatarMaker' }, { name: 'AI Image Generator', page: 'imageGenerator' }, { name: 'Photo to Sketch', page: '' }, { name: 'Colorizer', page: '' }, { name: 'Image Upscaler', page: '' }, { name: 'Text to Image', page: '' }, { name: 'Creative Filters', page: '' }, { name: 'Object Remover', page: '' }, { name: 'Style Transfer', page: '' }, ]; return (

Our Editing Tools

Explore our full suite of AI-powered and classic image editing tools to bring your creative vision to life.

{tools.map(tool => (

{tool.name}

))}
); }; const App = () => { const [page, setPage] = useState('home'); // FIX: Add explicit type for useState for better type safety. const [originalImage, setOriginalImage] = useState(null); const toolConfigs = { backgroundRemover: { name: "AI Background Remover", description: "Upload an image and our AI will automatically remove the background, leaving you with a clean cutout.", requiresImage: true, requiresPrompt: false, apiCall: async ({ imageFile }) => { const imagePart = await fileToGenerativePart(imageFile); const response = await ai.models.generateContent({ model: 'gemini-2.5-flash-image-preview', contents: { parts: [imagePart, { text: 'Remove the background of this image and replace it with transparency.' }] }, config: { responseModalities: [Modality.IMAGE, Modality.TEXT] }, }); for (const part of response.candidates[0].content.parts) { if (part.inlineData) { return `data:${part.inlineData.mimeType};base64,${part.inlineData.data}`; } } throw new Error("No image returned from API"); }, renderResult: (result) => Background removed result, }, imageGenerator: { name: "AI Image Generator", description: "Describe anything you can imagine, and our AI will generate a unique image based on your text prompt.", requiresImage: false, requiresPrompt: true, promptPlaceholder: "e.g., A robot holding a red skateboard", apiCall: async ({ prompt }) => { const response = await ai.models.generateImages({ model: 'imagen-4.0-generate-001', prompt: prompt, config: { numberOfImages: 1, outputMimeType: 'image/png' }, }); const base64ImageBytes = response.generatedImages[0].image.imageBytes; return `data:image/png;base64,${base64ImageBytes}`; }, renderResult: (result) => AI generated result, }, avatarMaker: { name: "AI Avatar Maker", description: "Upload your photo and let our AI transform it into a stylish and unique avatar. (This tool is a placeholder).", requiresImage: true, requiresPrompt: false, apiCall: async () => { // Placeholder: In a real scenario, you'd call the Gemini API here. await new Promise(res => setTimeout(res, 1000)); return 'https://via.placeholder.com/512/0d1117/3b82f6?text=Coming+Soon'; }, renderResult: (result) => Avatar result, } }; const renderPage = () => { switch (page) { case 'home': return ; case 'editor': return originalImage ? : ; case 'tools': return ; case 'backgroundRemover': return ; case 'imageGenerator': return ; case 'avatarMaker': return ; default: return ; } }; return ( <>
{renderPage()}