Files
dewedev/src/pages/JsonTool.js
dwindown 7f2dd5260f Initial commit: Developer Tools MVP with visual editor
- Complete React app with 7 developer tools
- JSON Tool with visual structured editor
- Serialize Tool with visual structured editor
- URL, Base64, CSV/JSON, Beautifier, Diff tools
- Responsive navigation with dropdown menu
- Dark/light mode toggle
- Mobile-responsive design with sticky header
- All tools working with copy/paste functionality
2025-08-02 09:31:26 +07:00

248 lines
7.7 KiB
JavaScript

import React, { useState } from 'react';
import { Code, AlertCircle, CheckCircle, Edit3 } from 'lucide-react';
import ToolLayout from '../components/ToolLayout';
import CopyButton from '../components/CopyButton';
import StructuredEditor from '../components/StructuredEditor';
const JsonTool = () => {
const [input, setInput] = useState('');
const [output, setOutput] = useState('');
const [error, setError] = useState('');
const [isValid, setIsValid] = useState(null);
const [editorMode, setEditorMode] = useState('text'); // 'text' or 'visual'
const [structuredData, setStructuredData] = useState({});
const formatJson = () => {
try {
const parsed = JSON.parse(input);
const formatted = JSON.stringify(parsed, null, 2);
setOutput(formatted);
setError('');
setIsValid(true);
} catch (err) {
setError(`Invalid JSON: ${err.message}`);
setOutput('');
setIsValid(false);
}
};
const minifyJson = () => {
try {
const parsed = JSON.parse(input);
const minified = JSON.stringify(parsed);
setOutput(minified);
setError('');
setIsValid(true);
} catch (err) {
setError(`Invalid JSON: ${err.message}`);
setOutput('');
setIsValid(false);
}
};
const validateJson = () => {
try {
JSON.parse(input);
setError('');
setIsValid(true);
setOutput('✅ Valid JSON');
} catch (err) {
setError(`Invalid JSON: ${err.message}`);
setIsValid(false);
setOutput('');
}
};
const clearAll = () => {
setInput('');
setOutput('');
setError('');
setIsValid(null);
};
const handleStructuredDataChange = (newData) => {
setStructuredData(newData);
setInput(JSON.stringify(newData, null, 2));
setError('');
setIsValid(true);
};
const switchToVisualEditor = () => {
try {
const parsed = input ? JSON.parse(input) : {};
setStructuredData(parsed);
setEditorMode('visual');
setError('');
setIsValid(true);
} catch (err) {
setError(`Cannot switch to visual editor: ${err.message}`);
setIsValid(false);
}
};
const switchToTextEditor = () => {
setEditorMode('text');
};
const loadSample = () => {
const sample = {
"name": "John Doe",
"age": 30,
"email": "john@example.com",
"address": {
"street": "123 Main St",
"city": "New York",
"zipCode": "10001"
},
"hobbies": ["reading", "coding", "traveling"],
"isActive": true
};
setInput(JSON.stringify(sample, null, 2));
setStructuredData(sample);
};
return (
<ToolLayout
title="JSON Encoder/Decoder"
description="Format, validate, and minify JSON data with syntax highlighting"
icon={Code}
>
{/* Editor Mode Toggle */}
<div className="flex bg-gray-100 dark:bg-gray-800 rounded-lg p-1 mb-6 w-fit">
<button
onClick={switchToTextEditor}
className={`flex items-center space-x-2 px-4 py-2 rounded-md font-medium transition-colors ${
editorMode === 'text'
? 'bg-white dark:bg-gray-700 text-primary-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400'
}`}
>
<Code className="h-4 w-4" />
<span>Text Editor</span>
</button>
<button
onClick={switchToVisualEditor}
className={`flex items-center space-x-2 px-4 py-2 rounded-md font-medium transition-colors ${
editorMode === 'visual'
? 'bg-white dark:bg-gray-700 text-primary-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400'
}`}
>
<Edit3 className="h-4 w-4" />
<span>Visual Editor</span>
</button>
</div>
{/* Controls */}
<div className="flex flex-wrap gap-3 mb-6">
<button onClick={formatJson} className="tool-button">
Format JSON
</button>
<button onClick={minifyJson} className="tool-button">
Minify JSON
</button>
<button onClick={validateJson} className="tool-button">
Validate JSON
</button>
<button onClick={loadSample} className="tool-button-secondary">
Load Sample
</button>
<button onClick={clearAll} className="tool-button-secondary">
Clear All
</button>
</div>
{/* Status Indicator */}
{isValid !== null && (
<div className={`flex items-center space-x-2 p-3 rounded-md mb-4 ${
isValid
? 'bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-300'
: 'bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300'
}`}>
{isValid ? (
<CheckCircle className="h-5 w-5" />
) : (
<AlertCircle className="h-5 w-5" />
)}
<span className="font-medium">
{isValid ? 'Valid JSON' : 'Invalid JSON'}
</span>
</div>
)}
{/* Error Display */}
{error && (
<div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md p-4 mb-4">
<div className="flex items-start space-x-2">
<AlertCircle className="h-5 w-5 text-red-500 mt-0.5" />
<div>
<h4 className="text-red-800 dark:text-red-200 font-medium">Error</h4>
<p className="text-red-700 dark:text-red-300 text-sm mt-1">{error}</p>
</div>
</div>
</div>
)}
{/* Input/Output Grid */}
<div className={`grid gap-6 ${
editorMode === 'visual'
? 'grid-cols-1'
: 'grid-cols-1 lg:grid-cols-2'
}`}>
{/* Input */}
<div className="space-y-2">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
{editorMode === 'text' ? 'Input JSON' : 'Visual JSON Editor'}
</label>
<div className="relative">
{editorMode === 'text' ? (
<textarea
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Paste your JSON here..."
className="tool-input h-96"
/>
) : (
<div className="min-h-96">
<StructuredEditor
initialData={structuredData}
onDataChange={handleStructuredDataChange}
/>
</div>
)}
</div>
</div>
{/* Output */}
<div className="space-y-2">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
Output
</label>
<div className="relative">
<textarea
value={output}
readOnly
placeholder="Formatted JSON will appear here..."
className="tool-input h-96 bg-gray-50 dark:bg-gray-800"
/>
{output && <CopyButton text={output} />}
</div>
</div>
</div>
{/* Usage Tips */}
<div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md p-4 mt-6">
<h4 className="text-blue-800 dark:text-blue-200 font-medium mb-2">Usage Tips</h4>
<ul className="text-blue-700 dark:text-blue-300 text-sm space-y-1">
<li> Use "Format JSON" to beautify and indent your JSON</li>
<li> Use "Minify JSON" to compress JSON by removing whitespace</li>
<li> Use "Validate JSON" to check if your JSON syntax is correct</li>
<li> Click the copy button to copy the output to your clipboard</li>
</ul>
</div>
</ToolLayout>
);
};
export default JsonTool;