diff --git a/002.FRONTEND/src/components/RadniNalogLista.jsx b/002.FRONTEND/src/components/RadniNalogLista.jsx deleted file mode 100644 index 1615676..0000000 --- a/002.FRONTEND/src/components/RadniNalogLista.jsx +++ /dev/null @@ -1,29 +0,0 @@ -// src/components/RadniNalogLista.jsx -import { h } from 'preact'; -import { useEffect } from 'preact/hooks'; -import { useStore } from '@nanostores/preact'; -import { radniNalozi, setRadniNalozi } from '../stores/operativaStore'; - -export default function RadniNalogLista({ nalozi = [], limit = 5 }) { - useEffect(() => { - if (nalozi.length > 0) setRadniNalozi(nalozi); - }, [nalozi]); - - const podaciIzStora = useStore(radniNalozi); - - if (!podaciIzStora.length) return
Učitavanje...
; - - return ( - - ); -} \ No newline at end of file diff --git a/002.FRONTEND/src/components/common/LoadingSpinner.jsx b/002.FRONTEND/src/components/common/LoadingSpinner.jsx new file mode 100644 index 0000000..44a3b1b --- /dev/null +++ b/002.FRONTEND/src/components/common/LoadingSpinner.jsx @@ -0,0 +1,11 @@ +// src/components/common/LoadingSpinner.jsx +import { h } from 'preact'; + +export default function LoadingSpinner({ text = "Učitavanje podataka..." }) { + return ( +
+
+ {text} +
+ ); +} \ No newline at end of file diff --git a/002.FRONTEND/src/components/common/UniversalList.jsx b/002.FRONTEND/src/components/common/UniversalList.jsx new file mode 100644 index 0000000..21cd35c --- /dev/null +++ b/002.FRONTEND/src/components/common/UniversalList.jsx @@ -0,0 +1,46 @@ +// src/components/common/UniversalList.jsx +import { h } from 'preact'; +import { useEffect, useState } from 'preact/hooks'; +import { useStore } from '@nanostores/preact'; +import { getBaseUrl } from '../lib/nav'; +import LoadingSpinner from './LoadingSpinner.jsx'; + +export default function UniversalList({ store, setter, fetchMethod, limit, baseName, children }) { + const [loading, setLoading] = useState(true); + const list = useStore(store); + + // Ako je baseName poslan, dohvati URL, inače ostavi undefined + const baseUrl = baseName ? getBaseUrl(baseName) : undefined; + + useEffect(() => { + async function fetchData() { + if (list.length > 0) { + setLoading(false); + return; + } + + try { + setLoading(true); + const data = await fetchMethod(); + setter(data || []); + } catch (error) { + console.error("Greška pri dohvatu:", error); + setter([]); + } finally { + setTimeout(() => setLoading(false), 1000); + } + } + fetchData(); + }, []); + + if (loading) return ; + + const displayList = limit ? list.slice(0, limit) : list; + + return ( +
+ {/* children funkcija sada prima item i opcionalni baseUrl */} + {displayList.map(item => children(item, baseUrl))} +
+ ); +} \ No newline at end of file diff --git a/002.FRONTEND/src/components/edit/RadniNalogEditorStatus.jsx b/002.FRONTEND/src/components/edit/RadniNalogEditorStatus.jsx deleted file mode 100644 index 6e54feb..0000000 --- a/002.FRONTEND/src/components/edit/RadniNalogEditorStatus.jsx +++ /dev/null @@ -1,31 +0,0 @@ -// src/components/edit/RadniNalogEditorStatus.jsx -// Ovo postaje višak -import { h } from 'preact'; -import { useState } from 'preact/hooks'; -import { patchNalog } from '../../lib/api'; -import Button from '../Button'; // Import nove komponente - -export default function RadniNalogEditorStatus({ nalogId, pocetniStatus }) { - const [status, setStatus] = useState(pocetniStatus); - const [loading, setLoading] = useState(false); - - const azurirajStatus = async () => { - setLoading(true); - const rezultat = await patchNalog(nalogId, { status: 'ZAVRSENO' }); - setLoading(false); - - if (rezultat) { - setStatus('ZAVRSENO'); - window.showToast?.("Status ažuriran", "success"); - } - }; - - return ( - - - ); + {formData.putni_mode === 'existing' && ( + setFormData({...formData, putni_id: e.target.value})} + renderItem={pn => } + /> + )} + + + + + ); } \ No newline at end of file diff --git a/002.FRONTEND/src/layouts/Layout.astro b/002.FRONTEND/src/layouts/Layout.astro index 6e31c38..bdb1679 100644 --- a/002.FRONTEND/src/layouts/Layout.astro +++ b/002.FRONTEND/src/layouts/Layout.astro @@ -72,13 +72,13 @@ const { title } = Astro.props; ))} - +
- +
-
+
diff --git a/002.FRONTEND/src/lib/nav.js b/002.FRONTEND/src/lib/nav.js new file mode 100644 index 0000000..428923c --- /dev/null +++ b/002.FRONTEND/src/lib/nav.js @@ -0,0 +1,7 @@ +// src/lib/nav.js +import siteConfig from '../data/site.json'; + +export function getBaseUrl(name) { + const item = siteConfig.navigation.find(n => n.name === name); + return item ? item.url : '/'; +} \ No newline at end of file diff --git a/002.FRONTEND/src/pages/fleet/strojevi.astro b/002.FRONTEND/src/pages/fleet/strojevi.astro index f31d1c1..421b5f6 100644 --- a/002.FRONTEND/src/pages/fleet/strojevi.astro +++ b/002.FRONTEND/src/pages/fleet/strojevi.astro @@ -1,6 +1,7 @@ --- +// srs/pages/fleet/strojevi.astro import Layout from '../../layouts/Layout.astro'; -import FleetStrojeviLista from '../../components/FleetStrojeviLista.jsx'; +import FleetStrojeviLista from '../../components/lista/FleetStrojeviLista.jsx'; import { getStrojevi } from '../../lib/api'; // Ovdje koristi getStrojevi const strojeviData = await getStrojevi(); // I ovdje koristi getStrojevi @@ -10,6 +11,6 @@ const strojeviData = await getStrojevi(); // I ovdje koristi getStrojevi

