From 7ba3dd68198a5ec7fd426a8bf5ea26a40aa35c77 Mon Sep 17 00:00:00 2001 From: dvirlabs Date: Tue, 3 Jun 2025 07:24:23 +0300 Subject: [PATCH] Add form to add new app/section --- frontend/src/components/ControlPanel.jsx | 45 ++++++++++++++++++++++++ frontend/src/services/api.js | 15 ++++++++ frontend/src/style/ControlPanel.css | 27 ++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 frontend/src/components/ControlPanel.jsx create mode 100644 frontend/src/services/api.js create mode 100644 frontend/src/style/ControlPanel.css diff --git a/frontend/src/components/ControlPanel.jsx b/frontend/src/components/ControlPanel.jsx new file mode 100644 index 0000000..d8b5b11 --- /dev/null +++ b/frontend/src/components/ControlPanel.jsx @@ -0,0 +1,45 @@ +import { useState } from 'react'; +import { addAppToSection } from '../services/api'; +import '../style/ControlPanel.css'; + +function ControlPanel({ onUpdate }) { + const [section, setSection] = useState(''); + const [name, setName] = useState(''); + const [icon, setIcon] = useState(''); + const [description, setDescription] = useState(''); + const [url, setUrl] = useState(''); + + const handleSubmit = async (e) => { + e.preventDefault(); + if (!section || !name || !url) return; + + try { + await addAppToSection({ + section, + app: { name, icon, description, url } + }); + + if (onUpdate) onUpdate(); + setSection(''); + setName(''); + setIcon(''); + setDescription(''); + setUrl(''); + } catch (err) { + console.error('Failed to add app:', err); + } + }; + + return ( +
+ setSection(e.target.value)} /> + setName(e.target.value)} /> + setIcon(e.target.value)} /> + setDescription(e.target.value)} /> + setUrl(e.target.value)} /> + +
+ ); +} + +export default ControlPanel; diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js new file mode 100644 index 0000000..290463b --- /dev/null +++ b/frontend/src/services/api.js @@ -0,0 +1,15 @@ +export async function fetchSections() { + const res = await fetch('/apps'); + if (!res.ok) throw new Error('Failed to fetch sections'); + return res.json(); +} + +export async function addAppToSection({ section, app }) { + const res = await fetch('/add_app', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ section, app }) + }); + if (!res.ok) throw new Error(await res.text()); + return res.json(); +} \ No newline at end of file diff --git a/frontend/src/style/ControlPanel.css b/frontend/src/style/ControlPanel.css new file mode 100644 index 0000000..ed27afc --- /dev/null +++ b/frontend/src/style/ControlPanel.css @@ -0,0 +1,27 @@ +.control-panel { + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-bottom: 2rem; + background-color: #1e1e1e; + padding: 1rem; + border-radius: 8px; + max-width: 400px; +} + +.control-panel input, +.control-panel button { + padding: 0.5rem; + border: none; + border-radius: 4px; +} + +.control-panel button { + background-color: #007bff; + color: white; + cursor: pointer; +} + +.control-panel button:hover { + background-color: #0056b3; +}