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:
@@ -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' }}>(1–20)</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;
|
||||
Reference in New Issue
Block a user