PageSourceSearch

https://rankpine.com/assets/feedback-dialog-BB3lNXLP.js

js rankpine.com collected 2026-10-02 05:19:41 UTC 4,858 bytes, 1 lines download raw bytes

1import{$ as e,Z as t}from"./components-DVvmw17K.js";import{a as n}from"./lib-037fcQjj.js";import{t as r}from"./jsx-runtime-CfTG4PTq.js";import{t as i}from"./utils-DojpP95n.js";import{t as a}from"./button-DynFPFiX.js";import{i as o,t as s}from"./analytics-DOCL9tzx.js";import{t as c}from"./Image.es-BQb4DAmi.js";import{t as l}from"./Paperclip.es-BayJxquR.js";import{t as u}from"./SpinnerGap.es-6FMMK_ni.js";import{t as d}from"./XCircle.es-B-XELFO6.js";import{t as f}from"./textarea-Bw54mjGd.js";import{a as p,i as m,n as h,o as g,r as _,t as v}from"./dialog-DDwTzRLl.js";var y=e(t(),1),b=r(),x=`image/png,image/jpeg,image/webp,image/gif,application/pdf`,S=10,C=5;function w({open:e,onClose:t}){let r=n(),[w,T]=(0,y.useState)(``),[E,D]=(0,y.useState)([]),[O,k]=(0,y.useState)(!1),[A,j]=(0,y.useState)(null),M=(0,y.useRef)(null),N=r.state!==`idle`,P=r.data?.ok===!0,F=(0,y.useRef)(0);(0,y.useEffect)(()=>{r.data?.ok&&o(s.feedbackSubmitted,{attachments:F.current})},[r.data]);function I(){T(``),D([]),j(null),t()}function L(e){j(null);let t=Array.from(e),n=[...E];for(let e of t){if(n.length>=C){j(`Max ${C} attachments.`);break}if(e.size>S*1024*1024){j(`"${e.name}" exceeds ${S} MB.`);continue}let t=e.type.startsWith(`image/`)?URL.createObjectURL(e):void 0;n.push({id:crypto.randomUUID(),file:e,preview:t})}D(n)}function R(e){e.preventDefault(),k(!1),e.dataTransfer.files.length&&L(e.dataTransfer.files)}function z(e){let t=Array.from(e.clipboardData.items).filter(e=>e.kind===`file`).map(e=>e.getAsFile()).filter(e=>e!==null);t.length&&L(t)}function B(e){D(t=>{let n=t.find(t=>t.id===e);return n?.preview&&URL.revokeObjectURL(n.preview),t.filter(t=>t.id!==e)})}function V(){if(!w.trim())return;let e=new FormData;e.set(`message`,w.trim());for(let{file:t}of E)e.append(`attachments`,t);F.current=E.length,r.submit(e,{method:`post`,action:`/api/feedback`,encType:`multipart/form-data`})}return(0,b.jsx)(v,{open:e,onOpenChange:e=>{!e&&!N&&I()},children:(0,b.jsx)(h,{className:`max-w-md`,children:P?(0,b.jsxs)(`div`,{className:`py-6 text-center`,children:[(0,b.jsx)(`p`,{className:`text-2xl`,children:`✓`}),(0,b.jsx)(`h2`,{className:`mt-3 font-semibold text-lg tracking-tight`,children:`Thanks for your feedback!`}),(0,b.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:`We read every note and use it to make RankPine better.`}),(0,b.jsx)(a,{variant:`secondary`,size:`sm`,className:`mt-5`,onClick:I,children:`Close`})]}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(p,{children:[(0,b.jsx)(g,{children:`Give feedback`}),(0,b.jsx)(_,{children:`Tell us what's working, what isn't, or what you'd like to see.`})]}),(0,b.jsxs)(`div`,{className:`space-y-3`,children:[(0,b.jsx)(f,{placeholder:`Add a few details so we can understand the context…`,rows:4,value:w,onChange:e=>T(e.target.value),onPaste:z,disabled:N,className:`resize-none`}),E.length>0&&(0,b.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:E.map(({id:e,file:t,preview:n})=>(0,b.jsxs)(`div`,{className:`group relative flex h-14 w-14 items-center justify-center overflow-hidden rounded-lg border border-border bg-muted`,children:[n?(0,b.jsx)(`img`,{src:n,alt:t.name,className:`h-full w-full object-cover`}):(0,b.jsx)(l,{className:`size-5 text-muted-foreground`}),(0,b.jsx)(`button`,{type:`button`,onClick:()=>B(e),className:`absolute inset-0 flex items-center justify-center bg-foreground
1/60 opacity-0 transition-opacity group-hover:opacity-100`,"aria-label":`Remove ${t.name}`,children:(0,b.jsx)(d,{weight:`fill`,className:`size-5 text-white`})})]},e))}),(0,b.jsxs)(`div`,{onDragOver:e=>{e.preventDefault(),k(!0)},onDragLeave:()=>k(!1),onDrop:R,className:i(`flex cursor-pointer flex-col items-center justify-center gap-1.5 rounded-lg border border-dashed py-4 transition-colors`,O?`border-primary bg-primary/5`:`border-border bg-muted/40 hover:border-muted-foreground/40`),onClick:()=>M.current?.click(),children:[(0,b.jsx)(c,{className:`size-5 text-muted-foreground`}),(0,b.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`Drop or paste an image here · or`,` `,(0,b.jsx)(`span`,{className:`font-medium text-foreground`,children:`browse`})]}),(0,b.jsxs)(`span`,{className:`text-[11px] text-muted-foreground/60`,children:[`PNG, JPG, GIF, PDF · max `,S,` MB each`]})]}),(0,b.jsx)(`input`,{ref:M,type:`file`,accept:x,multiple:!0,className:`hidden`,onChange:e=>e.target.files&&L(e.target.files)}),A&&(0,b.jsx)(`p`,{className:`text-xs text-destructive`,children:A}),r.data?.error&&(0,b.jsx)(`p`,{className:`text-xs text-destructive`,children:r.data.error})]}),(0,b.jsxs)(m,{children:[(0,b.jsx)(a,{variant:`secondary`,size:`sm`,onClick:I,disabled:N,children:`Cancel`}),(0,b.jsx)(a,{size:`sm`,onClick:V,disabled:N||!w.trim(),children:N?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(u,{className:`animate-spin`}),`Sending…`]}):`Send feedback`})]})]})})})}export{w as t};

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.