PageSourceSearch

https://ctwalsh.com/assets/admin.projects._id-Dm8gUAM5.js

js ctwalsh.com collected 2026-10-02 01:28:20 UTC 7,199 bytes, 1 lines download raw bytes

1import{D as k,c as d,w as t,E as u}from"./index-jWWD7jul.js";import{j as F,H as q,a7 as Q,u as $,F as A,L as I,t as i}from"./routeTree.gen-BLs9mk7j.js";import{u as y}from"./useQuery-DyPcMpgP.js";import{u as P}from"./useServerFn-Btw2kepA.js";import{B as h}from"./button-BzLzroW1.js";import{T as p,F as _,N as z,a as G}from"./admin-form-Dci-guTu.js";import{D as J}from"./drop-zone-Cl-Qa_OF.js";import"./useBaseQuery-BqQO5Hyc.js";import"./index-BzclYw72.js";import"./input-ChxVGATT.js";import"./textarea-DF-wN8rA.js";const M=F({method:"POST"}).middleware([q]).handler(k("75351ab5f25875ac22da2153f7364046d0e3dc08fe9e92bfe34e1592ef79db9a")),V=F({method:"POST"}).middleware([q]).handler(k("a78925095aea183a89d22f876aa2a322117677d5f515e10560123af6b4384ead")),Z={title:"",description:null,category:"",status:"idea",meta:null,cover_image:null,external_url:null,link_label:null,sort_order:0,published:!1,published_at:null};function ne(){const{id:o}=Q.useParams(),r=o==="new",w=$(),g=A(),{data:m,isLoading:D}=y({queryKey:["admin","project",o],queryFn:async()=>{if(r)return null;const{data:e,error:a}=await u.from("projects").select("*").eq("id",o).maybeSingle();if(a)throw a;return e}}),E=y({queryKey:["admin","project_statuses"],queryFn:async()=>{const{data:e,error:a}=await u.from("project_statuses").select("slug, label").order("sort_order");if(a)throw a;return e}}),x=y({queryKey:["admin","project_categories"],queryFn:async()=>{const{data:e,error:a}=await u.from("project_categories").select("slug, label").order("sort_order");if(a)throw a;return e}}),[s,f]=d.useState(Z),[c,N]=d.useState(!1),[L,S]=d.useState(!1),C=d.useRef(!1);d.useEffect(()=>{m&&!C.current&&(f(m),C.current=!0)},[m]);const l=(e,a)=>f(n=>({...n,[e]:a})),T=async e=>{S(!0);try{const a=`projects/${Date.now()}-${e.name.replace(/[^a-zA-Z0-9.\-_]/g,"_")}`,{error:n}=await u.storage.from("listing-images").upload(a,e,{upsert:!1});if(n)throw n;const{data:v}=u.storage.from("listing-images").getPublicUrl(a);l("cover_image",v.publicUrl),i.success("Image uploaded")}catch(a){i.error(a instanceof Error?a.message:"Upload failed")}finally{S(!1)}},U=P(M),R=P(V),K=(e={})=>{const a={...s,...e};return{title:a.title,description:a.description??null,category:a.category||x.data?.[0]?.slug||"",status:a.status??"idea",meta:a.meta??null,cover_image:a.cover_image??null,external_url:a.external_url??null,link_label:a.link_label??null,sort_order:a.sort_order??0,published:!!a.published,published_at:a.published_at??null}},b=async(e={})=>{N(!0);try{const a=K(e),{id:n}=await U({data:{id:r?null:o,project:a}});Object.keys(e).length&&f(v=>({...v,...e})),i.success(r?"Project created":"Saved"),g.invalidateQueries({queryKey:["admin","projects"]}),g.invalidateQueries({queryKey:["admin","project",n]}),r&&w({to:"/admin/projects/$id",params:{id:n}})}catch(a){i.error(a instanceof Error?a.message:"Save failed")}finally{N(!1)}},B=async()=>{if(r){i.error("Save the project first, then publish.");return}const e=!s.published;await b({published:e,published_at:e&&!s.published_at?new Date().toISOString():s.published_at}),i.success(e?"Published":"Unpublished")},O=async()=>{if(!r&&confirm(`Delete ${s.title}?`))try{await R({data:{id:o}}),i.success("Deleted"),g.invalidateQueries({queryKey:["admin","projects"]}),w({to:"/admin/projects"})}catch(e){i.error(e instanceof Error?e.message:"Delete failed")}};if(!r&&D)return t.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"});if(!r&&!m)return t.jsx("p",{className:"text-sm text-destructive",children:"Project not found."});const j="w-full border hairline bg-background px-3 py-2 text-sm rounded-md";return t.jsxs("div",{className:"max-w-4xl",children:[t.jsx(I,{to:"/admin/projects",className:"text-xs font-sans text-muted-foreground",children:"[ ← projects ]"}),t.jsxs("div",{className:"mt-4 flex items-start justify-between gap-4",children:[t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("h1",{className:"text-2xl font-sans",children:r?"New project":s.title||"Untitled"}),t.jsx("span",{className:`label px-2 py-1 border hairline ${s.published?"text-foreground":"text-destructive"}`,children:s.published?"● on site":"○ draft"})]}),!r&&t.jsxs("p",{className:"mt-1 text-xs font-sans text-muted-foreground select-all",children:["ID: ",o]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[!r&&s.external_url&&t.jsx("a",{href:s.external_url,target:"_blank",rel:"noreferrer",className:"text-xs font-sans text-muted-foreground underline underline-offset-4 hover:text-foreground",children:"[ visit ↗ ]"}),!r&&t.jsx(h,{variant:"ghost",onClick:O,className:"text-destructive",children:"Delete"}),t.jsx(h,{variant:"outline",onClick:()=>
1b(),disabled:c,children:c?"Saving…":"Save draft"}),!r&&t.jsx(h,{onClick:B,disabled:c,children:s.published?"Remove from site":"Publish to site"})]})]}),t.jsxs("section",{className:"mt-10 border-t hairline pt-6",children:[t.jsx("p",{className:"label mb-4",children:"Basics"}),t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsx(p,{label:"Title",value:s.title,onChange:e=>l("title",e),required:!0}),t.jsx(_,{label:"Category",hint:"Add or edit categories in the Categories tab",children:t.jsx("select",{className:j,value:s.category||x.data?.[0]?.slug||"",onChange:e=>l("category",e.target.value),children:(x.data??[]).map(e=>t.jsx("option",{value:e.slug,children:e.label},e.slug))})}),t.jsx(_,{label:"Status",hint:"Add or edit statuses in the Statuses tab",children:t.jsx("select",{className:j,value:s.status??"idea",onChange:e=>l("status",e.target.value),children:(E.data??[]).map(e=>t.jsx("option",{value:e.slug,children:e.label},e.slug))})}),t.jsx(z,{label:"Sort order",value:s.sort_order,onChange:e=>l("sort_order",e??0),hint:"Lower numbers show first"})]}),t.jsx(G,{label:"Description",value:s.description,onChange:e=>l("description",e||null),rows:2,hint:"The one-line summary shown on the card",className:"mt-4"}),t.jsxs("div",{className:"grid grid-cols-2 gap-4 mt-4",children:[t.jsx(p,{label:"Meta line",value:s.meta,onChange:e=>l("meta",e||null),placeholder:"Chrome extension · 2025",hint:"Small type under the description"}),t.jsx(p,{label:"External link",value:s.external_url,onChange:e=>l("external_url",e||null),placeholder:"https://…",hint:"The card's link. Only shown when status is Live."}),t.jsx(p,{label:"Link label",value:s.link_label,onChange:e=>l("link_label",e||null),placeholder:"Visit",hint:"Button text for the link (e.g. Download, Enroll, Join waitlist). Defaults to “Visit”."})]})]}),t.jsxs("section",{className:"mt-10 border-t hairline pt-6",children:[t.jsx("p",{className:"label mb-4",children:"Cover image"}),t.jsx(_,{label:"URL",hint:"Paste a URL or upload below",children:t.jsx("input",{className:j,value:s.cover_image??"",onChange:e=>l("cover_image",e.target.value||null)})}),t.jsx("div",{className:"mt-2",children:t.jsx(J,{uploading:L,onFiles:e=>{const a=e[0];a&&T(a)},hint:"PNG, JPG, WEBP"})}),s.cover_image&&t.jsx("img",{src:s.cover_image,alt:"",className:"mt-3 max-h-40 border hairline"})]}),t.jsx("div",{className:"mt-8 flex justify-end",children:t.jsx(h,{onClick:()=>b(),disabled:c,children:c?"Saving…":"Save draft"})})]})}export{ne as component};

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.