Add 8 new tools: Hash Verifier, URL Tool, String Utils, Cron Explainer, IP Calc, Lorem Ipsum, CSV Viewer, Notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Nirodan
2026-05-06 09:10:25 +02:00
parent ef03e76950
commit 75062dbf5e
20 changed files with 1727 additions and 2 deletions
@@ -0,0 +1,92 @@
import { useState } from 'react';
import axios from '../services/api';
const TYPES = [
{ value: 'words', label: 'Wörter' },
{ value: 'sentences', label: 'Sätze' },
{ value: 'paragraphs', label: 'Absätze' },
];
function LoremIpsumTool() {
const [type, setType] = useState('sentences');
const [count, setCount] = useState(3);
const [result, setResult] = useState('');
const [error, setError] = useState('');
const [copied, setCopied] = useState(false);
const generate = async () => {
setError('');
setResult('');
try {
const res = await axios.post('/api/lorem/generate', { type, count });
setResult(res.data.text);
} catch (err) {
setError(err.response?.data?.message || 'Fehler bei der Generierung');
}
};
const copy = () => {
navigator.clipboard.writeText(result);
setCopied(true);
setTimeout(() => setCopied(false), 1500);
};
return (
<div className="main-content">
<h2>Lorem Ipsum Generator</h2>
<p style={{ color: 'var(--muted)', marginBottom: '16px', fontSize: '0.95rem' }}>
Blindtext für Designs und Mockups generieren.
</p>
<div style={{ display: 'flex', gap: '6px', marginBottom: '12px' }}>
{TYPES.map(({ value, label }) => (
<button
key={value}
className={type === value ? '' : 'ghost'}
onClick={() => setType(value)}
style={{ margin: 0 }}
>
{label}
</button>
))}
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '12px' }}>
<label style={{ color: 'var(--text)', fontWeight: 600, fontSize: '0.9rem', whiteSpace: 'nowrap' }}>
Anzahl:
</label>
<input
type="number"
min={1}
max={20}
value={count}
onChange={(e) => setCount(Math.max(1, Math.min(20, Number(e.target.value))))}
style={{ width: '80px' }}
/>
<span style={{ color: 'var(--muted)', fontSize: '0.85rem' }}>(120)</span>
</div>
<button onClick={generate}>Generieren</button>
{error && <p className="error" style={{ marginTop: '12px' }}>{error}</p>}
{result && (
<div style={{ marginTop: '14px' }}>
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '6px' }}>
<button className="ghost" onClick={copy} style={{ margin: 0, padding: '6px 14px', fontSize: '0.85rem' }}>
{copied ? 'Kopiert!' : 'Kopieren'}
</button>
</div>
<textarea
rows={10}
readOnly
value={result}
style={{ resize: 'vertical', color: 'var(--muted)', fontFamily: 'inherit', lineHeight: '1.6' }}
/>
</div>
)}
</div>
);
}
export default LoremIpsumTool;