Pregled strojeva

- +
\ No newline at end of file diff --git a/002.FRONTEND/src/pages/index.astro b/002.FRONTEND/src/pages/index.astro index 97af0ec..f12c17c 100644 --- a/002.FRONTEND/src/pages/index.astro +++ b/002.FRONTEND/src/pages/index.astro @@ -2,11 +2,9 @@ // src/pages/index.astro import Layout from "../layouts/Layout.astro"; import siteConfig from "../data/site.json"; -import { getRadniNalozi, getVozila } from "../lib/api"; -import RadniNalogLista from '../components/RadniNalogLista.jsx'; - -const nalozi = await getRadniNalozi(); -const vozila = await getVozila(); +import RadniNalogLista from '../components/lista/RadniNalogLista.jsx'; +import FleetStrojeviLista from '../components/lista/FleetStrojeviLista.jsx'; +import FleetVozilaLista from "../components/lista/FleetVozilaLista"; --- @@ -18,19 +16,18 @@ const vozila = await getVozila();

Radni nalozi

- + {/* client:only osigurava da se lista sama dohvati u pregledniku */} +

Stanje flote

-
-

Ukupno vozila: {vozila.length}

-
    - {vozila.map((vozilo) => ( -
  • {vozilo.marka} {vozilo.model} ({vozilo.registracija})
  • - ))} -
-
+ +
+ +
+

Stanje flote

+
diff --git a/biljeske/SKELETON_LIST_VIEW.md b/biljeske/SKELETON_LIST_VIEW.md new file mode 100644 index 0000000..1fc3f50 --- /dev/null +++ b/biljeske/SKELETON_LIST_VIEW.md @@ -0,0 +1,114 @@ +## Skeleton za List View + +```jsx +// src/components/common/UniversalList.jsx +import { h } from 'preact'; +import { useEffect, useState } from 'preact/hooks'; +import { useStore } from '@nanostores/preact'; +import { getBaseUrl } from '../lib/nav'; +import LoadingSpinner from './LoadingSpinner.jsx'; + +export default function UniversalList({ store, setter, fetchMethod, limit, baseName, children }) { + const [loading, setLoading] = useState(true); + const list = useStore(store); + + // Ako je baseName poslan, dohvati URL, inače ostavi undefined + const baseUrl = baseName ? getBaseUrl(baseName) : undefined; + + useEffect(() => { + async function fetchData() { + if (list.length > 0) { + setLoading(false); + return; + } + + try { + setLoading(true); + const data = await fetchMethod(); + setter(data || []); + } catch (error) { + console.error("Greška pri dohvatu:", error); + setter([]); + } finally { + setTimeout(() => setLoading(false), 1000); + } + } + fetchData(); + }, []); + + if (loading) return ; + + const displayList = limit ? list.slice(0, limit) : list; + + return ( +
+ {/* children funkcija sada prima item i opcionalni baseUrl */} + {displayList.map(item => children(item, baseUrl))} +
+ ); +} +``` + +## Loading komponenta + +```jsx +// src/components/common/LoadingSpinner.jsx +import { h } from 'preact'; + +export default function LoadingSpinner({ text = "Učitavanje podataka..." }) { + return ( +
+
+ {text} +
+ ); +} +``` + +## Komponenta FleetStrojeviLista.jsx koristi Skeleton + +```jsx +/// src/components/fleet/FleetStrojeviLista.jsx +import { h } from 'preact'; +import UniversalList from '../common/UniversalList.jsx'; +import { strojevi, setStrojevi } from '../stores/fleetStore'; +import { getStrojevi } from '../lib/api'; + +export default function FleetStrojeviLista({ limit = 10 }) { + return ( + + {(s, baseUrl) => ( +
+
+

{s.naziv}

+ + {s.tip_human_readable} + +
+ +
    +
  • Marka/Model: {s.marka} {s.model_stroja}
  • +
  • Serijski br: {s.serijski_broj}
  • +
  • Vlasnik: {s.vlasnik_naziv}
  • +
  • Radni sati: {s.radni_sati} h
  • + {s.registracija &&
  • Reg: {s.registracija}
  • } +
+ + + Pregled detalja + +
+ )} +
+ ); +} +``` \ No newline at end of file