feat: zodpovedna osoba za projekt - novy sloupec + editace
Pridano pole responsible_user_id do tabulky projects s FK na users. Select zodpovedne osoby v ProjectDetail, ProjectCreate a sloupec v seznamu projektu. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
53
dist/api/admin/handlers/projects-handlers.php
vendored
53
dist/api/admin/handlers/projects-handlers.php
vendored
@@ -7,6 +7,16 @@ function generateProjectNumber(PDO $pdo): string
|
||||
return generateSharedNumber($pdo);
|
||||
}
|
||||
|
||||
function handleGetUsers(PDO $pdo): void
|
||||
{
|
||||
$stmt = $pdo->query(
|
||||
"SELECT id, CONCAT(first_name, ' ', last_name) as name
|
||||
FROM users WHERE is_active = 1 ORDER BY first_name, last_name"
|
||||
);
|
||||
$users = $stmt->fetchAll();
|
||||
successResponse(['users' => $users]);
|
||||
}
|
||||
|
||||
function handleGetNextNumber(PDO $pdo): void
|
||||
{
|
||||
$number = generateProjectNumber($pdo);
|
||||
@@ -37,6 +47,15 @@ function handleCreateProject(PDO $pdo): void
|
||||
errorResponse('Zákazník nebyl nalezen', 404);
|
||||
}
|
||||
|
||||
$responsibleUserId = isset($input['responsible_user_id']) ? (int)$input['responsible_user_id'] : null;
|
||||
if ($responsibleUserId) {
|
||||
$stmt = $pdo->prepare('SELECT id FROM users WHERE id = ?');
|
||||
$stmt->execute([$responsibleUserId]);
|
||||
if (!$stmt->fetch()) {
|
||||
errorResponse('Zodpovědná osoba nebyla nalezena', 404);
|
||||
}
|
||||
}
|
||||
|
||||
$startDate = $input['start_date'] ?? date('Y-m-d');
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $startDate)) {
|
||||
errorResponse('Neplatný formát data zahájení');
|
||||
@@ -79,14 +98,15 @@ function handleCreateProject(PDO $pdo): void
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO projects (
|
||||
project_number, name, customer_id,
|
||||
project_number, name, customer_id, responsible_user_id,
|
||||
status, start_date, created_at, modified_at
|
||||
) VALUES (?, ?, ?, 'aktivni', ?, NOW(), NOW())
|
||||
) VALUES (?, ?, ?, ?, 'aktivni', ?, NOW(), NOW())
|
||||
");
|
||||
$stmt->execute([
|
||||
$projectNumber,
|
||||
$name,
|
||||
$customerId,
|
||||
$responsibleUserId,
|
||||
$startDate,
|
||||
]);
|
||||
$projectId = (int)$pdo->lastInsertId();
|
||||
@@ -185,15 +205,17 @@ function handleGetList(PDO $pdo): void
|
||||
|
||||
$from = "FROM projects p
|
||||
LEFT JOIN customers c ON p.customer_id = c.id
|
||||
LEFT JOIN orders o ON p.order_id = o.id";
|
||||
LEFT JOIN orders o ON p.order_id = o.id
|
||||
LEFT JOIN users u ON p.responsible_user_id = u.id";
|
||||
|
||||
$result = PaginationHelper::paginate(
|
||||
$pdo,
|
||||
"SELECT COUNT(*) {$from} {$where}",
|
||||
"SELECT p.id, p.project_number, p.name, p.status, p.start_date, p.end_date,
|
||||
p.order_id, p.quotation_id, p.created_at,
|
||||
p.order_id, p.quotation_id, p.created_at, p.responsible_user_id,
|
||||
c.name as customer_name,
|
||||
o.order_number
|
||||
o.order_number,
|
||||
CONCAT(u.first_name, ' ', u.last_name) as responsible_user_name
|
||||
{$from} {$where}
|
||||
ORDER BY {$p['sort']} {$p['order']}",
|
||||
$params,
|
||||
@@ -212,14 +234,17 @@ function handleGetDetail(PDO $pdo, int $id): void
|
||||
SELECT p.id, p.project_number, p.name, p.customer_id,
|
||||
p.quotation_id, p.order_id, p.status,
|
||||
p.start_date, p.end_date, p.notes,
|
||||
p.responsible_user_id,
|
||||
p.created_at, p.modified_at,
|
||||
c.name as customer_name,
|
||||
o.order_number, o.status as order_status,
|
||||
q.quotation_number
|
||||
q.quotation_number,
|
||||
CONCAT(u.first_name, \' \', u.last_name) as responsible_user_name
|
||||
FROM projects p
|
||||
LEFT JOIN customers c ON p.customer_id = c.id
|
||||
LEFT JOIN orders o ON p.order_id = o.id
|
||||
LEFT JOIN quotations q ON p.quotation_id = q.id
|
||||
LEFT JOIN users u ON p.responsible_user_id = u.id
|
||||
WHERE p.id = ?
|
||||
');
|
||||
$stmt->execute([$id]);
|
||||
@@ -235,7 +260,7 @@ function handleGetDetail(PDO $pdo, int $id): void
|
||||
function handleUpdateProject(PDO $pdo, int $id): void
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT id, project_number, name, status, start_date, end_date, notes
|
||||
'SELECT id, project_number, name, status, start_date, end_date, notes, responsible_user_id
|
||||
FROM projects WHERE id = ?'
|
||||
);
|
||||
$stmt->execute([$id]);
|
||||
@@ -282,6 +307,18 @@ function handleUpdateProject(PDO $pdo, int $id): void
|
||||
errorResponse('Poznámky jsou příliš dlouhé (max 5000 znaků)');
|
||||
}
|
||||
|
||||
// Zodpovedna osoba
|
||||
$responsibleUserId = array_key_exists('responsible_user_id', $input)
|
||||
? ($input['responsible_user_id'] ? (int)$input['responsible_user_id'] : null)
|
||||
: $project['responsible_user_id'];
|
||||
if ($responsibleUserId) {
|
||||
$stmt = $pdo->prepare('SELECT id FROM users WHERE id = ?');
|
||||
$stmt->execute([$responsibleUserId]);
|
||||
if (!$stmt->fetch()) {
|
||||
errorResponse('Zodpovědná osoba nebyla nalezena', 404);
|
||||
}
|
||||
}
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
$stmt = $pdo->prepare('
|
||||
@@ -291,6 +328,7 @@ function handleUpdateProject(PDO $pdo, int $id): void
|
||||
start_date = ?,
|
||||
end_date = ?,
|
||||
notes = ?,
|
||||
responsible_user_id = ?,
|
||||
modified_at = NOW()
|
||||
WHERE id = ?
|
||||
');
|
||||
@@ -300,6 +338,7 @@ function handleUpdateProject(PDO $pdo, int $id): void
|
||||
$input['start_date'] ?? $project['start_date'],
|
||||
$input['end_date'] ?? $project['end_date'],
|
||||
$notes,
|
||||
$responsibleUserId,
|
||||
$id,
|
||||
]);
|
||||
|
||||
|
||||
3
dist/api/admin/projects.php
vendored
3
dist/api/admin/projects.php
vendored
@@ -56,6 +56,9 @@ try {
|
||||
requirePermission($authData, 'projects.create');
|
||||
handleGetNextNumber($pdo);
|
||||
break;
|
||||
case 'users':
|
||||
handleGetUsers($pdo);
|
||||
break;
|
||||
default:
|
||||
handleGetList($pdo);
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"window_start":1773397693,"count":7}
|
||||
{"window_start":1773397817,"count":1}
|
||||
@@ -1 +1 @@
|
||||
{"window_start":1773396919,"count":1}
|
||||
{"window_start":1773399442,"count":1}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{j as e,m as f}from"./vendor-animation-0s3FMHwK.js";import{r as m}from"./vendor-react-BVs3cwbi.js";import{a9 as T}from"./vendor-utils-Dyr8OjFr.js";import{a as C,u as A,c as O,F as B,A as H}from"./index-CnEy_BDh.js";import{F as I}from"./Forbidden-D25jV3Oq.js";import{c as W,b as k,g as w,d as z,e as S,a as v,h as E,i as y,f as b}from"./attendanceHelpers-D6sLEw0q.js";const L="/api/admin",R=s=>s.break_start&&s.break_end?`${b(s.break_start)} - ${b(s.break_end)}`:s.break_start?`${b(s.break_start)} - ?`:"—",Z=s=>s.project_logs&&s.project_logs.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.125rem"},children:s.project_logs.map((n,g)=>{let d,c,o=!1;if(n.hours!==null&&n.hours!==void 0)d=parseInt(n.hours)||0,c=parseInt(n.minutes)||0;else{o=!n.ended_at;const x=n.ended_at?new Date(n.ended_at):new Date,p=Math.floor((x-new Date(n.started_at))/6e4);d=Math.floor(p/60),c=p%60}return e.jsxs("span",{className:"admin-badge",style:{fontSize:"0.7rem",display:"inline-block",background:o?"var(--accent-light)":void 0},children:[n.project_name||`#${n.project_id}`," (",d,":",String(c).padStart(2,"0"),"h",o?" ▸":"",")"]},n.id||g)})}):s.project_name?e.jsx("span",{className:"admin-badge admin-badge-wrap",style:{fontSize:"0.75rem"},children:s.project_name}):"—",Y=s=>s.overtime>0?e.jsxs("span",{className:"leave-badge badge-overtime",children:["+",s.overtime,"h přesčas"]}):s.remaining>0?e.jsxs("span",{style:{color:"#dc2626"},children:["−",s.remaining,"h"]}):e.jsx("span",{style:{color:"#16a34a"},children:"splněno"});function Q(){const s=C(),{user:n,hasPermission:g}=A(),[d,c]=m.useState(!0),o=m.useRef(null),[x,p]=m.useState(()=>{const a=new Date;return`${a.getFullYear()}-${String(a.getMonth()+1).padStart(2,"0")}`}),[t,D]=m.useState({records:[],month_name:"",year:new Date().getFullYear(),total_minutes:0,vacation_hours:0,sick_hours:0,holiday_hours:0,unpaid_hours:0,leave_balance:null,monthly_fund:null}),_=m.useCallback(async()=>{c(!0);try{const a=await O(`${L}/attendance.php?action=history&month=${x}`);if(a.status===401)return;const i=await a.json();i.success&&D(i.data)}catch{s.error("Nepodařilo se načíst data")}finally{c(!1)}},[x,s]);if(m.useEffect(()=>{_()},[_]),!g("attendance.history"))return e.jsx(I,{});const $=()=>{if(!o.current)return;const a=window.open("","_blank");a.document.write(`
|
||||
import{j as e,m as f}from"./vendor-animation-0s3FMHwK.js";import{r as m}from"./vendor-react-BVs3cwbi.js";import{a9 as T}from"./vendor-utils-Dyr8OjFr.js";import{a as C,u as A,c as O,F as B,A as H}from"./index-CNxd7jIT.js";import{F as I}from"./Forbidden-D25jV3Oq.js";import{c as W,b as k,g as w,d as z,e as S,a as v,h as E,i as y,f as b}from"./attendanceHelpers-D6sLEw0q.js";const L="/api/admin",R=s=>s.break_start&&s.break_end?`${b(s.break_start)} - ${b(s.break_end)}`:s.break_start?`${b(s.break_start)} - ?`:"—",Z=s=>s.project_logs&&s.project_logs.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.125rem"},children:s.project_logs.map((n,g)=>{let d,c,o=!1;if(n.hours!==null&&n.hours!==void 0)d=parseInt(n.hours)||0,c=parseInt(n.minutes)||0;else{o=!n.ended_at;const x=n.ended_at?new Date(n.ended_at):new Date,p=Math.floor((x-new Date(n.started_at))/6e4);d=Math.floor(p/60),c=p%60}return e.jsxs("span",{className:"admin-badge",style:{fontSize:"0.7rem",display:"inline-block",background:o?"var(--accent-light)":void 0},children:[n.project_name||`#${n.project_id}`," (",d,":",String(c).padStart(2,"0"),"h",o?" ▸":"",")"]},n.id||g)})}):s.project_name?e.jsx("span",{className:"admin-badge admin-badge-wrap",style:{fontSize:"0.75rem"},children:s.project_name}):"—",Y=s=>s.overtime>0?e.jsxs("span",{className:"leave-badge badge-overtime",children:["+",s.overtime,"h přesčas"]}):s.remaining>0?e.jsxs("span",{style:{color:"#dc2626"},children:["−",s.remaining,"h"]}):e.jsx("span",{style:{color:"#16a34a"},children:"splněno"});function Q(){const s=C(),{user:n,hasPermission:g}=A(),[d,c]=m.useState(!0),o=m.useRef(null),[x,p]=m.useState(()=>{const a=new Date;return`${a.getFullYear()}-${String(a.getMonth()+1).padStart(2,"0")}`}),[t,D]=m.useState({records:[],month_name:"",year:new Date().getFullYear(),total_minutes:0,vacation_hours:0,sick_hours:0,holiday_hours:0,unpaid_hours:0,leave_balance:null,monthly_fund:null}),_=m.useCallback(async()=>{c(!0);try{const a=await O(`${L}/attendance.php?action=history&month=${x}`);if(a.status===401)return;const i=await a.json();i.success&&D(i.data)}catch{s.error("Nepodařilo se načíst data")}finally{c(!1)}},[x,s]);if(m.useEffect(()=>{_()},[_]),!g("attendance.history"))return e.jsx(I,{});const $=()=>{if(!o.current)return;const a=window.open("","_blank");a.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
dist/assets/ProjectCreate-FGcLP7J1.js
vendored
Normal file
1
dist/assets/ProjectCreate-FGcLP7J1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/assets/ProjectCreate-k3l1K_1G.js
vendored
1
dist/assets/ProjectCreate-k3l1K_1G.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/ProjectDetail-CDPrOXSn.js
vendored
1
dist/assets/ProjectDetail-CDPrOXSn.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/ProjectDetail-Dg0G_KTk.js
vendored
Normal file
1
dist/assets/ProjectDetail-Dg0G_KTk.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{j as e,m as p,A as Z}from"./vendor-animation-0s3FMHwK.js";import{r as i,L as J}from"./vendor-react-BVs3cwbi.js";import{a9 as G}from"./vendor-utils-Dyr8OjFr.js";import{a as q,u as Q,c as b,b as X,F as r,A as C,f as l,C as ee}from"./index-CnEy_BDh.js";import{F as se}from"./Forbidden-D25jV3Oq.js";import{b as $}from"./attendanceHelpers-D6sLEw0q.js";const N="/api/admin";function de(){const d=q(),{hasPermission:L}=Q(),[k,D]=i.useState(!0),[j,V]=i.useState(()=>{const s=new Date;return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-01`}),[g,A]=i.useState(()=>{const s=new Date,t=new Date(s.getFullYear(),s.getMonth()+1,0).getDate();return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(t).padStart(2,"0")}`}),[m,F]=i.useState(""),[h,E]=i.useState(""),[P,B]=i.useState({trips:[],vehicles:[],users:[],totals:{total:0,business:0,count:0}}),[n,I]=i.useState(null),w=i.useRef(null),[T,v]=i.useState(!1),[_,U]=i.useState(null),[a,o]=i.useState({vehicle_id:"",trip_date:"",start_km:"",end_km:"",route_from:"",route_to:"",is_business:1,notes:""}),[u,z]=i.useState({show:!1,trip:null}),y=i.useCallback(async(s=!0)=>{s&&D(!0);try{let t=`${N}/trips.php?action=admin&date_from=${j}&date_to=${g}`;m&&(t+=`&vehicle_id=${m}`),h&&(t+=`&user_id=${h}`);const c=await(await b(t)).json();c.success&&B(c.data)}catch{d.error("Nepodařilo se načíst data")}finally{s&&D(!1)}},[j,g,m,h,d]);if(i.useEffect(()=>{y()},[y]),X(T),!L("trips.admin"))return e.jsx(se,{});const H=s=>{U(s),o({vehicle_id:s.vehicle_id,trip_date:s.trip_date,start_km:s.start_km,end_km:s.end_km,route_from:s.route_from,route_to:s.route_to,is_business:s.is_business,notes:s.notes||""}),v(!0)},O=async()=>{if(parseInt(a.end_km)<=parseInt(a.start_km)){d.error("Konečný stav km musí být větší než počáteční");return}try{const t=await(await b(`${N}/trips.php?id=${_.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).json();t.success?(v(!1),await y(!1),await new Promise(x=>setTimeout(x,300)),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},W=async()=>{if(u.trip)try{const t=await(await b(`${N}/trips.php?id=${u.trip.id}`,{method:"DELETE"})).json();t.success?(z({show:!1,trip:null}),await y(!1),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},K=async()=>{try{let s=`${N}/trips.php?action=print&date_from=${j}&date_to=${g}`;m&&(s+=`&vehicle_id=${m}`),h&&(s+=`&user_id=${h}`);const x=await(await b(s)).json();x.success&&(I(x.data),setTimeout(()=>{if(w.current){const c=window.open("","_blank");c.document.write(`
|
||||
import{j as e,m as p,A as Z}from"./vendor-animation-0s3FMHwK.js";import{r as i,L as J}from"./vendor-react-BVs3cwbi.js";import{a9 as G}from"./vendor-utils-Dyr8OjFr.js";import{a as q,u as Q,c as b,b as X,F as r,A as C,f as l,C as ee}from"./index-CNxd7jIT.js";import{F as se}from"./Forbidden-D25jV3Oq.js";import{b as $}from"./attendanceHelpers-D6sLEw0q.js";const N="/api/admin";function de(){const d=q(),{hasPermission:L}=Q(),[k,D]=i.useState(!0),[j,V]=i.useState(()=>{const s=new Date;return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-01`}),[g,A]=i.useState(()=>{const s=new Date,t=new Date(s.getFullYear(),s.getMonth()+1,0).getDate();return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(t).padStart(2,"0")}`}),[m,F]=i.useState(""),[h,E]=i.useState(""),[P,B]=i.useState({trips:[],vehicles:[],users:[],totals:{total:0,business:0,count:0}}),[n,I]=i.useState(null),w=i.useRef(null),[T,v]=i.useState(!1),[_,U]=i.useState(null),[a,o]=i.useState({vehicle_id:"",trip_date:"",start_km:"",end_km:"",route_from:"",route_to:"",is_business:1,notes:""}),[u,z]=i.useState({show:!1,trip:null}),y=i.useCallback(async(s=!0)=>{s&&D(!0);try{let t=`${N}/trips.php?action=admin&date_from=${j}&date_to=${g}`;m&&(t+=`&vehicle_id=${m}`),h&&(t+=`&user_id=${h}`);const c=await(await b(t)).json();c.success&&B(c.data)}catch{d.error("Nepodařilo se načíst data")}finally{s&&D(!1)}},[j,g,m,h,d]);if(i.useEffect(()=>{y()},[y]),X(T),!L("trips.admin"))return e.jsx(se,{});const H=s=>{U(s),o({vehicle_id:s.vehicle_id,trip_date:s.trip_date,start_km:s.start_km,end_km:s.end_km,route_from:s.route_from,route_to:s.route_to,is_business:s.is_business,notes:s.notes||""}),v(!0)},O=async()=>{if(parseInt(a.end_km)<=parseInt(a.start_km)){d.error("Konečný stav km musí být větší než počáteční");return}try{const t=await(await b(`${N}/trips.php?id=${_.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).json();t.success?(v(!1),await y(!1),await new Promise(x=>setTimeout(x,300)),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},W=async()=>{if(u.trip)try{const t=await(await b(`${N}/trips.php?id=${u.trip.id}`,{method:"DELETE"})).json();t.success?(z({show:!1,trip:null}),await y(!1),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},K=async()=>{try{let s=`${N}/trips.php?action=print&date_from=${j}&date_to=${g}`;m&&(s+=`&vehicle_id=${m}`),h&&(s+=`&user_id=${h}`);const x=await(await b(s)).json();x.success&&(I(x.data),setTimeout(()=>{if(w.current){const c=window.open("","_blank");c.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{j as x}from"./vendor-animation-0s3FMHwK.js";import{r as t}from"./vendor-react-BVs3cwbi.js";import{a as L,c as O}from"./index-CnEy_BDh.js";function J({column:e,sort:r,order:n}){return r!==e?null:x.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",style:{marginLeft:4,verticalAlign:"middle"},children:x.jsx("path",{d:n==="ASC"?"M18 15l-6-6-6 6":"M6 9l6 6 6-6"})})}function V(e,r="DESC"){const[n,a]=t.useState(e),[o,c]=t.useState(r),i=t.useRef(!1),S=t.useCallback(u=>{i.current=!0,a(m=>m===u?(c(h=>h==="ASC"?"DESC":"ASC"),m):(c("DESC"),u))},[]),d=i.current?n:null;return{sort:n,order:o,handleSort:S,activeSort:d}}function I(e,r=300){const[n,a]=t.useState(e);return t.useEffect(()=>{const o=setTimeout(()=>a(e),r);return()=>clearTimeout(o)},[e,r]),n}const N="/api/admin";function _(e,{dataKey:r,search:n,sort:a,order:o,page:c,perPage:i,extraParams:S,errorMsg:d="Nepodařilo se načíst data"}={}){const u=L(),[m,h]=t.useState([]),[j,D]=t.useState(!0),[w,k]=t.useState(null),l=t.useRef(null),p=S?JSON.stringify(S):"",b=I(n,300),C=t.useCallback(async()=>{l.current&&l.current.abort();const g=new AbortController;l.current=g;try{const s=new URLSearchParams;if(b&&s.set("search",b),a&&s.set("sort",a),o&&s.set("order",o),c&&s.set("page",c),i&&s.set("per_page",i),p){const R=JSON.parse(p);Object.entries(R).forEach(([y,A])=>{A&&s.set(y,A)})}const E=await O(`${N}/${e}?${s}`,{signal:g.signal});if(E.status===401)return;const f=await E.json();f.success?(h(f.data[r]||[]),f.data.pagination&&k(f.data.pagination)):u.error(f.error||d)}catch(s){if(s.name==="AbortError")return;u.error("Chyba připojení")}finally{D(!1)}},[u,e,r,b,a,o,c,i,p,d]);return t.useEffect(()=>(C(),()=>{l.current&&l.current.abort()}),[C]),{items:m,setItems:h,loading:j,pagination:w,refetch:C}}export{J as S,_ as a,V as u};
|
||||
import{j as x}from"./vendor-animation-0s3FMHwK.js";import{r as t}from"./vendor-react-BVs3cwbi.js";import{a as L,c as O}from"./index-CNxd7jIT.js";function J({column:e,sort:r,order:n}){return r!==e?null:x.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",style:{marginLeft:4,verticalAlign:"middle"},children:x.jsx("path",{d:n==="ASC"?"M18 15l-6-6-6 6":"M6 9l6 6 6-6"})})}function V(e,r="DESC"){const[n,a]=t.useState(e),[o,c]=t.useState(r),i=t.useRef(!1),S=t.useCallback(u=>{i.current=!0,a(m=>m===u?(c(h=>h==="ASC"?"DESC":"ASC"),m):(c("DESC"),u))},[]),d=i.current?n:null;return{sort:n,order:o,handleSort:S,activeSort:d}}function I(e,r=300){const[n,a]=t.useState(e);return t.useEffect(()=>{const o=setTimeout(()=>a(e),r);return()=>clearTimeout(o)},[e,r]),n}const N="/api/admin";function _(e,{dataKey:r,search:n,sort:a,order:o,page:c,perPage:i,extraParams:S,errorMsg:d="Nepodařilo se načíst data"}={}){const u=L(),[m,h]=t.useState([]),[j,D]=t.useState(!0),[w,k]=t.useState(null),l=t.useRef(null),p=S?JSON.stringify(S):"",b=I(n,300),C=t.useCallback(async()=>{l.current&&l.current.abort();const g=new AbortController;l.current=g;try{const s=new URLSearchParams;if(b&&s.set("search",b),a&&s.set("sort",a),o&&s.set("order",o),c&&s.set("page",c),i&&s.set("per_page",i),p){const R=JSON.parse(p);Object.entries(R).forEach(([y,A])=>{A&&s.set(y,A)})}const E=await O(`${N}/${e}?${s}`,{signal:g.signal});if(E.status===401)return;const f=await E.json();f.success?(h(f.data[r]||[]),f.data.pagination&&k(f.data.pagination)):u.error(f.error||d)}catch(s){if(s.name==="AbortError")return;u.error("Chyba připojení")}finally{D(!1)}},[u,e,r,b,a,o,c,i,p,d]);return t.useEffect(()=>(C(),()=>{l.current&&l.current.abort()}),[C]),{items:m,setItems:h,loading:j,pagination:w,refetch:C}}export{J as S,_ as a,V as u};
|
||||
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -29,7 +29,7 @@
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Plus+Jakarta+Sans:wght@400;500;600;700&family=Urbanist:wght@400;500;600;700;800&display=swap"
|
||||
rel="stylesheet" />
|
||||
<script type="module" crossorigin src="/assets/index-CnEy_BDh.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-CNxd7jIT.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BVs3cwbi.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-animation-0s3FMHwK.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-utils-Dyr8OjFr.js">
|
||||
|
||||
4
dist/vendor/composer/installed.php
vendored
4
dist/vendor/composer/installed.php
vendored
@@ -3,7 +3,7 @@
|
||||
'name' => 'boha/website',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '10fbb9ebc7c5fecb2f704317c3024d5be8fc2d91',
|
||||
'reference' => '308941449e1b5f1ec6752c297d286e6633c11fed',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -13,7 +13,7 @@
|
||||
'boha/website' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '10fbb9ebc7c5fecb2f704317c3024d5be8fc2d91',
|
||||
'reference' => '308941449e1b5f1ec6752c297d286e6633c11fed',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
Reference in New Issue
Block a user