Javno odobravanje predloga: Prihvati/Odbij sa komentarom

- Dodati handleri za prihvatanje i odbijanje predloga sa mobilnog
- Prihvatanje: predložene stavke prelaze u ugrađene (predlozeno 1→0)
- Odbijanje: brišu se predložene stavke
- Komentar klijenta uz odluku (textarea na mobilnom, prikaz u detaljima)
- Oznaka na kanbanu za naloge sa predlozima (narandžasta tačka + leva ivica)
- Oznaka na kanbanu za poruku klijenta (💬 dugme, tap za prikaz)
- Spojene kartice Radovi/Predložene usluge i Delovi/Predloženi delovi
- Auto-detekcija predlozeno=1 kad status != Primljeno
- Obrisana Otključaj/Zaključaj dugmad
- Ukupno sa predlogom na javnoj status stranici
- CSRF middleware premešten u zaštićenu grupu
- Migracija 078: komentar_klijenta
- Repo metode: ObrisiPredlozene, AzurirajKomentarKlijenta
- Popravljeno: 405 na odbij, duple rute, razmak između kartica
This commit is contained in:
2026-06-24 02:41:06 +02:00
parent af33d5c20d
commit d6b3e7149c
19 changed files with 699 additions and 148 deletions
+10
View File
@@ -1308,6 +1308,9 @@ select {
transform: translateY(-1px);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
}
.kanban-ceka-odobrenje {
border-left: 3px solid #f59e0b;
}
/* dugme uz SN broj — otvara internu napomenu */
.napomena-omot {
display: inline-flex;
@@ -1365,6 +1368,13 @@ select {
/* forme „Dodaj rad/deo" u detaljima naloga — grid u CSS (ne inline) da ga @media može nadjačati */
.detalji-forma-rad { display: grid; grid-template-columns: 1fr 80px 120px auto; gap: 10px; align-items: flex-end; }
.detalji-forma-deo { display: grid; grid-template-columns: 1fr 70px 80px 120px auto; gap: 10px; align-items: flex-end; }
/* predlog servisera — kartica sa narandžastim akcentom i bedž „Predlog" */
.predlog-kartica { border-left: 3px solid #f59e0b; }
.predlog-bedz {
display: inline-block; padding: 2px 10px; border-radius: 20px;
font-size: 11px; font-weight: 600; background: #f59e0b; color: #fff;
}
@media (max-width: 600px) {
/* na telefonu: dve kolone, dugme preko cele širine */
.detalji-forma-rad,
+1 -1
View File
@@ -235,7 +235,7 @@ document.addEventListener('alpine:init', () => {
const punoIme = ((k.Ime || '') + ' ' + (k.Prezime || '')).trim()
const polja = (tip === 'pravno') ? [k.NazivFirme] : [punoIme, k.Ime, k.Prezime]
return polja.some(p => (p || '').toLowerCase().startsWith(q))
}).slice(0, 8)
}).slice(0, 100)
},
jeTip(t) {
return this.tip === t
+9 -3
View File
@@ -48,12 +48,11 @@
<div class="kanban-kartice">
{{range $.Nalozi}}
{{if eq .Status $status}}
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" href="/servis/{{.ID}}" class="kartica kanban-karta">
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" href="/servis/{{.ID}}" class="kartica kanban-karta{{if .ImaPredlog}} kanban-ceka-odobrenje{{end}}">
<div style="display:flex;align-items:center;gap:6px;">
{{if .ImaPredlog}}<span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#f59e0b;flex-shrink:0;" title="Čeka odobrenje klijenta"></span>{{end}}
<span style="font-size:14px;font-weight:500;color:var(--sb-akcent);font-family:monospace;">{{.BrojNaloga}}</span>
{{if .Napomena}}
<!-- dugme uz SN broj otvara internu napomenu (hover na desktopu, tap→focus na mobilnom);
onclick sprečava da klik na dugme otvori sam nalog (kartica je hx-boost link) -->
<span class="napomena-omot">
<button type="button" class="napomena-dugme" aria-label="Interna napomena"
onclick="event.preventDefault();event.stopPropagation();">
@@ -68,6 +67,13 @@
<div class="karta-napomena">{{.Napomena}}</div>
</span>
{{end}}
{{if .KomentarKlijenta}}
<span class="napomena-omot">
<button type="button" class="napomena-dugme" aria-label="Poruka klijenta"
onclick="event.preventDefault();event.stopPropagation();">💬</button>
<div class="karta-napomena" style="border-color:#f59e0b;">{{.KomentarKlijenta}}</div>
</span>
{{end}}
</div>
<div style="font-size:13px;color:var(--tekst-glavni);margin-top:4px;">{{.Uredjaj}}</div>
{{if .KlijentNaziv}}
+86 -14
View File
@@ -166,6 +166,24 @@
{{end}}
</div>
</div>
<!-- poruka klijenta uz odluku o predlogu -->
{{if .Nalog.KomentarKlijenta}}
<div style="margin-bottom:16px;padding:14px 16px;background:rgba(245,158,11,0.08);border:1px solid rgba(245,158,11,0.3);border-radius:10px;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
{{if index .Dozvole "servis.izmeni"}}
<form method="POST" action="/servis/{{.Nalog.ID}}/obrisi-komentar-klijenta" style="margin:0;" data-refresh="#nalog-zaglavlje">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<button type="submit" data-potvrda="Obrisati poruku klijenta?" style="background:none;border:none;cursor:pointer;color:#94a3b8;font-size:16px;padding:0 2px;line-height:1;">×</button>
</form>
{{end}}
<span style="font-size:14px;">💬</span>
<span style="font-size:12px;font-weight:600;color:#f59e0b;text-transform:uppercase;letter-spacing:0.5px;flex:1;">Poruka klijenta</span>
</div>
<div style="font-size:14px;color:var(--tekst-glavni);line-height:1.5;white-space:pre-wrap;">{{.Nalog.KomentarKlijenta}}</div>
</div>
{{end}}
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(140px, 1fr));gap:16px;">
<div>
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Datum prijema</div>
@@ -426,16 +444,18 @@
{{/* kartice radova/delova se ne prikazuju kad je popravka odbijena (samo dijagnostika)
ni kad je nalog „Završeno"/„Preuzeto" (posao gotov — sume ostaju u kartici Ukupno) */}}
{{if and (not .Nalog.PopravkaOdbijena) (ne .Nalog.Status "Završeno") (ne .Nalog.Status "Preuzeto")}}
<!-- radovi (usluge) -->
<div id="radovi-blok">
<!-- radovi (usluge) — traženi pri prijemu -->
<div class="kartica detalji-kartica animiraj" id="radovi-kartica">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);flex-wrap:wrap;gap:10px;">
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Radovi (usluge)</span>
</div>
<!-- forma za dodavanje rada iz cenovnika usluga -->
<!-- forma za dodavanje rada — u dijagnostici se automatski beleži kao predlog -->
{{if index .Dozvole "servis.izmeni"}}
<form method="POST" action="/servis/{{.Nalog.ID}}/radovi" style="margin-bottom:16px;" data-refresh="#radovi-kartica, #nalog-ukupno">
<form method="POST" action="/servis/{{.Nalog.ID}}/radovi" style="margin-bottom:16px;" data-refresh="#radovi-blok, #nalog-ukupno">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
{{if .ZakljucaniUgradjeni}}<input type="hidden" name="predlozeno" value="1">{{end}}
<div class="detalji-forma-rad">
<div>
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Usluga</label>
@@ -461,7 +481,7 @@
<!-- lista radova -->
<div id="radovi-spisak">
{{if .ServisniRadovi}}
{{if or .ServisniRadovi .PredlozeniRadovi}}
<div class="tabela-skrol">
<table class="tabela">
<thead>
@@ -481,8 +501,8 @@
<td style="padding:9px 10px;text-align:right;font-size:14px;color:var(--tekst-glavni);">{{dinari .CenaKomada}} din</td>
<td style="padding:9px 10px;text-align:right;font-size:14px;font-weight:500;color:var(--tekst-glavni);">{{dinari .Ukupno}} din</td>
<td style="padding:9px 10px;text-align:center;">
{{if index $.Dozvole "servis.izmeni"}}
<form method="POST" action="/servis/{{$.Nalog.ID}}/radovi/{{.ID}}/obrisi" style="display:inline;" data-refresh="#radovi-kartica, #nalog-ukupno">
{{if and (not $.ZakljucaniUgradjeni) (index $.Dozvole "servis.izmeni")}}
<form method="POST" action="/servis/{{$.Nalog.ID}}/radovi/{{.ID}}/obrisi" style="display:inline;" data-refresh="#radovi-blok, #nalog-ukupno">
<input type="hidden" name="_csrf" value="{{$.CsrfToken}}">
<button type="submit"
data-potvrda="Ukloniti rad '{{.Naziv}}'?"
@@ -494,6 +514,26 @@
</td>
</tr>
{{end}}
{{range .PredlozeniRadovi}}
<tr style="border-bottom:0.5px solid var(--ivica);background:rgba(245,158,11,0.08);">
<td style="padding:9px 10px;font-size:14px;color:var(--tekst-glavni);">{{.Naziv}} <span class="predlog-bedz" style="font-size:10px;padding:1px 7px;">Predlog</span></td>
<td style="padding:9px 10px;text-align:center;font-size:14px;color:var(--tekst-glavni);">{{.Kolicina}}</td>
<td style="padding:9px 10px;text-align:right;font-size:14px;color:var(--tekst-glavni);">{{dinari .CenaKomada}} din</td>
<td style="padding:9px 10px;text-align:right;font-size:14px;font-weight:500;color:var(--tekst-glavni);">{{dinari .Ukupno}} din</td>
<td style="padding:9px 10px;text-align:center;">
{{if index $.Dozvole "servis.izmeni"}}
<form method="POST" action="/servis/{{$.Nalog.ID}}/radovi/{{.ID}}/obrisi" style="display:inline;" data-refresh="#radovi-blok, #nalog-ukupno">
<input type="hidden" name="_csrf" value="{{$.CsrfToken}}">
<button type="submit"
data-potvrda="Ukloniti predloženi rad '{{.Naziv}}'?"
style="background:none;border:none;cursor:pointer;color:#dc2626;font-size:16px;padding:2px 6px;border-radius:4px;">
×
</button>
</form>
{{end}}
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
@@ -504,17 +544,20 @@
{{end}}
</div>
</div>
</div>
<!-- ugrađeni delovi -->
<div class="kartica detalji-kartica animiraj">
<div id="delovi-blok">
<div class="kartica detalji-kartica animiraj" id="delovi-kartica">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);flex-wrap:wrap;gap:10px;">
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Ugrađeni delovi</span>
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Delovi</span>
</div>
<!-- forma za dodavanje dela -->
<!-- forma za dodavanje dela — u dijagnostici se automatski beleži kao predlog -->
{{if index .Dozvole "servis.izmeni"}}
<form method="POST" action="/servis/{{.Nalog.ID}}/delovi" style="margin-bottom:16px;" data-refresh="#delovi-spisak, #nalog-zaglavlje, #nalog-ukupno">
<form method="POST" action="/servis/{{.Nalog.ID}}/delovi" style="margin-bottom:16px;" data-refresh="#delovi-blok, #nalog-zaglavlje, #nalog-ukupno">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
{{if .ZakljucaniUgradjeni}}<input type="hidden" name="predlozeno" value="1">{{end}}
<div style="margin-bottom:10px;">
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Kategorija</label>
<select id="deo-kategorija" style="width:100%;"></select>
@@ -547,7 +590,7 @@
<!-- lista delova -->
<div id="delovi-spisak">
{{if .ServisniDelovi}}
{{if or .ServisniDelovi .PredlozeniDelovi}}
<div class="tabela-skrol">
<table class="tabela">
<thead>
@@ -573,8 +616,8 @@
{{if .Kolicina}}{{dinari .Ukupno}} din{{else}}—{{end}}
</td>
<td style="padding:9px 10px;text-align:center;">
{{if and .ID (index $.Dozvole "servis.izmeni")}}
<form method="POST" action="/servis/{{$.Nalog.ID}}/delovi/{{.ID}}/obrisi" style="display:inline;" data-refresh="#delovi-spisak, #nalog-zaglavlje, #nalog-ukupno">
{{if and (not $.ZakljucaniUgradjeni) (index $.Dozvole "servis.izmeni")}}
<form method="POST" action="/servis/{{$.Nalog.ID}}/delovi/{{.ID}}/obrisi" style="display:inline;" data-refresh="#delovi-blok, #nalog-zaglavlje, #nalog-ukupno">
<input type="hidden" name="_csrf" value="{{$.CsrfToken}}">
<button type="submit"
data-potvrda="Ukloniti deo '{{.ArtikalNaziv}}'?"
@@ -586,18 +629,47 @@
</td>
</tr>
{{end}}
{{range .PredlozeniDelovi}}
<tr data-artikal-id="{{.ArtikalID}}" data-kolicina="{{.Kolicina}}" data-potrazivano="{{.Potrazivano}}" style="border-bottom:0.5px solid var(--ivica);background:rgba(245,158,11,0.08);{{if .Potrazivano}}background:rgba(220,38,38,0.06);{{end}}">
<td style="padding:9px 10px;font-size:14px;color:var(--tekst-glavni);">{{.ArtikalNaziv}} <span class="predlog-bedz" style="font-size:10px;padding:1px 7px;">Predlog</span></td>
<td style="padding:9px 10px;text-align:center;font-size:14px;{{if .Potrazivano}}color:#dc2626;font-weight:600;{{else}}color:var(--tekst-glavni);{{end}}">
{{.Kolicina}}{{if .Potrazivano}}<span style="font-weight:400;"> + {{.Potrazivano}} na čekanju</span>{{end}}
</td>
<td style="padding:9px 10px;text-align:right;font-size:14px;color:var(--tekst-glavni);">
{{if .Kolicina}}{{dinari .CenaKomada}} din{{else}}—{{end}}
</td>
<td style="padding:9px 10px;text-align:right;font-size:14px;font-weight:500;color:var(--tekst-glavni);">
{{if .Kolicina}}{{dinari .Ukupno}} din{{else}}—{{end}}
</td>
<td style="padding:9px 10px;text-align:center;">
{{if and .ID (index $.Dozvole "servis.izmeni")}}
<form method="POST" action="/servis/{{$.Nalog.ID}}/delovi/{{.ID}}/obrisi" style="display:inline;" data-refresh="#delovi-blok, #nalog-zaglavlje, #nalog-ukupno">
<input type="hidden" name="_csrf" value="{{$.CsrfToken}}">
<button type="submit"
data-potvrda="Ukloniti predloženi deo '{{.ArtikalNaziv}}'?"
style="background:none;border:none;cursor:pointer;color:#dc2626;font-size:16px;padding:2px 6px;border-radius:4px;">
×
</button>
</form>
{{end}}
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{else}}
<div style="font-size:13px;color:var(--tekst-sporedni);text-align:center;padding:16px 0;">
Nema ugrađenih delova za ovaj nalog.
Nema delova za ovaj nalog.
</div>
{{end}}
</div>
</div>
</div>
{{end}}
<!-- ukupno: zbir usluga (radova) i ugrađenih delova -->
<div id="nalog-ukupno" class="kartica detalji-kartica animiraj">
<div style="margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);">
@@ -122,8 +122,22 @@
<div class="odeljak-naslov">Uređaj i traženi radovi</div>
<div style="margin-bottom:6px;"><strong>Uređaj:</strong> {{if .Nalog.Uredjaj}}{{.Nalog.Uredjaj}}{{else}}<span class="prazno"></span>{{end}}{{if .Nalog.SerijskiBroj}} &middot; S/N: {{.Nalog.SerijskiBroj}}{{end}}</div>
<div class="polje-tekst"><strong>Zahtev klijenta:</strong> {{if .Nalog.OpisKvara}}{{.Nalog.OpisKvara}}{{else}}<span class="prazno"></span>{{end}}</div>
{{if .Nalog.TrazeneNadogradnje}}
<div class="polje-tekst" style="margin-top:6px;"><strong>Tražene nadogradnje:</strong> {{.Nalog.TrazeneNadogradnje}}</div>
{{end}}
{{if .Nalog.NapomenaKlijentu}}
<div class="polje-tekst" style="margin-top:6px;"><strong>Napomena klijentu:</strong> {{.Nalog.NapomenaKlijentu}}</div>
{{end}}
</div>
<!-- utvrđen kvar (rezultat dijagnostike) -->
{{if .Nalog.NalazDijagnostike}}
<div class="odeljak">
<div class="odeljak-naslov">Utvrđen kvar</div>
<div class="polje-tekst">{{.Nalog.NalazDijagnostike}}</div>
</div>
{{end}}
<!-- radovi -->
{{if .Radovi}}
<div class="odeljak">
+48 -13
View File
@@ -86,7 +86,14 @@
<div class="zg-okvir" style="font-size:12px;line-height:1.6;">
<div class="polje-labela">Klijent</div>
<div class="polje-vrednost">{{if .KlijentNaziv}}{{.KlijentNaziv}}{{else}}<span class="prazno"></span>{{end}}</div>
{{if .KlijentTelefon}}<div style="color:#555;">Tel: {{telefon .KlijentTelefon}}</div>{{end}}
{{if .Klijent}}
<div style="color:#555;">
{{if .Klijent.Telefon}}Tel: {{telefon .Klijent.Telefon}}<br>{{end}}
{{if .Klijent.Email}}{{.Klijent.Email}}<br>{{end}}
{{if .Klijent.Mesto}}{{.Klijent.Mesto}}<br>{{end}}
{{if .Klijent.PIB}}PIB: {{.Klijent.PIB}}{{end}}
</div>
{{end}}
</div>
<!-- DESNO: barkod na vrhu, ispod broj + status + datumi + serviser -->
<div class="zg-okvir" style="flex:1.3;">
@@ -151,10 +158,49 @@
{{end}}
</div>
<!-- utvrđen kvar (rezultat dijagnostike) -->
{{if .Nalog.NalazDijagnostike}}
<div class="odeljak">
<div class="odeljak-naslov">Utvrđeni kvar</div>
<div class="polje-tekst">{{.Nalog.NalazDijagnostike}}</div>
</div>
{{end}}
<!-- napomena klijentu -->
{{if .Nalog.NapomenaKlijentu}}
<div class="odeljak">
<div class="odeljak-naslov">Napomena klijentu</div>
<div class="polje-tekst">{{.Nalog.NapomenaKlijentu}}</div>
</div>
{{end}}
<!-- usluge koje serviser treba da uradi — bez cena -->
{{if .Radovi}}
<div class="odeljak">
<div class="odeljak-naslov">Usluge (radovi)</div>
<table class="tabela">
<thead>
<tr>
<th>Usluga</th>
<th class="desno" style="width:90px;">Količina</th>
</tr>
</thead>
<tbody>
{{range .Radovi}}
<tr>
<td>{{.Naziv}}</td>
<td class="desno">{{.Kolicina}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
<!-- rezervisani/ugrađeni delovi — bez cena -->
{{if .ServisniDelovi}}
<div class="odeljak">
<div class="odeljak-naslov">Delovi na nalogu</div>
<div class="odeljak-naslov">Delovi za ugradnju</div>
<table class="tabela">
<thead>
<tr>
@@ -174,17 +220,6 @@
</div>
{{end}}
<!-- prazna polja za servisera -->
<div class="odeljak">
<div class="upis-labela">Dijagnoza / utvrđen kvar</div>
<div class="upis-okvir upis-veliki"></div>
</div>
<div class="odeljak">
<div class="upis-labela">Urađen rad</div>
<div class="upis-okvir upis-veliki"></div>
</div>
<!-- vreme i potpis -->
<div class="zavrsetak">
<div>
+3 -1
View File
@@ -59,6 +59,8 @@
.strana { padding: 16px 20px; max-width: 100%; }
.dugme-stampa { display: none !important; }
@page { size: A4; margin: 12mm 14mm; }
/* uslovi servisa (sa potpisima) idu na novu stranicu */
.uslovi-strana { break-before: page; }
}
.dugme-stampa { position: fixed; bottom: 24px; right: 24px; background: #111; color: #fff; border: none; padding: 12px 22px; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.2); }
.dugme-stampa:hover { background: #333; }
@@ -178,7 +180,7 @@
<!-- uslovi servisa -->
{{if .Uslovi}}
<div class="odeljak">
<div class="odeljak uslovi-strana">
<div class="odeljak-naslov">Uslovi servisa</div>
<div class="uslovi-blok">{{.Uslovi}}</div>
</div>
+129 -27
View File
@@ -6,21 +6,21 @@
<title>Status popravke — {{.Nalog.BrojNaloga}}</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif; font-size: 14px; color: #111; background: #f5f5f7; min-height: 100vh; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif; font-size: 14px; color: #e2e8f0; background: #0f172a; min-height: 100vh; }
.omotac { max-width: 480px; margin: 0 auto; padding: 24px 16px 48px; }
/* zaglavlje firme */
.zaglavlje { text-align: center; margin-bottom: 24px; }
.firma-naziv { font-size: 18px; font-weight: 700; color: #111; }
.firma-info { font-size: 12px; color: #666; margin-top: 4px; line-height: 1.6; }
.firma-naziv { font-size: 18px; font-weight: 700; color: #f1f5f9; }
.firma-info { font-size: 12px; color: #94a3b8; margin-top: 4px; line-height: 1.6; }
/* kartica naloga */
.kartica { background: #fff; border-radius: 16px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 4px rgba(0,0,0,0.08); }
.kartica-naslov { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; color: #999; margin-bottom: 12px; }
.kartica { background: #1e293b; border-radius: 16px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 4px rgba(0,0,0,0.35); }
.kartica-naslov { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; color: #94a3b8; margin-bottom: 12px; }
.uredjaj { font-size: 22px; font-weight: 700; color: #111; line-height: 1.2; }
.broj-naloga { font-size: 13px; color: #888; margin-top: 4px; font-family: monospace; }
.uredjaj { font-size: 22px; font-weight: 700; color: #f1f5f9; line-height: 1.2; }
.broj-naloga { font-size: 13px; color: #94a3b8; margin-top: 4px; font-family: monospace; }
/* status bedž */
.status-bedz {
@@ -40,39 +40,63 @@
/* napredak */
.napredak { margin: 16px 0 4px; }
.napredak-labela { font-size: 11px; color: #999; margin-bottom: 8px; }
.napredak-labela { font-size: 11px; color: #94a3b8; margin-bottom: 8px; }
.koraci { display: flex; gap: 4px; }
.korak {
flex: 1;
height: 5px;
border-radius: 3px;
background: #e5e7eb;
background: #334155;
}
.korak.aktivan { background: #10b981; }
.korak.zavrseno { background: #10b981; }
.korak.tekuci { background: #f59e0b; }
/* red podataka */
.red { display: flex; justify-content: space-between; align-items: flex-start; padding: 10px 0; border-bottom: 0.5px solid #f0f0f0; gap: 12px; }
.red { display: flex; justify-content: space-between; align-items: flex-start; padding: 10px 0; border-bottom: 0.5px solid #334155; gap: 12px; }
.red:last-child { border-bottom: none; }
.red-labela { font-size: 12px; color: #888; min-width: 0; overflow-wrap: anywhere; }
.red-vrednost { font-size: 13px; color: #111; font-weight: 500; text-align: right; flex-shrink: 0; white-space: nowrap; }
.red-labela { font-size: 12px; color: #94a3b8; min-width: 0; overflow-wrap: anywhere; }
.red-vrednost { font-size: 13px; color: #f1f5f9; font-weight: 500; text-align: right; flex-shrink: 0; white-space: nowrap; }
/* cena */
.cena-blok { background: #f9fafb; border-radius: 10px; padding: 14px 16px; margin-top: 4px; }
.cena-blok { background: #0f172a; border-radius: 10px; padding: 14px 16px; margin-top: 4px; }
.cena-od-do { display: flex; gap: 8px; align-items: center; }
.cena-od-do .cena-vrednost { font-size: 20px; font-weight: 700; color: #111; }
.cena-od-do .cena-sep { color: #bbb; }
.cena-labela { font-size: 11px; color: #888; margin-top: 2px; }
.cena-od-do .cena-vrednost { font-size: 20px; font-weight: 700; color: #f1f5f9; }
.cena-od-do .cena-sep { color: #475569; }
.cena-labela { font-size: 11px; color: #94a3b8; margin-top: 2px; }
.cena-vrednost { color: #f1f5f9; }
/* kontakt */
.kontakt { background: #fff; border-radius: 16px; padding: 18px 20px; box-shadow: 0 1px 4px rgba(0,0,0,0.08); }
.kontakt-naslov { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; color: #999; margin-bottom: 12px; }
.kontakt-tel { font-size: 18px; font-weight: 700; color: #1a56db; text-decoration: none; display: block; }
.kontakt-adresa { font-size: 13px; color: #666; margin-top: 6px; line-height: 1.5; }
.kontakt { background: #1e293b; border-radius: 16px; padding: 18px 20px; box-shadow: 0 1px 4px rgba(0,0,0,0.35); }
.kontakt-naslov { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; color: #94a3b8; margin-bottom: 12px; }
.kontakt-tel { font-size: 18px; font-weight: 700; color: #60a5fa; text-decoration: none; display: block; }
.kontakt-adresa { font-size: 13px; color: #94a3b8; margin-top: 6px; line-height: 1.5; }
/* napomena za klijenta */
.napomena-blok { background: #fffbeb; border-radius: 10px; padding: 12px 14px; margin-top: 4px; font-size: 13px; color: #555; line-height: 1.5; }
.napomena-blok { background: #0f172a; border-left: 3px solid #f59e0b; border-radius: 8px; padding: 12px 14px; margin-top: 4px; font-size: 13px; color: #cbd5e1; line-height: 1.5; white-space: pre-wrap; }
/* predlog popravke — istaknuta kartica koju klijent odobrava */
.predlog-kartica { border: 1px solid #f59e0b; box-shadow: 0 0 0 3px rgba(245,158,11,0.12); }
/* dugmad za odobravanje */
.dugme-prihvati {
width: 100%; padding: 12px 16px; border: none; border-radius: 10px;
font-size: 14px; font-weight: 600; cursor: pointer;
background: #10b981; color: #fff;
transition: background 0.2s;
}
.dugme-prihvati:hover { background: #059669; }
.dugme-odbij {
width: 100%; padding: 12px 16px; border: 1px solid #475569; border-radius: 10px;
font-size: 14px; font-weight: 500; cursor: pointer;
background: transparent; color: #94a3b8;
transition: background 0.2s, color 0.2s;
}
.dugme-odbij:hover { background: #334155; color: #e2e8f0; }
.predlog-bedz { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 600; background: #f59e0b; color: #1f1300; }
.predlog-ukupno .cena-labela { color: #fcd34d; }
.predlog-ukupno .cena-vrednost { color: #fcd34d; }
</style>
</head>
<body>
@@ -134,6 +158,34 @@
</div>
</div>
<!-- kartica: zahtev klijenta (opis kvara, nadogradnje, napomena) -->
{{if or .Nalog.OpisKvara (or .Nalog.TrazeneNadogradnje .Nalog.NapomenaKlijentu)}}
<div class="kartica">
<div class="kartica-naslov">Vaš zahtev</div>
{{if .Nalog.OpisKvara}}
<div style="margin-bottom:12px;">
<div class="red-labela" style="margin-bottom:6px;">Opis kvara</div>
<div class="napomena-blok">{{.Nalog.OpisKvara}}</div>
</div>
{{end}}
{{if .Nalog.TrazeneNadogradnje}}
<div style="margin-bottom:12px;">
<div class="red-labela" style="margin-bottom:6px;">Tražene nadogradnje</div>
<div class="napomena-blok">{{.Nalog.TrazeneNadogradnje}}</div>
</div>
{{end}}
{{if .Nalog.NapomenaKlijentu}}
<div>
<div class="red-labela" style="margin-bottom:6px;">Napomena klijentu</div>
<div class="napomena-blok">{{.Nalog.NapomenaKlijentu}}</div>
</div>
{{end}}
</div>
{{end}}
<!-- kartica: detalji -->
<div class="kartica">
<div class="kartica-naslov">Detalji</div>
@@ -162,12 +214,6 @@
</div>
{{end}}
{{if .Nalog.NapomenaKlijentu}}
<div style="margin-top:12px;">
<div class="red-labela" style="margin-bottom:6px;">Napomena</div>
<div class="napomena-blok">{{.Nalog.NapomenaKlijentu}}</div>
</div>
{{end}}
</div>
<!-- kartica: radovi i delovi sa procenom -->
@@ -193,6 +239,62 @@
<span class="cena-labela" style="margin:0;">Ukupno (procena)</span>
<span class="cena-vrednost">{{dinari .UkupnoSve}} din</span>
</div>
{{if .ImaPredlog}}
<div class="cena-blok" style="margin-top:8px;padding:10px 14px;display:flex;justify-content:space-between;align-items:center;background:#0f172a;border:1px solid #f59e0b;border-radius:8px;">
<span class="cena-labela" style="margin:0;color:#fbbf24;">Sa predlogom</span>
<span class="cena-vrednost" style="font-size:16px;font-weight:700;color:#fbbf24;">{{dinari .UkupnoSaPredlogom}} din</span>
</div>
{{end}}
</div>
{{end}}
<!-- kartica: predlog popravke — serviser predložio posle dijagnostike -->
{{if .ImaPredlog}}
<div class="kartica predlog-kartica">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
<span class="kartica-naslov" style="margin:0;">Predlog popravke</span>
<span class="predlog-bedz">Predlog</span>
</div>
<div style="font-size:12px;color:#94a3b8;margin-bottom:10px;line-height:1.5;">
Serviser predlaže sledeće radove i delove. Pogledajte i javite nam da li ste saglasni.
</div>
{{range .PredlozeniRadovi}}
<div class="red">
<span class="red-labela">{{.Naziv}}{{if gt .Kolicina 1.0}} &times;{{.Kolicina}}{{end}}</span>
<span class="red-vrednost">{{dinari .Ukupno}} din</span>
</div>
{{end}}
{{range .PredlozeniDelovi}}
<div class="red">
<span class="red-labela">{{.ArtikalNaziv}}{{if gt .Kolicina 1}} &times;{{.Kolicina}}{{end}}</span>
<span class="red-vrednost">{{dinari .Ukupno}} din</span>
</div>
{{end}}
<div class="cena-blok predlog-ukupno" style="margin-top:12px;display:flex;justify-content:space-between;align-items:center;">
<span class="cena-labela" style="margin:0;">Predlog ukupno</span>
<span class="cena-vrednost">{{dinari .UkupnoPredlog}} din</span>
</div>
<!-- komentar i dugmad -->
<form method="POST" style="margin-top:16px;">
<textarea name="komentar" placeholder="Poruka serviseru (opciono)..." rows="2"
style="width:100%;padding:10px 12px;border:0.5px solid #334155;border-radius:8px;background:#0f172a;color:#e2e8f0;font-size:13px;font-family:inherit;resize:vertical;margin-bottom:10px;box-sizing:border-box;"></textarea>
<div style="display:flex;gap:10px;">
<button type="submit" formaction="/status/{{.Nalog.JavniToken}}/prihvati" class="dugme-prihvati" style="flex:1;">Prihvatam predlog</button>
<button type="submit" formaction="/status/{{.Nalog.JavniToken}}/odbij" class="dugme-odbij" style="flex:1;">Ne prihvatam</button>
</div>
</form>
</div>
{{end}}
{{if .Odgovoreno}}
<div class="kartica" style="border-color:#10b981;text-align:center;">
<div style="font-size:16px;font-weight:600;color:#10b981;">Hvala na odgovoru!</div>
<div style="font-size:12px;color:#94a3b8;margin-top:6px;">Serviser je obavešten o vašoj odluci.</div>
</div>
{{end}}