PageSourceSearch

https://www.freelancerllm.com/assets/ContactInboxPage-Cr_-E2MR.js

js freelancerllm.com collected 2026-10-02 01:30:25 UTC 7,515 bytes, 117 lines download raw bytes

1import{r as s,j as e}from"./react-CHTGUyAX.js";import{a as h}from"./index-COIxwMRP.js";import{N as f}from"./PageSeo-C78Y-SUW.js";import"./router-D1a9Ug87.js";function C(i){if(!i)return"—";try{return new Date(i).toLocaleString()}catch{return i}}function M(){const[i,g]=s.useState(!0),[S,j]=s.useState(!1),[x,m]=s.useState([]),[c,z]=s.useState("all"),[w,y]=s.useState(""),[v,p]=s.useState(""),b=s.useCallback(async()=>{g(!0),p("");try{const t=await h("/api/contact/inbox-access"),d=await t.json().catch(()=>({}));if(!t.ok)throw new Error(d.message||"Could not check access");if(!d.canView){j(!1),m([]);return}j(!0);const o=c!=="all"?`?status=${encodeURIComponent(c)}`:"",r=await h(`/api/contact/messages${o}`),l=await r.json().catch(()=>({}));if(!r.ok)throw new Error(l.message||"Could not load messages");const n=l.messages||[];m(n),y(u=>{var k;return u&&n.some(L=>L.id===u)?u:((k=n[0])==null?void 0:k.id)||""})}catch(t){p(t.message||"Couldn't load contact messages. Refresh and try again.")}finally{g(!1)}},[c]);s.useEffect(()=>{b()},[b]);const a=x.find(t=>t.id===w)||null;async function N(t,d){try{const o=await h(`/api/contact/messages/${t}`,{method:"PATCH",body:{status:d}}),r=await o.json().catch(()=>({}));if(!o.ok)throw new Error(r.message||"Update failed");m(l=>l.map(n=>n.id===t?{...n,status:r.status}:n))}catch(o){p(o.message||"Could not update status")}}return i?e.jsxs("div",{className:"contact-inbox",children:[e.jsx(f,{title:"Contact inbox — FreelancerLLM"}),e.jsx("p",{className:"muted",children:"Loading contact messages…"})]}):S?e.jsxs("div",{className:"contact-inbox",children:[e.jsx(f,{title:"Contact inbox — FreelancerLLM"}),e.jsxs("header",{className:"contact-inbox-head",children:[e.jsxs("div",{children:[e.jsx("h1",{children:"Contact inbox"}),e.jsx("p",{className:"muted",children:"Submissions from the public contact form (stored in MongoDB)."})]}),e.jsxs("div",{className:"contact-inbox-filters",children:[["all","new","read","archived"].map(t=>e.jsx("button",{type:"button",className:c===t?"active":"",onClick:()=>z(t),children:t},t)),e.jsx("button",{type:"button",onClick:()=>void b(),children:"Refresh"})]})]}),v&&e.jsx("p",{className:"contact-inbox-error",children:v}),e.jsxs("div",{className:"contact-inbox-grid",children:[e.jsx("div",{className:"contact-inbox-list",children:x.length===0?e.jsx("p",{className:"muted",children:"No contact messages yet. New form submissions will appear here."}):x.map(t=>e.jsxs("button",{type:"button",className:`contact-inbox-item${t.id===w?" selected":""}`,onClick:()=>y(t.id),children:[e.jsx("strong",{children:t.subject}),e.jsxs("span",{children:[t.name," · ",t.email]}),e.jsxs("span",{className:"meta",children:[t.category," · ",t.status," · ",C(t.createdAt)]})]},t.id))}),e.jsx("div",{className:"contact-inbox-detail",children:a?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"detail-head",children:[e.jsx("h2",{children:a.subject}),e.jsxs("div",{className:"detail-actions",children:[e.jsx("button",{type:"button",onClick:()=>void N(a.id,"read"),children:"Mark read"}),e.jsx("button",{type:"button",onClick:()=>void N(a.id,"archived"),children:"Archive"}),e.jsx("a",{href:`mailto:${a.email}?subject=Re: ${encodeURIComponent(a.subject)}`,children:"Reply"})]})]}),e.jsxs("dl",{children:[e.jsx("dt",{children:"From"}),e.jsxs("dd",{children:[a.name," <",a.email,">"]}),e.jsx("dt",{children:"Category"}),e.jsx("dd",{children:a.category}),e.jsx("dt",{children:"Status"}),e.jsx("dd",{children:a.status}),e.jsx("dt",{children:"Received"}),e.jsx("dd",{children:C(a.createdAt)})]}),e.jsx("pre",{className:"detail-message",children:a.message})]}):e.jsx("p",{className:"muted",children:"Select a message to view details."})})]}),e.jsx("style",{children:`
2        .contact-inbox h1 { margin: 0 0 6px; font-size: 1.5rem; }
3        .contact-inbox .muted { color: var(--muted, #6b7280); margin: 0; }
4        .contact-inbox-head {
5          display: flex;
6          flex-wrap: wrap;
7          justify-content: space-between;
8          gap: 16px;
9          margin-bottom: 20px;
10        }
11        .contact-inbox-filters {
12          display: flex;
13          flex-wrap: wrap;
14          gap: 8px;
15          align-items: center;
16        }
17        .contact-inbox-filters button {
18          padding: 6px 12px;
19          border-radius: 8px;
20          border: 1px solid var(--border, #e7e5e4);
21          background: #fff;
22          cursor: pointer;
23          font-size: 0.85rem;
24        }
25        .contact-inbox-filters button.active {
26          border-color: #059669;
27          background: rgba(5, 150, 105, 0.08);
28          color: #047857;
29        }
30        .contact-inbox-error {
31          color: #b91c1c;
32          margin-bottom: 12px;
33        }
34        .contact-inbox-grid {
35          display: grid;
36          grid-template-columns: minmax(240px, 340px) 1fr;
37          gap: 16px;
38          min-height: 420px;
39        }
40        @media (max-width: 900px) {
41          .contact-inbox-grid { grid-template-columns: 1fr; }
42        }
43        .contact-inbox-list,
44        .contact-inbox-detail {
45          border: 1px solid var(--border, #e7e5e4);
46          border-radius: 12px;
47          background: #fff;
48          padding: 12px;
49        }
50        .contact-inbox-item {
51          display: flex;
52          flex-direction: column;
53          align-items: flex-start;
54          gap: 4px;
55          width: 100%;
56          text-align: left;
57          padding: 10px 12px;
58          margin-bottom: 8px;
59          border-radius: 8px;
60          border: 1px solid transparent;
61          background: #fafaf9;
62          cursor: pointer;
63          font: inherit;
64        }
65        .contact-inbox-item.selected {
66          border-color: #059669;
67          background: rgba(5, 150, 105, 0.06);
68        }
69        .contact-inbox-item strong { font-size: 0.92rem; }
70        .contact-inbox-item span { font-size: 0.8rem; color: #57534e; }
71        .contact-inbox-item .meta { font-size: 0.75rem; color: #78716c; }
72        .detail-head {
73          display: flex;
74          flex-wrap: wrap;
75          justify-content: space-between;
76          gap: 12px;
77          margin-bottom: 16px;
78        }
79        .detail-head h2 { margin: 0; font-size: 1.15rem; }
80        .detail-actions {
81          display: flex;
82          flex-wrap: wrap;
83          gap: 8px;
84          align-items: center;
85        }
86        .detail-actions button,
87        .detail-actions a {
88          padding: 6px 12px;
89          border-radius: 8px;
90          border: 1px solid var(--border, #e7e5e4);
91          background: #fff;
92          font-size: 0.85rem;
93          text-decoration: none;
94          color: #059669;
95          cursor: pointer;
96        }
97        .contact-inbox dl {
98          display: grid;
99          grid-template-columns: 100px 1fr;
100          gap: 6px 12px;
101          margin: 0 0 16px;
102          font-size: 0.9rem;
103        }
104        .contact-inbox dt { color: #78716c; margin: 0; }
105        .contact-inbox dd { margin: 0; }
106        .detail-message {
107          white-space: pre-wrap;
108          word-break: break-word;
109          margin: 0;
110          padding: 14px;
111          border-radius: 8px;
112          background: #faf7f2;
113          font-family: inherit;
114          font-size: 0.92rem;
115          line-height: 1.6;
116        }
117      `})]}):e.jsxs("div",{className:"contact-inbox",children:[e.jsx(f,{title:"Contact inbox — FreelancerLLM"}),e.jsx("h1",{children:"Contact inbox"}),e.jsx("p",{className:"muted",children:"You do not have permission to view contact submissions."})]})}
117export{M 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.