diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx new file mode 100644 index 0000000..dac49df --- /dev/null +++ b/frontend/src/App.jsx @@ -0,0 +1,733 @@ +import { useState, useEffect, useRef, useCallback } from 'react'; +import { api, S } from './lib.js'; +import { TOOLS, getGroupedTools } from './toolRegistry.js'; + +const ICONS = ['๐','๐','๐','๐','๐ ','๐ง','๐','๐พ','๐ฅ','๐ก','๐','๐','๐ฏ','โก','๐ ','๐ง','๐ฑ','๐ฎ','๐','๐ก']; + +// โโ Responsive Hook โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ +function useIsMobile() { + const [mobile, setMobile] = useState(window.innerWidth < 768); + useEffect(() => { + // Nur auf Breite reagieren, nicht auf Keyboard-Open (Hรถhenรคnderung) + const fn = () => { + const isMob = window.innerWidth < 768; + setMobile(prev => prev === isMob ? prev : isMob); + }; + window.addEventListener('resize', fn); + return () => window.removeEventListener('resize', fn); + }, []); + return mobile; +} + +// โโ Toast โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ +function Toast({ msg, type }) { + if (!msg) return null; + const c = type === 'error' ? '#ff6b9d' : '#4ecdc4'; + return ( +
{r.body}
+ docker compose up -d --build
+ + {new Date().toLocaleDateString('de-DE', { weekday:'long', day:'numeric', month:'long' })} +
++ Vollstรคndige SQLite-Datenbank sichern oder wiederherstellen. +
+