1import{c as q,r as o,j as e,X as P,S as k,Z as R}from"./index-BbKKAkbW.js";import{q as w,o as T,c as b,d as p,a as H,g as S,w as z,b as E,e as B,u as M,s as y}from"./sharesureE2eRuntime-Dz_8VYhc.js";import{u as D}from"./ShareSureContext-BLSUBbtd.js";import{A as U}from"./alert-circle-D2ora1Ll.js";import{C as A}from"./calendar-B9DyPZPu.js";import{C as L}from"./clock-BIE1ytJQ.js";import{F as $}from"./file-text-CeGfA1jE.js";/* empty css */import{P as G}from"./plus-MotWeq--.js";import{A as I}from"./activity-BKTbg0bl.js";import{C as O}from"./check-circle-2-BSQTN7aA.js";import{A as Z}from"./alert-triangle-61aWnxUj.js";import{F as Q}from"./filter-s_oomI2J.js";import{T as W}from"./thermometer-BiXJYulL.js";import"./config-B9c8M7-X.js";/** 2 * @license lucide-react v0.344.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const X=q("History",[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]]);class J{constructor(){this.collectionName="facilities",this.bookingsCollection="bookings"}subscribeToFacilities(a){const r=w(b(p,this.collectionName),T("name","asc"));return H(r,t=>{const i=t.docs.map(c=>({id:c.id,...c.data()}));a(i)})}async getFacilities(){const a=w(b(p,this.collectionName),T("name","asc"));return(await S(a)).docs.map(t=>({id:t.id,...t.data()}))}async bookEquipment(a,r,t,i,c){const j=w(b(p,this.bookingsCollection),z("equipmentId","==",a),z("status","==","confirmed")),m=(await S(j)).docs.map(d=>d.data()),g=new Date(t).getTime(),l=new Date(i).getTime();if(m.some(d=>{const v=d.startTime.toMillis(),n=d.endTime.toMillis();return g<n&&l>v}))throw new Error("This equipment is already booked for the selected time slot.");await E(b(p,this.bookingsCollection),{equipmentId:a,userId:r,startTime:new Date(t),endTime:new Date(i),purpose:c,status:"confirmed",createdAt:y()});const u=Date.now();if(g<=u&&l>=u){const d=B(p,this.collectionName,a);await M(d,{status:"busy",currentBookingId:a})}}async updateHealth(a,r,t){const i=B(p,this.collectionName,a);await M(i,{health:r,lastMaintenance:y(),maintenanceLog:t,updatedAt:y()})}async seedFacilities(){const a=[{name:"Plasma Reactor Alpha",category:"Reactor Systems",status:"available",health:100,lastMaintenance:new Date},{name:"GC-MS Analyzer",category:"Characterization Tools",status:"available",health:95,lastMaintenance:new Date},{name:"Micro-GC Station 1",category:"Characterization Tools",status:"available",health:98,lastMaintenance:new Date},{name:"Fixed-Bed Reactor 01",category:"Reactor Systems",status:"busy",health:85,lastMaintenance:new Date},{name:"High-Temp Furnace",category:"Material Synthesis",status:"available",health:100,lastMaintenance:new Date},{name:"ICP-OES Spectrometer",category:"Characterization Tools",status:"maintenance",health:60,lastMaintenance:new Date}];if((await S(b(p,this.collectionName))).empty){for(const t of a)await E(b(p,this.collectionName),{...t,createdAt:y()});console.log("Facilities seeded successfully")}}}const C=new J,K=({equipment:x,onClose:a,onSuccess:r})=>{const{currentUser:t}=D(),[i,c]=o.useState(!1),[j,h]=o.useState(null),[m,g]=o.useState(""),[l,f]=o.useState(""),[u,d]=o.useState(""),v=async n=>{if(n.preventDefault(),!m||!l||!u){h("Please fill in all fields.");return}const s=new Date(m),N=new Date(l);if(s>=N){h("End time must be after start time.");return}if(s<new Date){h("Cannot book in the past.");return}c(!0),h(null);try{await C.bookEquipment(x.id,t.uid,m,l,u),r()}catch(F){console.error("Booking failed:",F),h(F.message||"Failed to complete booking. Please try again.")}finally{c(!1)}};return e.jsx("div",{className:"modal-overlay",onClick:a,children:e.jsxs("div",{className:"modal-content",onClick:n=>n.stopPropagation(),style:{maxWidth:"500px"},children:[e.jsxs("div",{className:"modal-header",children:[e.jsxs("h3",{children:["Book ",x.name]}),e.jsx("button",{onClick:a,className:"close-btn",children:e.jsx(P,{size:24})})]}),e.jsxs("form",{onSubmit:v,className:"modal-body",children:[j&&e.jsxs("div",{className:"error-banner",children:[e.jsx(U,{size:18}),e.jsx("span",{children:j})]}),e.jsxs("div",{className:"form-section",children:[e.jsx("p",{className:"eq-category",children:x.category}),e.jsxs("div",{className:"current-status",children:[e.jsx("span",{className:"dot",style:{backgroundColor:x.status==="available"?"#10B981":"#F59E0B"}}),"Current Status: ",x.status.toUpperCase()]})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{children:[e.jsx(A,{size:16})," Start Time"]}),e.jsx("input",{type:"datetime-local",value:m,onChange:n=>g(n.target.value),required:!0,disabled:i})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{children:[e.jsx(L,{size:16})," End Time"]}
6),e.jsx("input",{type:"datetime-local",value:l,onChange:n=>f(n.target.value),required:!0,disabled:i})]}),e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{children:[e.jsx($,{size:16})," Purpose of Use"]}),e.jsx("textarea",{value:u,onChange:n=>d(n.target.value),placeholder:"Briefly describe your experiment...",rows:"3",required:!0,disabled:i})]}),e.jsxs("div",{className:"modal-footer",children:[e.jsx("button",{type:"button",onClick:a,className:"secondary-btn",disabled:i,children:"Cancel"}),e.jsx("button",{type:"submit",className:"primary-btn",disabled:i,children:i?"Confirming...":"Confirm Booking"})]})]})]})})},me=()=>{const{currentUser:x}=D(),[a,r]=o.useState([]),[t,i]=o.useState(!0),[c,j]=o.useState("All"),[h,m]=o.useState(null),[g,l]=o.useState(!1);o.useEffect(()=>{C.seedFacilities();const s=C.subscribeToFacilities(N=>{r(N),i(!1)});return()=>s()},[]);const f=["All",...new Set(a.map(s=>s.category))],u=c==="All"?a:a.filter(s=>s.category===c),d=s=>{switch(s){case"available":return"#10B981";case"busy":return"#EF4444";case"maintenance":return"#F59E0B";default:return"#6B7280"}},v=s=>s>80?"#10B981":s>50?"#F59E0B":"#EF4444",n=s=>{m(s),l(!0)};return t?e.jsxs("div",{className:"facilities-loading",children:[e.jsx("div",{className:"spinner"}),e.jsx("p",{children:"Syncing facility status..."})]}):e.jsxs("div",{className:"research-directory-page facilities-dashboard",children:[e.jsxs("section",{className:"research-workspace-hero",children:[e.jsxs("div",{className:"research-workspace-hero-main",children:[e.jsx("div",{className:"research-workspace-avatar",children:e.jsx(k,{size:28})}),e.jsxs("div",{className:"research-workspace-copy",children:[e.jsx("span",{className:"research-workspace-eyebrow",children:"Facilities"}),e.jsx("h1",{children:"Facilities and Equipment Operations"}),e.jsx("p",{children:"Equipment booking and health monitoring now sit as an operations surface inside the research console rather than as a disconnected utility page."})]})]}),e.jsxs("div",{className:"research-workspace-actions",children:[e.jsxs("button",{className:"research-workspace-button",children:[e.jsx(X,{size:16})," My Bookings"]}),e.jsxs("button",{className:"research-workspace-button primary",children:[e.jsx(G,{size:16})," Add Equipment"]})]})]}),e.jsxs("section",{className:"research-directory-kpis dashboard-stats",children:[e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-icon pulse blue",children:e.jsx(I,{size:24})}),e.jsxs("div",{className:"stat-info",children:[e.jsx("span",{className:"label",children:"Active Systems"}),e.jsx("span",{className:"value",children:a.filter(s=>s.status==="busy").length})]})]}),e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-icon green",children:e.jsx(O,{size:24})}),e.jsxs("div",{className:"stat-info",children:[e.jsx("span",{className:"label",children:"Ready to Use"}),e.jsx("span",{className:"value",children:a.filter(s=>s.status==="available").length})]})]}),e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-icon orange",children:e.jsx(k,{size:24})}),e.jsxs("div",{className:"stat-info",children:[e.jsx("span",{className:"label",children:"In Maintenance"}),e.jsx("span",{className:"value",children:a.filter(s=>s.status==="maintenance").length})]})]}),e.jsxs("div",{className:"stat-card",children:[e.jsx("div",{className:"stat-icon orange",children:e.jsx(Z,{size:24})}),e.jsxs("div",{className:"stat-info",children:[e.jsx("span",{className:"label",children:"Average Health"}),e.jsx("span",{className:"value",children:a.length>0?`${Math.round(a.reduce((s,N)=>s+Number(N.health||0),0)/a.length)}%`:"0%"})]})]})]}),e.jsxs("section",{className:"research-workspace-panel full",children:[e.jsx("div",{className:"research-workspace-panel-header",children:e.jsxs("div",{children:[e.jsx("h3",{children:"Facility Fleet"}),e.jsx("p",{children:"Live status, category filtering, and booking actions for shared group assets."})]})}),e.jsx("div",{className:"filter-bar",children:e.jsxs("div",{className:"filter-group",children:[e.jsx(Q,{size:18}),f.map(s=>e.jsx("button",{className:`filter-chip ${c===s?"active":""}`,onClick:()=>j(s),children:s},s))]})}),e.jsx("div",{className:"facilities-grid",children:u.map(s=>e.jsxs("div",{className:`facility-card status-${s.status}`,children:[e.jsxs("div",{className:"card-top",children:[e.jsx("div",{className:"eq-icon-wrapper",children:s.category==="Reactor Systems"?e.jsx(R,{size:24}):s.category==="Characterization Tools"?e.jsx(W,{size:24}):e.jsx(k,{size:24})}),e.jsx("div",{className:"status-badge",style:{backgroundColor:d(s.status)},children:s.status.toUpperCase()})]}),e.jsxs("div",{className:"card-content",children:[e.jsx("h3",{children:s.name}),e.jsx("p",{className:"category",children:s.category}),e.jsxs("div",{className:"health-bar-container",children:[e.jsxs("div",{className:"health-label",children:[e.jsx("span",{children:"System Health"}),e.jsxs("span",{children:[s.health,"%"]})]}),e.jsx("div",{className:"health-bar",children:e.jsx("div",{className:"health-fill",style:{width:`${s.health}%`,backgroundColor:v(s.health)}})})]})]}),e.jsx("div",{className:"card-footer",children:e.jsxs("button",{className:"action-btn book",onClick:()=>n(s),disabled:s.status==="maintenance",children:[e.jsx(A,{size:16})," Book Now"]})})]},s.id))})]}),g&&h&&e.jsx(K,{equipment:h,onClose:()=>l(!1),onSuccess:()=>{l(!1)}})]})};export{me as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.