Compare commits

..

2 Commits

Author SHA1 Message Date
36f352de58 Auto 2026-02-27 20:08:32 +00:00
734dbfe24b Autovervollständigung 2026-02-27 20:07:45 +00:00
2 changed files with 85 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
import { NextResponse } from 'next/server';
import { getDbPool } from '@/lib/db';
import { RowDataPacket } from 'mysql2';
// GET /api/ausgaben/autocomplete - Fetch unique Wo and Was values for autocomplete
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url);
const typ = searchParams.get('typ');
const pool = getDbPool();
let query = 'SELECT DISTINCT Wo, Was FROM Ausgaben';
const params: any[] = [];
if (typ !== null && typ !== undefined) {
query += ' WHERE TYP = ?';
params.push(parseInt(typ));
}
query += ' ORDER BY Wo, Was';
const [rows] = await pool.query<RowDataPacket[]>(query, params);
// Extract unique Wo and Was values
const woSet = new Set<string>();
const wasSet = new Set<string>();
rows.forEach((row) => {
if (row.Wo) woSet.add(row.Wo);
if (row.Was) wasSet.add(row.Was);
});
const wo = Array.from(woSet).sort();
const was = Array.from(wasSet).sort();
return NextResponse.json({
success: true,
data: {
wo,
was,
},
});
} catch (error) {
console.error('Database error:', error);
return NextResponse.json(
{ success: false, error: 'Database error' },
{ status: 500 }
);
}
}

View File

@@ -32,6 +32,10 @@ export default function AusgabenForm({ onSuccess, selectedEntry, typ }: Ausgaben
const [year, setYear] = useState(''); const [year, setYear] = useState('');
const [isLoadingStats, setIsLoadingStats] = useState(false); const [isLoadingStats, setIsLoadingStats] = useState(false);
// Autocomplete data
const [autoCompleteWo, setAutoCompleteWo] = useState<string[]>([]);
const [autoCompleteWas, setAutoCompleteWas] = useState<string[]>([]);
const fetchStats = useCallback(async (y: string, m: string) => { const fetchStats = useCallback(async (y: string, m: string) => {
if (!y || !m) return; if (!y || !m) return;
@@ -49,6 +53,19 @@ export default function AusgabenForm({ onSuccess, selectedEntry, typ }: Ausgaben
} }
}, [typ]); }, [typ]);
const fetchAutoComplete = useCallback(async () => {
try {
const response = await fetch(`/api/ausgaben/autocomplete?typ=${typ}`);
const data = await response.json();
if (data.success) {
setAutoCompleteWo(data.data.wo);
setAutoCompleteWas(data.data.was);
}
} catch (error) {
console.error('Error fetching autocomplete data:', error);
}
}, [typ]);
// Initialize month/year on first load // Initialize month/year on first load
useEffect(() => { useEffect(() => {
const now = new Date(); const now = new Date();
@@ -65,6 +82,11 @@ export default function AusgabenForm({ onSuccess, selectedEntry, typ }: Ausgaben
} }
}, [month, year, typ, fetchStats]); }, [month, year, typ, fetchStats]);
// Fetch autocomplete data when typ changes
useEffect(() => {
fetchAutoComplete();
}, [typ, fetchAutoComplete]);
const handleMonthChange = (newMonth: string) => { const handleMonthChange = (newMonth: string) => {
setMonth(newMonth); setMonth(newMonth);
}; };
@@ -248,8 +270,14 @@ export default function AusgabenForm({ onSuccess, selectedEntry, typ }: Ausgaben
onChange={(e) => setFormData({ ...formData, Wo: e.target.value })} onChange={(e) => setFormData({ ...formData, Wo: e.target.value })}
className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none" className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none"
placeholder="Geschäft/Ort" placeholder="Geschäft/Ort"
list="wo-suggestions"
required required
/> />
<datalist id="wo-suggestions">
{autoCompleteWo.map((wo, index) => (
<option key={index} value={wo} />
))}
</datalist>
</td> </td>
<td className="p-2"> <td className="p-2">
<input <input
@@ -258,8 +286,14 @@ export default function AusgabenForm({ onSuccess, selectedEntry, typ }: Ausgaben
onChange={(e) => setFormData({ ...formData, Was: e.target.value })} onChange={(e) => setFormData({ ...formData, Was: e.target.value })}
className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none" className="w-full px-2 py-1 text-base rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none"
placeholder="Beschreibung" placeholder="Beschreibung"
list="was-suggestions"
required required
/> />
<datalist id="was-suggestions">
{autoCompleteWas.map((was, index) => (
<option key={index} value={was} />
))}
</datalist>
</td> </td>
<td className="p-2 w-24"> <td className="p-2 w-24">
<input <input