1import{a as c,j as e}from"./query-Ban24u4e.js";import{c as ee,u as re,H as te,m as G,F as j,X as R,a as C,P as q,B as N,L as T,S as ae}from"./index-jvhwSSW_.js";import{I as se}from"./input-DcaHre60.js";import{C as ne,S as h,g as oe}from"./catalog-subgraph-D0LzZVVf.js";import{S as le}from"./search-D8Je0oyf.js";import{C as ie}from"./chevron-right-Bm_-M2lJ.js";import"./radix-ui-DdasXo-Q.js";/** 2 * @license lucide-react v0.454.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 ce=ee("SlidersHorizontal",[["line",{x1:"21",x2:"14",y1:"4",y2:"4",key:"obuewd"}],["line",{x1:"10",x2:"3",y1:"4",y2:"4",key:"1q6298"}],["line",{x1:"21",x2:"12",y1:"12",y2:"12",key:"1iu8h1"}],["line",{x1:"8",x2:"3",y1:"12",y2:"12",key:"ntss68"}],["line",{x1:"21",x2:"16",y1:"20",y2:"20",key:"14d8ph"}],["line",{x1:"12",x2:"3",y1:"20",y2:"20",key:"m0wm8r"}],["line",{x1:"14",x2:"14",y1:"2",y2:"6",key:"14e1ph"}],["line",{x1:"8",x2:"8",y1:"10",y2:"14",key:"1i6ji0"}],["line",{x1:"16",x2:"16",y1:"18",y2:"22",key:"1lctlv"}]]),d="https://ctvcam.com",M=12;function I(r){return r==null?"":new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:0,maximumFractionDigits:0}).format(r/100)}function de(r){var i,l;const t=(i=r.priceRange)==null?void 0:i.min,n=(l=r.priceRange)==null?void 0:l.max;return t?t===n?I(t):`${I(t)} â ${I(n)}`:"Contact for price"}function me(r){const t=r.toLowerCase();return t.includes("bullet")?"Bullet":t.includes("dome")?"Dome":t.includes("turret")?"Turret":"Camera"}function ue(r){const t=r.match(/^(\d+)ch/i);return t?`${t[1]}CH`:""}function xe(r){const t=r.toLowerCase();return t.includes("8mp")?"8MP":t.includes("4mp")?"4MP":t.includes("2mp")?"2MP":""}function fe(r){const t=r.toLowerCase();return t.includes("nvr")?"NVR":t.includes("dvr")?"DVR":""}const O=[{label:"All Products",value:""},{label:"DVR Systems",value:"dvr"},{label:"NVR Systems",value:"nvr"},{label:"8MP / 4K",value:"8mp"},{label:"2MP / 1080P",value:"2mp"},{label:"Bullet Cameras",value:"bullet"},{label:"Dome Cameras",value:"dome"},{label:"Turret Cameras",value:"turret"}],pe={bullet:"/airo-assets/images/products/bullet-camera-dvr"};function he(r){const t=oe(r);if(t)return t;const n=(r.label??r.name??"").toLowerCase();for(const[i,l]of Object.entries(pe))if(n.includes(i))return l;return null}function ge({product:r}){const t=he(r),n=r.label??r.name??"Product",i=me(n),l=ue(n),u=xe(n),x=fe(n);return e.jsxs("article",{className:"group relative rounded-xl overflow-hidden border border-border/60 bg-card hover:border-primary/50 transition-all duration-300 hover:shadow-[0_0_30px_hsl(var(--primary)/0.12)] flex flex-col","data-dev-source-origin":"commerce","data-dev-commerce-product-id":r.id??"",children:[e.jsxs(T,{to:`/products/${r.id}`,className:"block relative overflow-hidden aspect-[4/3]",children:[t?e.jsx("img",{src:t,alt:n,className:"w-full h-full object-cover transition-transform duration-500 group-hover:scale-105",loading:"lazy",width:400,height:300}):e.jsx("div",{className:"w-full h-full bg-muted flex items-center justify-center",children:e.jsx(q,{size:40,className:"text-muted-foreground/40"})}),e.jsx("div",{className:"absolute inset-0 pointer-events-none",style:{background:"linear-gradient(to top, hsl(var(--card)/0.85) 0%, transparent 50%)"}}),e.jsxs("div",{className:"absolute top-3 left-3 flex gap-1.5 pointer-events-none",children:[l&&e.jsx(C,{className:"bg-primary/90 text-primary-foreground text-xs font-semibold px-2 py-0.5",children:l}),x&&e.jsx(C,{className:"bg-card/90 text-foreground border border-border/60 text-xs font-semibold px-2 py-0.5",children:x})]})]}),e.jsxs("div",{className:"p-4 flex flex-col flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[u&&e.jsx("span",{className:"text-primary text-xs font-semibold uppercase tracking-wider",children:e.jsx(j,{devId:"f5605f",guard:{file:"src/pages/products/index.tsx",tagName:"span",sourceKind:"bound-expression",contentKey:null,contentKeyTemplate:null,expressionHash:"sha256:f7fbd5853d11940e045abc7c4d7b8e3253947bcde21b8cd8555d71c6f02fd912"},children:u})}),u&&i&&e.jsx("span",{className:"text-border",children:"·"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:e.jsx(j,{devId:"f56061",guard:{file:"src/pages/products/index.tsx",tagName:"span",sourceKind:"bound-expression",contentKey:null,contentKeyTemplate:null,expressionH
6ash:"sha256:83f0fc020d5627f8ddaad287c5ec3765a94ada365f6cc535aba39f093c46eb75"},children:i})})]}),e.jsx(T,{to:`/products/${r.id}`,className:"flex-1",children:e.jsx("h3",{className:"text-foreground font-semibold text-sm leading-snug mb-3 hover:text-primary transition-colors line-clamp-2",children:e.jsx(j,{devId:"705dd3",guard:{file:"src/pages/products/index.tsx",tagName:"h3",sourceKind:"bound-expression",contentKey:null,contentKeyTemplate:null,expressionHash:"sha256:1aca80e8b55c802f7b43740da2990e1b5735bbb323d93eb5ebda8395b04025e2"},children:n})})}),e.jsxs("div",{className:"flex items-center justify-between mt-auto pt-3 border-t border-border/40",children:[e.jsx("div",{children:e.jsx("p",{className:"text-foreground font-bold text-base",children:e.jsx(j,{devId:"7b9db2",guard:{file:"src/pages/products/index.tsx",tagName:"p",sourceKind:"bound-expression",contentKey:null,contentKeyTemplate:null,expressionHash:"sha256:03a2b5ddc17cf7dd56a3ed0eb5f32f93f3facfbb317d45eb4e58df4daebbae9f"},children:de(r)})})}),e.jsx(N,{size:"sm",asChild:!0,className:"bg-primary/10 hover:bg-primary text-primary hover:text-primary-foreground border border-primary/30 hover:border-primary transition-all duration-200 text-xs shrink-0",children:e.jsxs(T,{to:`/products/${r.id}`,children:[e.jsx(ae,{size:13,className:"mr-1.5"}),"View"]}
6)})]})]})]})}function be(){return e.jsxs("div",{className:"rounded-xl overflow-hidden border border-border/60 bg-card flex flex-col",children:[e.jsx(h,{className:"aspect-[4/3] w-full rounded-none"}),e.jsxs("div",{className:"p-4 flex flex-col gap-3",children:[e.jsx(h,{className:"h-3 w-16"}),e.jsx(h,{className:"h-4 w-full"}),e.jsx(h,{className:"h-4 w-3/4"}),e.jsxs("div",{className:"flex items-center justify-between pt-3 border-t border-border/40",children:[e.jsx(h,{className:"h-5 w-20"}),e.jsx(h,{className:"h-8 w-20 rounded-md"})]})]})]})}function Se(){var K;const[r,t]=re(),[n,i]=c.useState([]),[l,u]=c.useState(!0),[x,A]=c.useState(0),[g,Q]=c.useState({hasNextPage:!1,hasPreviousPage:!1}),[V,w]=c.useState(""),P=c.useRef(null),m=r.get("q")??"",f=r.get("filter")??"",b=r.get("after")??"",L=c.useCallback(async()=>{var a,s,o,$,z,D,U,B,F,H;u(!0);try{const v=new URLSearchParams;v.set("first",String(M));const _=[m,f].filter(Boolean).join(" ");_&&v.set("searchQuery",_),b&&v.set("after",b);const E=await fetch(`/api/commerce/products?${v.toString()}`);if(!E.ok)throw new Error("Failed to fetch");const p=await E.json(),Y=((a=p.skuGroups)==null?void 0:a.edges)??[];i(Y.map(y=>y==null?void 0:y.node).filter(y=>!!y)),A(((s=p.skuGroups)==null?void 0:s.totalCount)??0),Q({hasNextPage:(($=(o=p.skuGroups)==null?void 0:o.pageInfo)==null?void 0:$.hasNextPage)??!1,hasPreviousPage:((D=(z=p.skuGroups)==null?void 0:z.pageInfo)==null?void 0:D.hasPreviousPage)??!1,endCursor:(B=(U=p.skuGroups)==null?void 0:U.pageInfo)==null?void 0:B.endCursor,startCursor:(H=(F=p.skuGroups)==null?void 0:F.pageInfo)==null?void 0:H.startCursor})}catch{i([])}finally{u(!1)}},[m,f,b]);c.useEffect(()=>{w(m)},[m]),c.useEffect(()=>{L()},[L]);const J=a=>{w(a),P.current&&clearTimeout(P.current),P.current=setTimeout(()=>{t(s=>{const o=new URLSearchParams(s);return a?o.set("q",a):o.delete("q"),o.delete("after"),o.delete("before"),o})},400)},S=a=>{t(s=>{const o=new URLSearchParams(s);return a?o.set("filter",a):o.delete("filter"),o.delete("after"),o.delete("before"),o})},X=()=>{t(a=>{const s=new URLSearchParams(a);return g.endCursor&&s.set("after",g.endCursor),s.delete("before"),s}),window.scrollTo({top:0,behavior:"smooth"})},Z=()=>{t(a=>{const s=new URLSearchParams(a);return s.delete("after"),s}),window.scrollTo({top:0,behavior:"smooth"})},k=()=>{w(""),t(a=>{const s=new URLSearchParams(a);return s.delete("q"),s.delete("after"),s})},W={"@context":"https://schema.org","@type":"CollectionPage","@id":`${d}/products#webpage`,name:"Commercial Security Camera Systems â CTVCam",description:"Browse commercial-grade DVR and NVR security camera packages, bullet, dome, and turret cameras with professional installation available in Texas.",url:`${d}/products`,isPartOf:{"@id":`${d}/#website`},about:{"@id":`${d}/#organization`}};return e.jsxs(e.Fragment,{children:[e.jsxs(te,{children:[e.jsx("title",{children:"Commercial Security Camera Systems â CTVCam"}),e.jsx("meta",{name:"description",content:"Browse commercial-grade security camera packages â DVR & NVR systems, 8MP 4K and 2MP 1080P, bullet, dome, and turret cameras. Professional installation available in Texas."}),e.jsx("link",{rel:"canonical",href:`${d}/products`}),e.jsx("meta",{property:"og:title",content:"Commercial Security Camera Systems â CTVCam"}),e.jsx("meta",{property:"og:description",content:"Commercial-grade DVR and NVR security camera packages with professional installation. 4-channel to 16-channel systems for any business."}),e.jsx("meta",{property:"og:type",content:"website"}),e.jsx("meta",{property:"og:url",content:`${d}/products`}),e.jsx("meta",{property:"og:image",content:`${d}/og-image.png`}),e.jsx("meta",{name:"twitter:card",content:"summary_large_image"}),e.jsx("meta",{name:"twitter:title",content:"Commercial Security Camera Systems â CTVCam"}),e.jsx("meta",{name:"twitter:description",content:"Commercial-grade DVR and NVR security camera packages with professional installation in Texas."}),e.jsx("meta",{name:"twitter:image",content:`${d}/og-image.png`}),e.jsx("script",{type:"application/ld+json",children:JSON.stringify(W)})]}),e.jsxs("main",{className:"pt-20 min-h-screen bg-background",children:[e.jsx("div",{className:"border-b border-border/40 bg-card/30",children:e.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10",children:e.jsxs(G.div,{initial:{opacity:0,y:16}
6,animate:{opacity:1,y:0},transition:{duration:.4,ease:"easeOut"},children:[e.jsx("p",{className:"text-primary text-sm font-semibold uppercase tracking-wider mb-2",children:"Product Catalog"}),e.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-foreground mb-2",children:"Security Camera Systems"}),e.jsx("p",{className:"text-muted-foreground",children:e.jsx(j,{devId:"34a6d7",guard:{file:"src/pages/products/index.tsx",tagName:"p",sourceKind:"bound-expression",contentKey:null,contentKeyTemplate:null,expressionHash:"sha256:4b5e70273a0a3d148970f2139f8af58dd626e800761ba277e52f8df9113315eb"},children:x>0&&!l?`${x} products available`:"Commercial-grade DVR & NVR packages"})})]})})}),e.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[e.jsxs("div",{className:"flex flex-col md:flex-row gap-4 mb-8",children:[e.jsxs("div",{className:"relative flex-1 max-w-md",children:[e.jsx(le,{size:16,className:"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none"}),e.jsx(se,{value:V,onChange:a=>J(a.target.value),placeholder:"Search products...",className:"pl-9 pr-9 bg-card border-border/60 focus:border-primary text-foreground placeholder:text-muted-foreground"}),V&&e.jsx("button",{onClick:k,className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors","aria-label":"Clear search",children:e.jsx(R,{size:14})})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx(ce,{size:15,className:"text-muted-foreground shrink-0"}),O.map(a=>e.jsx("button",{onClick:()=>S(a.value),className:`px-3 py-1.5 rounded-full text-xs font-medium transition-all duration-200 border ${f===a.value?"bg-primary text-primary-foreground border-primary":"bg-card text-muted-foreground border-border/60 hover:border-primary/50 hover:text-foreground"}`,children:a.label},a.value))]})]}),(m||f)&&e.jsxs("div",{className:"flex items-center gap-2 mb-6 flex-wrap",children:[e.jsx("span",{className:"text-muted-foreground text-sm",children:"Filtering by:"}),m&&e.jsxs(C,{variant:"secondary",className:"gap-1.5 text-xs",children:['"',m,'"',e.jsx("button",{onClick:k,"aria-label":"Remove search filter",children:e.jsx(R,{size:11})})]}),f&&e.jsxs(C,{variant:"secondary",className:"gap-1.5 text-xs",children:[(K=O.find(a=>a.value===f))==null?void 0:K.label,e.jsx("button",{onClick:()=>S(""),"aria-label":"Remove filter",children:e.jsx(R,{size:11})})]})]}),l?e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-
65",children:Array.from({length:M}).map((a,s)=>e.jsx(be,{},s))}):n.length===0?e.jsxs("div",{className:"text-center py-24",children:[e.jsx(q,{size:48,className:"text-muted-foreground/30 mx-auto mb-4"}),e.jsx("h3",{className:"text-foreground font-semibold text-lg mb-2",children:"No products found"}),e.jsx("p",{className:"text-muted-foreground text-sm mb-6",children:"Try adjusting your search or filters."}),e.jsx(N,{variant:"outline",onClick:()=>{k(),S("")},className:"border-border text-foreground hover:border-primary hover:text-primary",children:"Clear all filters"})]}):e.jsx(G.div,{initial:{opacity:0},animate:{opacity:1},transition:{duration:.3},className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5",children:n.map(a=>e.jsx(ge,{product:a},a.id))}),!l&&n.length>0&&(g.hasNextPage||g.hasPreviousPage||b)&&e.jsxs("div",{className:"flex items-center justify-between mt-10 pt-6 border-t border-border/40",children:[e.jsxs(N,{variant:"outline",onClick:Z,disabled:!b,className:"border-border text-foreground hover:border-primary hover:text-primary disabled:opacity-40",children:[e.jsx(ne,{size:16,className:"mr-1.5"}),"Previous"]}),e.jsxs("p",{className:"text-muted-foreground text-sm",children:["Showing ",n.length," of ",x," products"]}),e.jsxs(N,{variant:"outline",onClick:X,disabled:!g.hasNextPage,className:"border-border text-foreground hover:border-primary hover:text-primary disabled:opacity-40",children:["Next",e.jsx(ie,{size:16,className:"ml-1.5"})]})]})]})]})]})}export{Se 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.