- 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
189 lines
6.6 KiB
JavaScript
189 lines
6.6 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { Link2 } from 'lucide-react';
|
|
import ToolLayout from '../components/ToolLayout';
|
|
import CopyButton from '../components/CopyButton';
|
|
|
|
const UrlTool = () => {
|
|
const [input, setInput] = useState('');
|
|
const [output, setOutput] = useState('');
|
|
const [mode, setMode] = useState('encode'); // 'encode' or 'decode'
|
|
|
|
const encodeUrl = () => {
|
|
try {
|
|
const encoded = encodeURIComponent(input);
|
|
setOutput(encoded);
|
|
} catch (err) {
|
|
setOutput(`Error: ${err.message}`);
|
|
}
|
|
};
|
|
|
|
const decodeUrl = () => {
|
|
try {
|
|
const decoded = decodeURIComponent(input);
|
|
setOutput(decoded);
|
|
} catch (err) {
|
|
setOutput(`Error: Invalid URL encoding`);
|
|
}
|
|
};
|
|
|
|
const handleProcess = () => {
|
|
if (mode === 'encode') {
|
|
encodeUrl();
|
|
} else {
|
|
decodeUrl();
|
|
}
|
|
};
|
|
|
|
const clearAll = () => {
|
|
setInput('');
|
|
setOutput('');
|
|
};
|
|
|
|
const loadSample = () => {
|
|
if (mode === 'encode') {
|
|
setInput('https://example.com/search?q=hello world&category=web development&sort=date');
|
|
} else {
|
|
setInput('https%3A//example.com/search%3Fq%3Dhello%20world%26category%3Dweb%20development%26sort%3Ddate');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<ToolLayout
|
|
title="URL Encoder/Decoder"
|
|
description="Encode and decode URLs and query parameters"
|
|
icon={Link2}
|
|
>
|
|
{/* Mode Toggle */}
|
|
<div className="flex bg-gray-100 dark:bg-gray-800 rounded-lg p-1 mb-6 w-fit">
|
|
<button
|
|
onClick={() => setMode('encode')}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${
|
|
mode === 'encode'
|
|
? 'bg-white dark:bg-gray-700 text-primary-600 shadow-sm'
|
|
: 'text-gray-600 dark:text-gray-400'
|
|
}`}
|
|
>
|
|
Encode
|
|
</button>
|
|
<button
|
|
onClick={() => setMode('decode')}
|
|
className={`px-4 py-2 rounded-md font-medium transition-colors ${
|
|
mode === 'decode'
|
|
? 'bg-white dark:bg-gray-700 text-primary-600 shadow-sm'
|
|
: 'text-gray-600 dark:text-gray-400'
|
|
}`}
|
|
>
|
|
Decode
|
|
</button>
|
|
</div>
|
|
|
|
{/* Controls */}
|
|
<div className="flex flex-wrap gap-3 mb-6">
|
|
<button onClick={handleProcess} className="tool-button">
|
|
{mode === 'encode' ? 'Encode URL' : 'Decode URL'}
|
|
</button>
|
|
<button onClick={loadSample} className="tool-button-secondary">
|
|
Load Sample
|
|
</button>
|
|
<button onClick={clearAll} className="tool-button-secondary">
|
|
Clear All
|
|
</button>
|
|
</div>
|
|
|
|
{/* Input/Output Grid */}
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
{/* Input */}
|
|
<div className="space-y-2">
|
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
{mode === 'encode' ? 'URL to Encode' : 'Encoded URL to Decode'}
|
|
</label>
|
|
<div className="relative">
|
|
<textarea
|
|
value={input}
|
|
onChange={(e) => setInput(e.target.value)}
|
|
placeholder={
|
|
mode === 'encode'
|
|
? 'Enter URL or text to encode...'
|
|
: 'Enter encoded URL to decode...'
|
|
}
|
|
className="tool-input h-96"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Output */}
|
|
<div className="space-y-2">
|
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
{mode === 'encode' ? 'Encoded URL' : 'Decoded URL'}
|
|
</label>
|
|
<div className="relative">
|
|
<textarea
|
|
value={output}
|
|
readOnly
|
|
placeholder={
|
|
mode === 'encode'
|
|
? 'Encoded URL will appear here...'
|
|
: 'Decoded URL will appear here...'
|
|
}
|
|
className="tool-input h-96 bg-gray-50 dark:bg-gray-800"
|
|
/>
|
|
{output && <CopyButton text={output} />}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Common URL Characters Reference */}
|
|
<div className="bg-gray-50 dark:bg-gray-800 rounded-md p-4 mt-6">
|
|
<h4 className="text-gray-800 dark:text-gray-200 font-medium mb-3">Common URL Encoding Reference</h4>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">Space:</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%20</span>
|
|
</div>
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">!:</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%21</span>
|
|
</div>
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">#:</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%23</span>
|
|
</div>
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">$:</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%24</span>
|
|
</div>
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">&:</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%26</span>
|
|
</div>
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">':</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%27</span>
|
|
</div>
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">(:</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%28</span>
|
|
</div>
|
|
<div>
|
|
<span className="text-gray-600 dark:text-gray-400">):</span>
|
|
<span className="ml-2 font-mono text-gray-800 dark:text-gray-200">%29</span>
|
|
</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>• URL encoding is essential for passing special characters in URLs</li>
|
|
<li>• Spaces become %20, ampersands become %26, etc.</li>
|
|
<li>• Use encoding when building query parameters with special characters</li>
|
|
<li>• Decoding helps you read encoded URLs and parameters</li>
|
|
</ul>
|
|
</div>
|
|
</ToolLayout>
|
|
);
|
|
};
|
|
|
|
export default UrlTool;
|