ocean-brain 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/server/client/dist/assets/Calendar-DynpmB3D.js +25 -0
  3. package/server/client/dist/assets/{Callout-B2kPcDrq.js → Callout-tNHgPhLM.js} +1 -1
  4. package/server/client/dist/assets/Graph-DMXLUfCv.js +1 -0
  5. package/server/client/dist/assets/Image-ZxF459sC.js +1 -0
  6. package/server/client/dist/assets/{Image.es-Dld9r9MJ.js → Image.es-Dnn4SMzG.js} +1 -1
  7. package/server/client/dist/assets/{ModalActionRow-CES9L_Gy.js → ModalActionRow-B3vNjcDc.js} +1 -1
  8. package/server/client/dist/assets/Note-PDMuj62M.js +1 -0
  9. package/server/client/dist/assets/{Note-SK4hDhEM.css → Note-PEevDKBh.css} +1 -1
  10. package/server/client/dist/assets/Reminders-ComtTLuN.js +1 -0
  11. package/server/client/dist/assets/{Search-Cp17DGR6.js → Search-BJeZTbVu.js} +1 -1
  12. package/server/client/dist/assets/SurfaceCard-DAcVMY4f.js +1 -0
  13. package/server/client/dist/assets/{Tag-CwmuMPmo.js → Tag-BuNCDGD5.js} +1 -1
  14. package/server/client/dist/assets/TagNotes-ajFOP5pZ.js +1 -0
  15. package/server/client/dist/assets/{Trash.es-B3KWD8_C.js → Trash.es-DLiHgjNo.js} +1 -1
  16. package/server/client/dist/assets/{image.api-DJgOBt8S.js → image.api-CjJgNbC0.js} +1 -1
  17. package/server/client/dist/assets/{index-DYUg2N-6.js → index-CDrZmLC2.js} +1 -1
  18. package/server/client/dist/assets/index-DAZMX8bQ.css +1 -0
  19. package/server/client/dist/assets/index-DqFkOWbi.js +205 -0
  20. package/server/client/dist/assets/manage-image-CVyZTDT_.js +1 -0
  21. package/server/client/dist/assets/{manage-image-detail-BVaDZHRu.js → manage-image-detail-Bp17tylS.js} +1 -1
  22. package/server/client/dist/assets/mcp-BpD7VH-d.js +1 -0
  23. package/server/client/dist/assets/placeholder-DSf4QF4v.js +34 -0
  24. package/server/client/dist/assets/trash-Ceb17h_s.js +1 -0
  25. package/server/client/dist/assets/useReminderMutate-CzyOQ_VB.js +82 -0
  26. package/server/client/dist/index.html +2 -2
  27. package/server/dist/modules/blocknote.js +149 -3
  28. package/server/dist/modules/blocknote.js.map +1 -1
  29. package/server/dist/modules/note-authoring.js +16 -3
  30. package/server/dist/modules/note-authoring.js.map +1 -1
  31. package/server/client/dist/assets/Calendar-DRv2aEl8.js +0 -28
  32. package/server/client/dist/assets/Graph-DotbTrZR.js +0 -1
  33. package/server/client/dist/assets/Image-B5R7gF2P.js +0 -1
  34. package/server/client/dist/assets/Note-cIbXJc1v.js +0 -1
  35. package/server/client/dist/assets/Reminders-4LunlZRb.js +0 -1
  36. package/server/client/dist/assets/SurfaceCard-yzVU4Qkx.js +0 -1
  37. package/server/client/dist/assets/TagNotes-gGroWMtT.js +0 -1
  38. package/server/client/dist/assets/color-wpu7wT_s.js +0 -1
  39. package/server/client/dist/assets/index-40Y2UsVr.js +0 -205
  40. package/server/client/dist/assets/index-BnxpTwtL.css +0 -1
  41. package/server/client/dist/assets/manage-image-ByY1mRZx.js +0 -1
  42. package/server/client/dist/assets/mcp-Jj3061aI.js +0 -1
  43. package/server/client/dist/assets/placeholder-4P_GK7fV.js +0 -34
  44. package/server/client/dist/assets/trash-CPBwY07S.js +0 -1
  45. package/server/client/dist/assets/useReminderMutate-1YVndM2T.js +0 -82
@@ -0,0 +1 @@
1
+ import{j as e}from"./note-vendor-BofYbzmZ.js";import{k as x,q as m,ag as p,G as y,w as j,I,P as E,Q as A,E as N,L as M,ah as v,B as G,f as S,S as l,e as w,a9 as T}from"./index-DqFkOWbi.js";import"./graph-vendor-CUxe67Lr.js";import{I as _}from"./Image-ZxF459sC.js";import{S as b}from"./SurfaceCard-DAcVMY4f.js";import{f as P,d as R}from"./image.api-CjJgNbC0.js";import{c as k,n as q}from"./Trash.es-DLiHgjNo.js";import"./note-core-BCgMq5QA.js";const C=r=>{const{data:n}=x({queryKey:m.images.list(r.searchParams),async queryFn(){const t=await P({offset:r.searchParams.offset,limit:r.searchParams.limit});if(t.type==="error")throw t;return t.allImages}});return r.render(n)},L=240,Q=20,D=4,d=w(T),J=()=>{const r=p(),n=y(),t=d.useNavigate(),{page:o}=d.useSearch(),{containerRef:u,limit:i}=j({minItemWidth:L,gap:Q,rows:D}),h=I({mutationFn:R,onSuccess:a=>{if(a.type==="error")throw a;n.invalidateQueries({queryKey:m.images.listAll(),exact:!1})}}),f=async a=>{await r("Are you really sure?")&&h.mutate(a)};return e.jsx(E,{title:"Images",variant:"subtle",description:"Manage images uploaded to your notes",children:e.jsx("div",{ref:u,children:e.jsx(A,{fallback:e.jsxs("div",{className:"grid-auto-cards grid gap-4",children:[e.jsx(l,{height:"200px"}),e.jsx(l,{height:"200px"}),e.jsx(l,{height:"200px"})]}),errorTitle:"Failed to load images",errorDescription:"Retry loading uploaded image metadata.",resetKeys:[o,i],children:e.jsx(C,{searchParams:{offset:(o-1)*i,limit:i},render:({images:a,totalCount:c})=>a.length===0?e.jsx(N,{title:"There are no images",description:"Try drag and drop an image on the note editor."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"grid-auto-cards grid gap-4",children:a.map(s=>e.jsxs(b,{flush:!0,children:[e.jsx(M,{to:v,params:{id:s.id},className:"block overflow-hidden",children:e.jsx(_,{className:"h-48 w-full object-cover transition-transform duration-200 hover:scale-[1.02]",src:s.url,alt:s.id})}),e.jsxs("div",{className:"flex items-center justify-between border-t border-border-subtle px-3 py-2.5",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-sm font-medium text-fg-tertiary",children:[e.jsx(k,{className:"h-3.5 w-3.5"}),s.referenceCount]}),e.jsx(G,{variant:"ghost",size:"icon-sm",disabled:s.referenceCount>0,onClick:()=>f(s.id),children:e.jsx(q,{className:"h-4 w-4"})})]})]},s.id))}),c&&i<c&&e.jsx(S,{page:o,last:Math.ceil(c/i),onChange:s=>{t({search:g=>({...g,page:s})})}})]})})})})})};export{J as default};
@@ -1 +1 @@
1
- import{j as e}from"./note-vendor-BofYbzmZ.js";import{p as y,ag as b,L as f,N as C,w as E,ah as A,ae as w,z as v,A as I,u as h,q as d,ai as M,P as T,a7 as p,a as S,aj as Z,B as u,ak as _,e as D,af as F}from"./index-40Y2UsVr.js";import{I as R}from"./Image-B5R7gF2P.js";import{S as x}from"./SurfaceCard-yzVU4Qkx.js";import{a}from"./graph-vendor-CUxe67Lr.js";import{a as q,d as z}from"./image.api-DJgOBt8S.js";import{c as G,n as k}from"./Trash.es-B3KWD8_C.js";import{I as B}from"./Image.es-Dld9r9MJ.js";import"./note-core-BCgMq5QA.js";const O=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,36c-20.09,0-37.92,7.93-50,21.56C115.92,43.93,98.09,36,78,36a66.08,66.08,0,0,0-66,66c0,72.34,105.81,130.14,110.31,132.57a12,12,0,0,0,11.38,0C138.19,232.14,244,174.34,244,102A66.08,66.08,0,0,0,178,36Zm-5.49,142.36A328.69,328.69,0,0,1,128,210.16a328.69,328.69,0,0,1-44.51-31.8C61.82,159.77,36,131.42,36,102A42,42,0,0,1,78,60c17.8,0,32.7,9.4,38.89,24.54a12,12,0,0,0,22.22,0C145.3,69.4,160.2,60,178,60a42,42,0,0,1,42,42C220,131.42,194.18,159.77,172.51,178.36Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M232,102c0,66-104,122-104,122S24,168,24,102A54,54,0,0,1,78,48c22.59,0,41.94,12.31,50,32,8.06-19.69,27.41-32,50-32A54,54,0,0,1,232,102Z",opacity:"0.2"}),a.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M240,102c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,228.66,16,172,16,102A62.07,62.07,0,0,1,78,40c20.65,0,38.73,8.88,50,23.89C139.27,48.88,157.35,40,178,40A62.07,62.07,0,0,1,240,102Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,42c-21,0-39.26,9.47-50,25.34C117.26,51.47,99,42,78,42a60.07,60.07,0,0,0-60,60c0,29.2,18.2,59.59,54.1,90.31a334.68,334.68,0,0,0,53.06,37,6,6,0,0,0,5.68,0,334.68,334.68,0,0,0,53.06-37C219.8,161.59,238,131.2,238,102A60.07,60.07,0,0,0,178,42ZM128,217.11C111.59,207.64,30,157.72,30,102A48.05,48.05,0,0,1,78,54c20.28,0,37.31,10.83,44.45,28.27a6,6,0,0,0,11.1,0C140.69,64.83,157.72,54,178,54a48.05,48.05,0,0,1,48,48C226,157.72,144.41,207.64,128,217.11Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,44c-21.44,0-39.92,10.19-50,27.07C117.92,54.19,99.44,44,78,44a58.07,58.07,0,0,0-58,58c0,28.59,18,58.47,53.4,88.79a333.81,333.81,0,0,0,52.7,36.73,4,4,0,0,0,3.8,0,333.81,333.81,0,0,0,52.7-36.73C218,160.47,236,130.59,236,102A58.07,58.07,0,0,0,178,44ZM128,219.42c-14-8-100-59.35-100-117.42A50.06,50.06,0,0,1,78,52c21.11,0,38.85,11.31,46.3,29.51a4,4,0,0,0,7.4,0C139.15,63.31,156.89,52,178,52a50.06,50.06,0,0,1,50,50C228,160,142,211.46,128,219.42Z"}))]]),j=a.forwardRef((i,c)=>a.createElement(y,{ref:c,...i,weights:O}));j.displayName="HeartIcon";const L=j;function U({id:i,title:c,tags:t,createdAt:o,updatedAt:m}){const n=new Date(Number(o)),r=b(Number(m));return e.jsx("div",{className:"border-b-2 border-dashed border-border-subtle last:border-b-0",children:e.jsxs("div",{className:"py-4 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-fg-tertiary text-xs font-medium",children:r}),e.jsxs("span",{className:"text-fg-placeholder text-xs",children:["(",n.toDateString(),")"]})]}),e.jsx(f,{className:"font-bold text-fg-default hover:text-accent-primary transition-colors",to:C,params:{id:i},children:c||"Untitled"}),t&&t.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5",children:t.map(l=>e.jsx(f,{to:E,params:{id:l.id},search:{page:1},children:e.jsx(A,{name:l.name})},l.id))})]})})}const g=D(F),Y=()=>{const i=w(),c=v(),{id:t}=g.useParams(),o=g.useNavigate(),m=I(),{data:n}=h({queryKey:d.images.detail(t??""),async queryFn(){const s=await q(t);if(s.type==="error")throw s;return s.image},enabled:!!t}),{data:r}=h({queryKey:d.images.notes(t??""),async queryFn(){const s=await M(n.url);if(s.type==="error")throw s;return s.imageNotes},enabled:!!n}),l=!r||(r?.length||0)>0,N=async()=>{if(!l&&await i("Are you really sure?")){const s=await z(t);if(s.type==="error"){c(s.errors[0].message);return}if(!s.deleteImage){c("Failed to delete image");return}o({to:p,search:{page:1}})}};return e.jsxs(T,{title:"Image Detail",variant:"none",children:[e.jsxs(f,{to:p,search:{page:1},className:"mb-4 inline-flex items-center gap-1 text-sm font-medium text-fg-secondary transition-colors hover:text-fg-default",children:[e.jsx(S,{size:16}),"Back to Images"]}),e.jsxs("div",{className:"flex flex-col gap-6 lg:flex-row",children:[n&&e.jsx("div",{className:"w-full lg:w-[400px] lg:flex-shrink-0",children:e.jsxs(x,{className:"overflow-hidden p-0",children:[e.jsx("div",{className:"flex items-center justify-center bg-muted/20 p-4",children:e.jsx(R,{className:"max-h-80 w-auto max-w-full rounded-[14px] object-contain",src:n.url})}),e.jsxs("div",{className:"flex flex-col gap-3 border-t border-border-subtle p-4",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(G,{size:14,className:"text-fg-tertiary"}),e.jsxs("span",{className:"text-sm font-medium text-fg-secondary",children:[r?.length||0," ",(r?.length||0)===1?"reference":"references"]})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Z,{content:l?"Cannot delete while referenced by notes":"Delete this image",side:"bottom",children:e.jsxs(u,{variant:"soft-danger",size:"sm",className:"flex-1",disabled:l,onClick:N,children:[e.jsx(k,{size:16}),e.jsx("span",{children:"Delete"})]})}),e.jsxs(u,{variant:"primary",size:"sm",className:"flex-1",onClick:async()=>{await _("heroBanner",n.url),await m.invalidateQueries({queryKey:d.ui.heroBanner(),exact:!0})},children:[e.jsx(L,{size:16,className:"text-fg-secondary"}),e.jsx("span",{children:"Set hero banner"})]})]})]})]})}),e.jsx("div",{className:"flex-1 min-w-0",children:r&&r.length>0?e.jsxs(x,{className:"p-4",children:[e.jsx("p",{className:"mb-3 border-b border-border-subtle pb-2 text-sm font-semibold text-fg-default",children:"Referenced Notes"}),e.jsx("ul",{className:"flex flex-col",children:r.map(s=>e.jsx("li",{children:e.jsx(U,{...s})},s.id))})]}):e.jsxs(x,{className:"flex flex-col items-center justify-center p-6 text-center",children:[e.jsx(B,{size:28,className:"mb-2 text-fg-disabled"}),e.jsx("p",{className:"text-sm font-semibold text-fg-secondary",children:"No notes reference this image"}),e.jsx("p",{className:"mt-1 text-sm text-fg-secondary",children:"This image can be safely deleted"})]})})]})]})};export{Y as default};
1
+ import{j as e}from"./note-vendor-BofYbzmZ.js";import{p as b,ai as y,L as f,N as C,x as E,aj as A,ag as v,A as w,G as I,u as h,q as d,ak as M,P as T,a9 as u,b as S,al as Z,B as p,am as _,e as D,ah as F}from"./index-DqFkOWbi.js";import{I as R}from"./Image-ZxF459sC.js";import{S as x}from"./SurfaceCard-DAcVMY4f.js";import{a}from"./graph-vendor-CUxe67Lr.js";import{a as q,d as G}from"./image.api-CjJgNbC0.js";import{c as z,n as k}from"./Trash.es-DLiHgjNo.js";import{I as B}from"./Image.es-Dnn4SMzG.js";import"./note-core-BCgMq5QA.js";const O=new Map([["bold",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,36c-20.09,0-37.92,7.93-50,21.56C115.92,43.93,98.09,36,78,36a66.08,66.08,0,0,0-66,66c0,72.34,105.81,130.14,110.31,132.57a12,12,0,0,0,11.38,0C138.19,232.14,244,174.34,244,102A66.08,66.08,0,0,0,178,36Zm-5.49,142.36A328.69,328.69,0,0,1,128,210.16a328.69,328.69,0,0,1-44.51-31.8C61.82,159.77,36,131.42,36,102A42,42,0,0,1,78,60c17.8,0,32.7,9.4,38.89,24.54a12,12,0,0,0,22.22,0C145.3,69.4,160.2,60,178,60a42,42,0,0,1,42,42C220,131.42,194.18,159.77,172.51,178.36Z"}))],["duotone",a.createElement(a.Fragment,null,a.createElement("path",{d:"M232,102c0,66-104,122-104,122S24,168,24,102A54,54,0,0,1,78,48c22.59,0,41.94,12.31,50,32,8.06-19.69,27.41-32,50-32A54,54,0,0,1,232,102Z",opacity:"0.2"}),a.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["fill",a.createElement(a.Fragment,null,a.createElement("path",{d:"M240,102c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,228.66,16,172,16,102A62.07,62.07,0,0,1,78,40c20.65,0,38.73,8.88,50,23.89C139.27,48.88,157.35,40,178,40A62.07,62.07,0,0,1,240,102Z"}))],["light",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,42c-21,0-39.26,9.47-50,25.34C117.26,51.47,99,42,78,42a60.07,60.07,0,0,0-60,60c0,29.2,18.2,59.59,54.1,90.31a334.68,334.68,0,0,0,53.06,37,6,6,0,0,0,5.68,0,334.68,334.68,0,0,0,53.06-37C219.8,161.59,238,131.2,238,102A60.07,60.07,0,0,0,178,42ZM128,217.11C111.59,207.64,30,157.72,30,102A48.05,48.05,0,0,1,78,54c20.28,0,37.31,10.83,44.45,28.27a6,6,0,0,0,11.1,0C140.69,64.83,157.72,54,178,54a48.05,48.05,0,0,1,48,48C226,157.72,144.41,207.64,128,217.11Z"}))],["regular",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z"}))],["thin",a.createElement(a.Fragment,null,a.createElement("path",{d:"M178,44c-21.44,0-39.92,10.19-50,27.07C117.92,54.19,99.44,44,78,44a58.07,58.07,0,0,0-58,58c0,28.59,18,58.47,53.4,88.79a333.81,333.81,0,0,0,52.7,36.73,4,4,0,0,0,3.8,0,333.81,333.81,0,0,0,52.7-36.73C218,160.47,236,130.59,236,102A58.07,58.07,0,0,0,178,44ZM128,219.42c-14-8-100-59.35-100-117.42A50.06,50.06,0,0,1,78,52c21.11,0,38.85,11.31,46.3,29.51a4,4,0,0,0,7.4,0C139.15,63.31,156.89,52,178,52a50.06,50.06,0,0,1,50,50C228,160,142,211.46,128,219.42Z"}))]]),j=a.forwardRef((i,c)=>a.createElement(b,{ref:c,...i,weights:O}));j.displayName="HeartIcon";const L=j;function U({id:i,title:c,tags:s,createdAt:o,updatedAt:m}){const n=new Date(Number(o)),r=y(Number(m));return e.jsx("div",{className:"border-b-2 border-dashed border-border-subtle last:border-b-0",children:e.jsxs("div",{className:"py-4 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-fg-tertiary text-xs font-medium",children:r}),e.jsxs("span",{className:"text-fg-placeholder text-xs",children:["(",n.toDateString(),")"]})]}),e.jsx(f,{className:"font-bold text-fg-default hover:text-accent-primary transition-colors",to:C,params:{id:i},children:c||"Untitled"}),s&&s.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5",children:s.map(l=>e.jsx(f,{to:E,params:{id:l.id},search:{page:1},children:e.jsx(A,{name:l.name})},l.id))})]})})}const g=D(F),Y=()=>{const i=v(),c=w(),{id:s}=g.useParams(),o=g.useNavigate(),m=I(),{data:n}=h({queryKey:d.images.detail(s??""),async queryFn(){const t=await q(s);if(t.type==="error")throw t;return t.image},enabled:!!s}),{data:r}=h({queryKey:d.images.notes(s??""),async queryFn(){const t=await M(n.url);if(t.type==="error")throw t;return t.imageNotes},enabled:!!n}),l=!r||(r?.length||0)>0,N=async()=>{if(!l&&await i("Are you really sure?")){const t=await G(s);if(t.type==="error"){c(t.errors[0].message);return}if(!t.deleteImage){c("Failed to delete image");return}o({to:u,search:{page:1}})}};return e.jsxs(T,{title:"Image Detail",variant:"none",children:[e.jsxs(f,{to:u,search:{page:1},className:"mb-4 inline-flex items-center gap-1 text-sm font-medium text-fg-secondary transition-colors hover:text-fg-default",children:[e.jsx(S,{size:16}),"Back to Images"]}),e.jsxs("div",{className:"flex flex-col gap-6 lg:flex-row",children:[n&&e.jsx("div",{className:"w-full lg:w-[400px] lg:flex-shrink-0",children:e.jsxs(x,{flush:!0,children:[e.jsx("div",{className:"flex items-center justify-center bg-muted/20 p-4",children:e.jsx(R,{className:"max-h-80 w-auto max-w-full rounded-[14px] object-contain",src:n.url})}),e.jsxs("div",{className:"flex flex-col gap-3 border-t border-border-subtle p-4",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(z,{size:14,className:"text-fg-tertiary"}),e.jsxs("span",{className:"text-sm font-medium text-fg-secondary",children:[r?.length||0," ",(r?.length||0)===1?"reference":"references"]})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Z,{content:l?"Cannot delete while referenced by notes":"Delete this image",side:"bottom",children:e.jsxs(p,{variant:"soft-danger",size:"sm",className:"flex-1",disabled:l,onClick:N,children:[e.jsx(k,{size:16}),e.jsx("span",{children:"Delete"})]})}),e.jsxs(p,{variant:"primary",size:"sm",className:"flex-1",onClick:async()=>{await _("heroBanner",n.url),await m.invalidateQueries({queryKey:d.ui.heroBanner(),exact:!0})},children:[e.jsx(L,{size:16,className:"text-fg-secondary"}),e.jsx("span",{children:"Set hero banner"})]})]})]})]})}),e.jsx("div",{className:"flex-1 min-w-0",children:r&&r.length>0?e.jsxs(x,{children:[e.jsx("p",{className:"mb-3 border-b border-border-subtle pb-2 text-sm font-semibold text-fg-default",children:"Referenced Notes"}),e.jsx("ul",{className:"flex flex-col",children:r.map(t=>e.jsx("li",{children:e.jsx(U,{...t})},t.id))})]}):e.jsxs(x,{className:"flex flex-col items-center justify-center p-6 text-center",children:[e.jsx(B,{size:28,className:"mb-2 text-fg-disabled"}),e.jsx("p",{className:"text-sm font-semibold text-fg-secondary",children:"No notes reference this image"}),e.jsx("p",{className:"mt-1 text-sm text-fg-secondary",children:"This image can be safely deleted"})]})})]})]})};export{Y as default};
@@ -0,0 +1 @@
1
+ import{j as e}from"./note-vendor-BofYbzmZ.js";import{ac as r,A as j,G as N,u as M,I as i,P as C,ad as S,B as h,X as f,Z as w,Y as P}from"./index-DqFkOWbi.js";import{a as g}from"./graph-vendor-CUxe67Lr.js";import{S as c}from"./SurfaceCard-DAcVMY4f.js";import"./note-core-BCgMq5QA.js";const T=async()=>{const{data:s}=await r.get("/api/mcp-admin/status");return s},A=async s=>{const{data:a}=await r.post("/api/mcp-admin/enabled",{enabled:s});return a},F=async()=>{const{data:s}=await r.post("/api/mcp-admin/token/rotate");return s},q=async()=>{const{data:s}=await r.post("/api/mcp-admin/token/revoke");return s},n=["mcp-admin","status"],I=s=>JSON.stringify({mcpServers:{"ocean-brain":{command:"npx",args:["-y","ocean-brain","mcp","--server",s,"--token-file","/path/to/token.txt"]}}},null,2),L=s=>JSON.stringify({mcpServers:{"ocean-brain":{command:"npx",args:["-y","ocean-brain","mcp","--server",s,"--token","your-token-here"]}}},null,2),B=()=>{const s=j(),a=N(),[o,y]=g.useState(()=>window.location.origin),[l,d]=g.useState(""),{data:u,isLoading:v}=M({queryKey:n,queryFn:T}),m=i({mutationFn:A,onSuccess:t=>{a.setQueryData(n,t),s(t.enabled?"MCP access enabled.":"MCP access disabled.")}}),x=i({mutationFn:F,onSuccess:async({token:t})=>{d(t),s("A new MCP token has been issued."),await a.invalidateQueries({queryKey:n})}}),p=i({mutationFn:q,onSuccess:t=>{d(""),a.setQueryData(n,t),s("The active MCP token has been revoked.")}}),b=u?.enabled??!1,k=!v&&!m.isPending;return e.jsx(C,{title:"MCP",variant:"subtle",description:"Manage MCP access and issue a single service token",children:e.jsxs("div",{className:"grid grid-cols-1 gap-4",children:[e.jsx(c,{className:"space-y-4",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-subheading font-semibold text-fg-default",children:"MCP Access"}),e.jsx("p",{className:"text-label font-medium text-fg-tertiary",children:"Allow or block MCP requests at the server level."})]}),e.jsx("div",{className:"inline-flex items-center",children:e.jsx(S,{"aria-label":"Allow MCP access",checked:b,disabled:!k,onCheckedChange:()=>{m.mutate(!b)}})})]})}),e.jsxs(c,{className:"space-y-4",children:[e.jsxs("div",{className:"border-b border-border-subtle pb-4",children:[e.jsx("h2",{className:"text-subheading font-semibold text-fg-default",children:"Token Management"}),e.jsx("p",{className:"text-label font-medium text-fg-tertiary",children:"Ocean Brain supports one active MCP token at a time. Rotating immediately invalidates the previous one."})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(h,{onClick:()=>x.mutate(void 0),isLoading:x.isPending,children:"Rotate token"}),e.jsx(h,{variant:"soft-danger",onClick:()=>p.mutate(),isLoading:p.isPending,disabled:!u?.hasActiveToken,children:"Revoke token"})]}),l&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"issued-mcp-token",children:"Issued Token"}),e.jsx(w,{id:"issued-mcp-token",rows:3,readOnly:!0,value:l})]})]}),e.jsxs(c,{className:"space-y-4",children:[e.jsxs("div",{className:"border-b border-border-subtle pb-4",children:[e.jsx("h2",{className:"text-subheading font-semibold text-fg-default",children:"Connection Guide"}),e.jsx("p",{className:"text-label font-medium text-fg-tertiary",children:"How to connect your MCP client to this server."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(f,{htmlFor:"mcp-server-url",children:"Server URL"}),e.jsx(P,{id:"mcp-server-url",value:o,onChange:t=>y(t.target.value)})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"text-body font-semibold text-fg-default",children:["Token file"," ",e.jsx("span",{className:"text-label font-medium text-fg-tertiary",children:"(recommended — keeps token out of config)"})]}),e.jsx("pre",{className:"overflow-x-auto rounded-[14px] border border-border-subtle bg-surface px-4 py-3 text-xs text-fg-secondary",children:I(o)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"text-body font-semibold text-fg-default",children:["Inline token"," ",e.jsx("span",{className:"text-label font-medium text-fg-tertiary",children:"(quick local testing)"})]}),e.jsx("pre",{className:"overflow-x-auto rounded-[14px] border border-border-subtle bg-surface px-4 py-3 text-xs text-fg-secondary",children:L(o)})]})]})]})]})})};export{B as default};
@@ -0,0 +1,34 @@
1
+ import{j as e}from"./note-vendor-BofYbzmZ.js";import{p as D,g as y,A as I,G as O,q as x,an as $,u as H,I as P,P as q,B as f,_ as Z,ao as F,ap as v,o as k,M as p,X as g,Y as j,F as Q,f as T,e as K,aa as B}from"./index-DqFkOWbi.js";import{a as t}from"./graph-vendor-CUxe67Lr.js";import{C as U}from"./Callout-tNHgPhLM.js";import{n as X,M as G}from"./ModalActionRow-B3vNjcDc.js";import{S as C}from"./SurfaceCard-DAcVMY4f.js";import"./note-core-BCgMq5QA.js";const Y=new Map([["bold",t.createElement(t.Fragment,null,t.createElement("path",{d:"M216.49,168.49a12,12,0,0,1-17,0L128,97,56.49,168.49a12,12,0,0,1-17-17l80-80a12,12,0,0,1,17,0l80,80A12,12,0,0,1,216.49,168.49Z"}))],["duotone",t.createElement(t.Fragment,null,t.createElement("path",{d:"M208,160H48l80-80Z",opacity:"0.2"}),t.createElement("path",{d:"M213.66,154.34l-80-80a8,8,0,0,0-11.32,0l-80,80A8,8,0,0,0,48,168H208a8,8,0,0,0,5.66-13.66ZM67.31,152,128,91.31,188.69,152Z"}))],["fill",t.createElement(t.Fragment,null,t.createElement("path",{d:"M215.39,163.06A8,8,0,0,1,208,168H48a8,8,0,0,1-5.66-13.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,215.39,163.06Z"}))],["light",t.createElement(t.Fragment,null,t.createElement("path",{d:"M212.24,164.24a6,6,0,0,1-8.48,0L128,88.49,52.24,164.24a6,6,0,0,1-8.48-8.48l80-80a6,6,0,0,1,8.48,0l80,80A6,6,0,0,1,212.24,164.24Z"}))],["regular",t.createElement(t.Fragment,null,t.createElement("path",{d:"M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z"}))],["thin",t.createElement(t.Fragment,null,t.createElement("path",{d:"M210.83,162.83a4,4,0,0,1-5.66,0L128,85.66,50.83,162.83a4,4,0,0,1-5.66-5.66l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,210.83,162.83Z"}))]]),A=t.forwardRef((l,r)=>t.createElement(D,{ref:r,...l,weights:Y}));A.displayName="CaretUpIcon";const z=A,S=["id","name","template","replacement","createdAt","updatedAt"],J=new Set(S),V=`query FetchPlaceholders(
2
+ $searchFilter: SearchFilterInput,
3
+ $pagination: PaginationInput
4
+ ) {
5
+ allPlaceholders(
6
+ searchFilter: $searchFilter,
7
+ pagination: $pagination
8
+ ) {
9
+ totalCount
10
+ placeholders {
11
+ __PLACEHOLDER_FIELDS__ }
12
+ }
13
+ }`,W=l=>{const r=l&&l.length>0?l.filter(n=>J.has(n)):S;return Array.from(new Set(r)).map(n=>" "+n).join(`
14
+ `)+`
15
+ `},ee=async({limit:l=25,offset:r=0,query:d="",fields:n}={})=>{const h=W(n),c=V.replace("__PLACEHOLDER_FIELDS__",h);return y(c,{searchFilter:{query:d},pagination:{limit:l,offset:r}})},te=l=>y(`mutation CreatePlaceholder(
16
+ $name: String!,
17
+ $template: String!,
18
+ $replacement: String!
19
+ ) {
20
+ createPlaceholder(
21
+ name: $name,
22
+ template: $template,
23
+ replacement: $replacement
24
+ ) {
25
+ id
26
+ name
27
+ template
28
+ replacement
29
+ createdAt
30
+ updatedAt
31
+ }
32
+ }`,l),ae=l=>y(`mutation DeletePlaceholder($id: ID!) {
33
+ deletePlaceholder(id: $id)
34
+ }`,{id:l}),L=K(B),de=()=>{const l=I(),r=O(),d=L.useNavigate(),{page:n}=L.useSearch(),[h,c]=t.useState(!1),[u,b]=t.useState(!1),[s,m]=t.useState({name:"",template:"",replacement:""}),i=25,_=x.placeholders.list({limit:i,offset:(n-1)*i}),[w]=t.useState($),{data:o,isLoading:N}=H({queryKey:_,queryFn:async()=>{const a=await ee({offset:(n-1)*i,limit:i});if(a.type==="error")throw a;return a.allPlaceholders}}),E=P({mutationFn:te,onSuccess:async()=>{l("Placeholder added successfully"),c(!1),m({name:"",template:"",replacement:""}),await r.invalidateQueries({queryKey:x.placeholders.listAll(),exact:!1})}}),M=P({mutationFn:ae,onSuccess:async()=>{l("Placeholder deleted successfully"),await r.invalidateQueries({queryKey:x.placeholders.listAll(),exact:!1})}});return e.jsxs(q,{title:"Placeholders",variant:"subtle",description:"Manage template variables for note cloning",children:[e.jsx(U,{className:"mb-4",children:e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{children:"Placeholders will be replaced with new note data during cloning."}),e.jsx(f,{variant:"subtle",size:"icon-sm",onClick:()=>c(!0),children:e.jsx(X,{width:20,height:20})})]})}),e.jsxs("div",{className:"mt-3 flex flex-col gap-3",children:[e.jsxs("button",{type:"button",onClick:()=>b(!u),className:"focus-ring-soft surface-base flex items-center justify-between gap-2 rounded-[18px] px-4 py-3 text-left text-sm font-semibold text-fg-default transition-colors hover:bg-hover-subtle",children:[e.jsx("div",{children:"System Placeholders"}),e.jsx("div",{className:"flex h-6 w-6 items-center justify-center text-fg-tertiary",children:u?e.jsx(z,{}):e.jsx(Z,{})})]}),u&&e.jsx("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3",children:w.map(a=>e.jsxs(C,{children:[e.jsx("div",{className:"text-sm font-semibold text-fg-default",children:a.name}),e.jsxs("div",{className:"text-xs font-medium text-fg-tertiary",children:[F,a.template,v," = '",a.replacement,"'"]})]},a.name))}),!N&&o?.placeholders&&o.placeholders.length>0&&e.jsx("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3",children:o.placeholders.map(a=>e.jsxs(C,{className:"relative",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-semibold text-fg-default",children:a.name}),e.jsx("button",{type:"button",className:"focus-ring-soft inline-flex h-8 w-8 items-center justify-center rounded-[10px] text-fg-tertiary transition-colors hover:bg-hover-subtle hover:text-fg-default",onClick:()=>M.mutate(a.id.toString()),children:e.jsx(k,{})})]}),e.jsxs("div",{className:"text-xs font-medium text-fg-tertiary",children:[F,a.template,v," = '",a.replacement,"'"]})]},a.id))})]}),e.jsxs(p,{isOpen:h,onClose:()=>c(!1),children:[e.jsx(p.Header,{title:"Add Placeholder",onClose:()=>c(!1)}),e.jsx(p.Body,{children:e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx(g,{htmlFor:"name",children:"Name:"}),e.jsx(j,{id:"name",type:"text",value:s.name,onChange:a=>m({...s,name:a.target.value}),placeholder:"Description of this placeholder"}),e.jsx(g,{htmlFor:"template",children:"Placeholder:"}),e.jsx(j,{id:"template",type:"text",value:s.template,onChange:a=>m({...s,template:a.target.value}),placeholder:"note_app"}),e.jsx(g,{htmlFor:"replacement",children:"Replacement:"}),e.jsx(j,{id:"replacement",type:"text",value:s.replacement,onChange:a=>m({...s,replacement:a.target.value}),placeholder:"Ocean Brain"})]})}),e.jsx(p.Footer,{children:e.jsxs(G,{children:[e.jsx(f,{variant:"ghost",onClick:()=>c(!1),children:"Cancel"}),e.jsx(f,{variant:"primary",isLoading:E.isPending,onClick:()=>{if(!s.name||!s.template||!s.replacement){l("All fields are required");return}E.mutate({name:s.name,template:s.template,replacement:s.replacement})},children:"Add"})]})})]}),e.jsx(Q,{fallback:null,children:o?.totalCount&&i<o.totalCount&&e.jsx(T,{page:n,last:Math.ceil(o.totalCount/i),onChange:a=>{d({search:R=>({...R,page:a})})}})})]})};export{de as default};
@@ -0,0 +1 @@
1
+ import{j as e}from"./note-vendor-BofYbzmZ.js";import{P as x,Q as p,S as d,e as f,a3 as y,G as g,A as j,k as b,ae as v,q as i,I as N,af as T,N as S,F as q,a4 as E,B as R,f as Q,E as w,d as C}from"./index-DqFkOWbi.js";import"./graph-vendor-CUxe67Lr.js";import{S as K}from"./SurfaceCard-DAcVMY4f.js";import"./note-core-BCgMq5QA.js";const a=25,c=f(y),m=t=>C(t).format("YYYY-MM-DD HH:mm"),k=()=>{const{page:t}=c.useSearch(),u=c.useNavigate(),r=g(),h=j(),{data:l}=b({queryKey:i.notes.trash({limit:a,offset:(t-1)*a}),queryFn:async()=>{const s=await v({limit:a,offset:(t-1)*a});if(s.type==="error")throw s;return s.trashedNotes}}),o=N({mutationFn:T,onSuccess:async s=>{if(s.type==="error")throw s;await Promise.all([r.invalidateQueries({queryKey:i.notes.all(),exact:!1}),r.invalidateQueries({queryKey:i.tags.all(),exact:!1}),r.invalidateQueries({queryKey:i.reminders.all(),exact:!1}),r.invalidateQueries({queryKey:i.images.all(),exact:!1}),r.invalidateQueries({queryKey:["calendar"],exact:!1})]),h("The note has been restored."),u({to:S,params:{id:s.restoreTrashedNote.id}})},onError:()=>{h("Failed to restore the note.")}});return e.jsx(q,{fallback:e.jsx(w,{title:"Trash is empty",description:"Deleted notes stay here until you restore them or retention cleanup removes them."}),children:l.notes.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"grid gap-4",children:l.notes.map(s=>e.jsx(K,{children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-subheading font-semibold text-fg-default",children:s.title}),s.pinned&&e.jsxs("span",{className:"text-label inline-flex items-center gap-1 rounded-full border border-border-subtle bg-hover-subtle px-2 py-0.5 font-medium text-fg-secondary",children:[e.jsx(E,{className:"h-3.5 w-3.5"}),"Pinned"]})]}),e.jsxs("div",{className:"text-meta text-fg-secondary",children:["Deleted ",m(s.deletedAt)]}),e.jsxs("div",{className:"text-label text-fg-tertiary",children:["Last edited ",m(s.updatedAt)]}),s.tagNames.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2",children:s.tagNames.map(n=>e.jsx("span",{className:"text-label rounded-full border border-border-subtle bg-hover-subtle px-2 py-0.5 font-medium text-fg-secondary",children:n},`${s.id}-${n}`))})]}),e.jsx(R,{variant:"subtle",isLoading:o.isPending&&o.variables===s.id,onClick:()=>o.mutate(s.id),children:"Restore"})]})},s.id))}),l.totalCount>a&&e.jsx(Q,{page:t,last:Math.ceil(l.totalCount/a),onChange:s=>{u({search:n=>({...n,page:s})})}})]})})},Y=()=>{const{page:t}=c.useSearch();return e.jsx(x,{title:"Trash",variant:"subtle",description:"Restore notes removed from your active workspace before retention cleanup clears them",children:e.jsx(p,{fallback:e.jsxs("div",{className:"grid gap-4",children:[e.jsx(d,{height:"128px"}),e.jsx(d,{height:"128px"}),e.jsx(d,{height:"128px"})]}),errorTitle:"Failed to load trash",errorDescription:"Retry loading deleted notes.",resetKeys:[t],children:e.jsx(k,{})})})};export{Y as default};
@@ -0,0 +1,82 @@
1
+ import{a as n}from"./graph-vendor-CUxe67Lr.js";import{p as f,g as c,k as R,q as a,A as V,G as $}from"./index-DqFkOWbi.js";import{j as y}from"./note-vendor-BofYbzmZ.js";const h=new Map([["bold",n.createElement(n.Fragment,null,n.createElement("path",{d:"M216.49,79.52l-56-56A12,12,0,0,0,152,20H56A20,20,0,0,0,36,40V216a20,20,0,0,0,20,20H200a20,20,0,0,0,20-20V88A12,12,0,0,0,216.49,79.52ZM160,57l23,23H160ZM60,212V44h76V92a12,12,0,0,0,12,12h48V212Z"}))],["duotone",n.createElement(n.Fragment,null,n.createElement("path",{d:"M208,88H152V32Z",opacity:"0.2"}),n.createElement("path",{d:"M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Z"}))],["fill",n.createElement(n.Fragment,null,n.createElement("path",{d:"M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM152,88V44l44,44Z"}))],["light",n.createElement(n.Fragment,null,n.createElement("path",{d:"M212.24,83.76l-56-56A6,6,0,0,0,152,26H56A14,14,0,0,0,42,40V216a14,14,0,0,0,14,14H200a14,14,0,0,0,14-14V88A6,6,0,0,0,212.24,83.76ZM158,46.48,193.52,82H158ZM200,218H56a2,2,0,0,1-2-2V40a2,2,0,0,1,2-2h90V88a6,6,0,0,0,6,6h50V216A2,2,0,0,1,200,218Z"}))],["regular",n.createElement(n.Fragment,null,n.createElement("path",{d:"M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Z"}))],["thin",n.createElement(n.Fragment,null,n.createElement("path",{d:"M210.83,85.17l-56-56A4,4,0,0,0,152,28H56A12,12,0,0,0,44,40V216a12,12,0,0,0,12,12H200a12,12,0,0,0,12-12V88A4,4,0,0,0,210.83,85.17ZM156,41.65,198.34,84H156ZM200,220H56a4,4,0,0,1-4-4V40a4,4,0,0,1,4-4h92V88a4,4,0,0,0,4,4h52V216A4,4,0,0,1,200,220Z"}))]]),g=n.forwardRef((e,t)=>n.createElement(f,{ref:t,...e,weights:h}));g.displayName="FileIcon";const w=g,A=(e={})=>({limit:e.limit??10,offset:e.offset??0}),H=async(e,t)=>c(`
2
+ query FetchNoteReminders($noteId: ID!, $pagination: PaginationInput) {
3
+ noteReminders(noteId: $noteId, pagination: $pagination) {
4
+ totalCount
5
+ reminders {
6
+ id
7
+ noteId
8
+ reminderDate
9
+ priority
10
+ content
11
+ completed
12
+ createdAt
13
+ updatedAt
14
+ }
15
+ }
16
+ }
17
+ `,{noteId:e,pagination:A(t)}),D=async e=>c(`
18
+ query FetchUpcomingReminders($pagination: PaginationInput) {
19
+ upcomingReminders(pagination: $pagination) {
20
+ totalCount
21
+ reminders {
22
+ id
23
+ noteId
24
+ reminderDate
25
+ priority
26
+ content
27
+ completed
28
+ createdAt
29
+ updatedAt
30
+ note {
31
+ id
32
+ title
33
+ }
34
+ }
35
+ }
36
+ }
37
+ `,{pagination:A(e)}),M=async e=>{const{noteId:t,reminderDate:o,priority:s="medium",content:i}=e;return c(`
38
+ mutation CreateReminder($noteId: ID!, $reminderDate: String!, $priority: ReminderPriority, $content: String) {
39
+ createReminder(
40
+ noteId: $noteId,
41
+ reminderDate: $reminderDate,
42
+ priority: $priority,
43
+ content: $content
44
+ ) {
45
+ id
46
+ noteId
47
+ reminderDate
48
+ completed
49
+ priority
50
+ createdAt
51
+ updatedAt
52
+ }
53
+ }
54
+ `,{noteId:t,reminderDate:o.toISOString(),priority:s,content:i})},Z=async({id:e,reminderDate:t,completed:o,priority:s,content:i})=>{const r={id:e};return t&&(r.reminderDate=t.toISOString()),o!==void 0&&(r.completed=o),s&&(r.priority=s),i!==void 0&&(r.content=i),c(`
55
+ mutation UpdateReminder(
56
+ $id: ID!,
57
+ $reminderDate: String,
58
+ $completed: Boolean,
59
+ $priority: ReminderPriority,
60
+ $content: String
61
+ ) {
62
+ updateReminder(
63
+ id: $id,
64
+ reminderDate: $reminderDate,
65
+ completed: $completed,
66
+ priority: $priority,
67
+ content: $content
68
+ ) {
69
+ id
70
+ noteId
71
+ reminderDate
72
+ completed
73
+ priority
74
+ createdAt
75
+ updatedAt
76
+ }
77
+ }
78
+ `,r)},I=async e=>c(`
79
+ mutation DeleteReminder($id: ID!) {
80
+ deleteReminder(id: $id)
81
+ }
82
+ `,{id:e});function v({noteId:e,searchParams:t,render:o}){const{data:s}=R({queryKey:e?a.reminders.note(e,t):a.reminders.upcoming(t),queryFn:async()=>{if(e){const r=await H(e,t);if(r.type==="error")throw r;return r.noteReminders}const i=await D(t);if(i.type==="error")throw i;return i.upcomingReminders}});return y.jsx(y.Fragment,{children:o(s)})}function Q(){const e=V(),t=$(),o=n.useCallback(async(r,m,l="medium",d,u)=>{const p=await M({noteId:r,reminderDate:m,priority:l,content:u});if(p.type==="error"){e(p.errors[0].message);return}await Promise.all([t.invalidateQueries({queryKey:a.reminders.noteAllPages(r),exact:!1}),t.invalidateQueries({queryKey:a.reminders.upcomingAllPages(),exact:!1}),t.invalidateQueries({queryKey:a.reminders.inDateRangeAll(),exact:!1})]),d&&d()},[t,e]),s=n.useCallback(async(r,m,l,d)=>{const u=await Z({id:r,...l});if(u.type==="error"){e(u.errors[0].message);return}await Promise.all([t.invalidateQueries({queryKey:a.reminders.noteAllPages(m),exact:!1}),t.invalidateQueries({queryKey:a.reminders.upcomingAllPages(),exact:!1}),t.invalidateQueries({queryKey:a.reminders.inDateRangeAll(),exact:!1})]),d&&d()},[t,e]),i=n.useCallback(async(r,m,l)=>{const d=await I(r);if(d.type==="error"){e(d.errors[0].message);return}await Promise.all([t.invalidateQueries({queryKey:a.reminders.noteAllPages(m),exact:!1}),t.invalidateQueries({queryKey:a.reminders.upcomingAllPages(),exact:!1}),t.invalidateQueries({queryKey:a.reminders.inDateRangeAll(),exact:!1})]),l&&l()},[t,e]);return{onCreate:o,onUpdate:s,onDelete:i}}export{v as R,w as s,Q as u};
@@ -6,11 +6,11 @@
6
6
  <link rel="icon" type="image/png" href="/icon.png" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>Ocean Brain</title>
9
- <script type="module" crossorigin src="/assets/index-40Y2UsVr.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-DqFkOWbi.js"></script>
10
10
  <link rel="modulepreload" crossorigin href="/assets/graph-vendor-CUxe67Lr.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/note-core-BCgMq5QA.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/note-vendor-BofYbzmZ.js">
13
- <link rel="stylesheet" crossorigin href="/assets/index-BnxpTwtL.css">
13
+ <link rel="stylesheet" crossorigin href="/assets/index-DAZMX8bQ.css">
14
14
  </head>
15
15
 
16
16
  <body>
@@ -1,4 +1,33 @@
1
1
  import { ServerBlockNoteEditor } from "@blocknote/server-util";
2
+ import models from "../models.js";
3
+ import { ensureTagByName } from "./tag-organization.js";
4
+ const UNSUPPORTED_MARKDOWN_BLOCK_TYPES = /* @__PURE__ */ new Set([
5
+ "tableOfContents"
6
+ ]);
7
+ const defaultMarkdownImportDeps = {
8
+ ensureTag: async (name) => ensureTagByName(name),
9
+ findNotesByTitle: async (title) => {
10
+ const notes = await models.note.findMany({
11
+ select: {
12
+ id: true,
13
+ title: true
14
+ },
15
+ where: { title },
16
+ orderBy: { createdAt: "asc" },
17
+ take: 2
18
+ });
19
+ return notes.map((note) => ({
20
+ id: String(note.id),
21
+ title: note.title
22
+ }));
23
+ }
24
+ };
25
+ function stripUnsupportedMarkdownBlocks(blocks) {
26
+ return blocks.filter((block) => !UNSUPPORTED_MARKDOWN_BLOCK_TYPES.has(block.type)).map((block) => ({
27
+ ...block,
28
+ children: block.children?.length ? stripUnsupportedMarkdownBlocks(block.children) : []
29
+ }));
30
+ }
2
31
  function preprocessCustomInlineContent(blocks) {
3
32
  return blocks.map((block) => ({
4
33
  ...block,
@@ -23,6 +52,116 @@ function preprocessCustomInlineContent(blocks) {
23
52
  children: block.children?.length ? preprocessCustomInlineContent(block.children) : []
24
53
  }));
25
54
  }
55
+ function createTextInline(text, styles = {}) {
56
+ return {
57
+ type: "text",
58
+ text,
59
+ styles
60
+ };
61
+ }
62
+ function appendInline(target, inline) {
63
+ const previous = target.at(-1);
64
+ if (previous?.type === "text" && inline.type === "text" && previous.text !== void 0 && inline.text !== void 0 && JSON.stringify(previous.styles ?? {}) === JSON.stringify(inline.styles ?? {})) {
65
+ previous.text += inline.text;
66
+ return;
67
+ }
68
+ target.push(inline);
69
+ }
70
+ async function restoreCustomInlineContent(blocks, deps) {
71
+ const tagCache = /* @__PURE__ */ new Map();
72
+ const noteCache = /* @__PURE__ */ new Map();
73
+ const getTag = (token) => {
74
+ let existing = tagCache.get(token);
75
+ if (!existing) {
76
+ existing = deps.ensureTag(token.slice(1)).then((result) => ({
77
+ id: "tag" in result ? result.tag.id : result.id,
78
+ tag: "tag" in result ? result.tag.name : result.name
79
+ }));
80
+ tagCache.set(token, existing);
81
+ }
82
+ return existing;
83
+ };
84
+ const getNotesByTitle = (title) => {
85
+ let existing = noteCache.get(title);
86
+ if (!existing) {
87
+ existing = deps.findNotesByTitle(title);
88
+ noteCache.set(title, existing);
89
+ }
90
+ return existing;
91
+ };
92
+ const restoreTextInline = async (inline) => {
93
+ if (inline.type !== "text" || typeof inline.text !== "string" || !inline.text || inline.styles?.code === true) {
94
+ return [inline];
95
+ }
96
+ const restored = [];
97
+ const styles = inline.styles ?? {};
98
+ let cursor = 0;
99
+ while (cursor < inline.text.length) {
100
+ if (inline.text.startsWith("[[", cursor)) {
101
+ const closeIndex = inline.text.indexOf("]]", cursor + 2);
102
+ if (closeIndex !== -1) {
103
+ const title = inline.text.slice(cursor + 2, closeIndex);
104
+ const matchingNotes = await getNotesByTitle(title);
105
+ if (matchingNotes.length === 1) {
106
+ appendInline(restored, {
107
+ type: "reference",
108
+ props: {
109
+ id: matchingNotes[0].id,
110
+ title: matchingNotes[0].title
111
+ }
112
+ });
113
+ cursor = closeIndex + 2;
114
+ continue;
115
+ }
116
+ }
117
+ }
118
+ if (inline.text[cursor] === "#" && (cursor === 0 || /\s/.test(inline.text[cursor - 1]))) {
119
+ const remainder = inline.text.slice(cursor);
120
+ const tagMatch = remainder.match(/^#[^\s[\]]+/);
121
+ if (tagMatch) {
122
+ const tag = await getTag(tagMatch[0]);
123
+ appendInline(restored, {
124
+ type: "tag",
125
+ props: tag
126
+ });
127
+ cursor += tagMatch[0].length;
128
+ continue;
129
+ }
130
+ }
131
+ let nextCursor = cursor + 1;
132
+ while (nextCursor < inline.text.length && !inline.text.startsWith("[[", nextCursor) && !(inline.text[nextCursor] === "#" && /\s/.test(inline.text[nextCursor - 1] ?? ""))) {
133
+ nextCursor += 1;
134
+ }
135
+ appendInline(restored, createTextInline(inline.text.slice(cursor, nextCursor), styles));
136
+ cursor = nextCursor;
137
+ }
138
+ return restored;
139
+ };
140
+ return Promise.all(
141
+ blocks.map(async (block) => ({
142
+ ...block,
143
+ content: block.content ? (await Promise.all(block.content.map((inline) => restoreTextInline(inline)))).flat() : void 0,
144
+ children: block.children?.length ? await restoreCustomInlineContent(block.children, deps) : []
145
+ }))
146
+ );
147
+ }
148
+ function collectTagIds(blocks) {
149
+ const tagIds = /* @__PURE__ */ new Set();
150
+ const visit = (items) => {
151
+ for (const block of items) {
152
+ for (const inline of block.content ?? []) {
153
+ if (inline.type === "tag" && typeof inline.props?.id === "string") {
154
+ tagIds.add(inline.props.id);
155
+ }
156
+ }
157
+ if (block.children?.length) {
158
+ visit(block.children);
159
+ }
160
+ }
161
+ };
162
+ visit(blocks);
163
+ return [...tagIds];
164
+ }
26
165
  let editorInstance = null;
27
166
  function getEditor() {
28
167
  if (!editorInstance) {
@@ -33,20 +172,27 @@ function getEditor() {
33
172
  async function blocksToMarkdown(contentJson) {
34
173
  try {
35
174
  const blocks = JSON.parse(contentJson);
36
- const processed = preprocessCustomInlineContent(blocks);
175
+ const supportedBlocks = stripUnsupportedMarkdownBlocks(blocks);
176
+ const processed = preprocessCustomInlineContent(supportedBlocks);
37
177
  const editor = getEditor();
38
178
  return await editor.blocksToMarkdownLossy(processed);
39
179
  } catch {
40
180
  return "";
41
181
  }
42
182
  }
43
- async function markdownToBlocksJson(markdown) {
183
+ async function markdownToBlocksJson(markdown, deps = defaultMarkdownImportDeps) {
44
184
  const editor = getEditor();
45
185
  const blocks = await editor.tryParseMarkdownToBlocks(markdown);
46
- return JSON.stringify(blocks);
186
+ const restoredBlocks = await restoreCustomInlineContent(blocks, deps);
187
+ return JSON.stringify(restoredBlocks);
188
+ }
189
+ function extractTagIdsFromContentJson(contentJson) {
190
+ const blocks = JSON.parse(contentJson);
191
+ return collectTagIds(blocks);
47
192
  }
48
193
  export {
49
194
  blocksToMarkdown,
195
+ extractTagIdsFromContentJson,
50
196
  markdownToBlocksJson
51
197
  };
52
198
  //# sourceMappingURL=blocknote.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/modules/blocknote.ts"],"sourcesContent":["import { ServerBlockNoteEditor } from '@blocknote/server-util';\n\ninterface BlockNote {\n id?: string;\n type: string;\n props?: Record<string, unknown>;\n content?: BlockNote[];\n children?: BlockNote[];\n text?: string;\n styles?: Record<string, unknown>;\n}\n\nfunction preprocessCustomInlineContent(blocks: BlockNote[]): BlockNote[] {\n return blocks.map((block) => ({\n ...block,\n content: block.content?.map((inline) => {\n if (inline.type === 'reference') {\n return {\n type: 'text',\n text: `[[${inline.props?.title || inline.props?.id || ''}]]`,\n styles: {}\n };\n }\n if (inline.type === 'tag') {\n const tag = (inline.props?.tag as string)?.replace(/^@/, '') || '';\n return {\n type: 'text',\n text: `#${tag}`,\n styles: {}\n };\n }\n return inline;\n }),\n children: block.children?.length\n ? preprocessCustomInlineContent(block.children)\n : []\n }));\n}\n\nlet editorInstance: ServerBlockNoteEditor | null = null;\n\nfunction getEditor(): ServerBlockNoteEditor {\n if (!editorInstance) {\n editorInstance = ServerBlockNoteEditor.create();\n }\n return editorInstance;\n}\n\nexport async function blocksToMarkdown(contentJson: string): Promise<string> {\n try {\n const blocks = JSON.parse(contentJson);\n const processed = preprocessCustomInlineContent(blocks);\n const editor = getEditor();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return await editor.blocksToMarkdownLossy(processed as any);\n } catch {\n return '';\n }\n}\n\nexport async function markdownToBlocksJson(markdown: string): Promise<string> {\n const editor = getEditor();\n const blocks = await editor.tryParseMarkdownToBlocks(markdown);\n return JSON.stringify(blocks);\n}\n"],"mappings":"AAAA,SAAS,6BAA6B;AAYtC,SAAS,8BAA8B,QAAkC;AACrE,SAAO,OAAO,IAAI,CAAC,WAAW;AAAA,IAC1B,GAAG;AAAA,IACH,SAAS,MAAM,SAAS,IAAI,CAAC,WAAW;AACpC,UAAI,OAAO,SAAS,aAAa;AAC7B,eAAO;AAAA,UACH,MAAM;AAAA,UACN,MAAM,KAAK,OAAO,OAAO,SAAS,OAAO,OAAO,MAAM,EAAE;AAAA,UACxD,QAAQ,CAAC;AAAA,QACb;AAAA,MACJ;AACA,UAAI,OAAO,SAAS,OAAO;AACvB,cAAM,MAAO,OAAO,OAAO,KAAgB,QAAQ,MAAM,EAAE,KAAK;AAChE,eAAO;AAAA,UACH,MAAM;AAAA,UACN,MAAM,IAAI,GAAG;AAAA,UACb,QAAQ,CAAC;AAAA,QACb;AAAA,MACJ;AACA,aAAO;AAAA,IACX,CAAC;AAAA,IACD,UAAU,MAAM,UAAU,SACpB,8BAA8B,MAAM,QAAQ,IAC5C,CAAC;AAAA,EACX,EAAE;AACN;AAEA,IAAI,iBAA+C;AAEnD,SAAS,YAAmC;AACxC,MAAI,CAAC,gBAAgB;AACjB,qBAAiB,sBAAsB,OAAO;AAAA,EAClD;AACA,SAAO;AACX;AAEA,eAAsB,iBAAiB,aAAsC;AACzE,MAAI;AACA,UAAM,SAAS,KAAK,MAAM,WAAW;AACrC,UAAM,YAAY,8BAA8B,MAAM;AACtD,UAAM,SAAS,UAAU;AAEzB,WAAO,MAAM,OAAO,sBAAsB,SAAgB;AAAA,EAC9D,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAEA,eAAsB,qBAAqB,UAAmC;AAC1E,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,MAAM,OAAO,yBAAyB,QAAQ;AAC7D,SAAO,KAAK,UAAU,MAAM;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../src/modules/blocknote.ts"],"sourcesContent":["import { ServerBlockNoteEditor } from '@blocknote/server-util';\n\nimport models from '~/models.js';\nimport { ensureTagByName } from './tag-organization.js';\n\ninterface BlockNote {\n id?: string;\n type: string;\n props?: Record<string, unknown>;\n content?: BlockNoteInline[];\n children?: BlockNote[];\n text?: string;\n styles?: Record<string, unknown>;\n}\n\ninterface BlockNoteInline {\n type: string;\n props?: Record<string, unknown>;\n text?: string;\n styles?: Record<string, unknown>;\n}\n\ninterface MarkdownImportDeps {\n ensureTag: (name: string) => Promise<\n | {\n id: string;\n name: string;\n }\n | {\n tag: {\n id: string;\n name: string;\n };\n }\n >;\n findNotesByTitle: (title: string) => Promise<Array<{\n id: string;\n title: string;\n }>>;\n}\n\nconst UNSUPPORTED_MARKDOWN_BLOCK_TYPES = new Set([\n 'tableOfContents'\n]);\n\nconst defaultMarkdownImportDeps: MarkdownImportDeps = {\n ensureTag: async (name) => ensureTagByName(name),\n findNotesByTitle: async (title) => {\n const notes = await models.note.findMany({\n select: {\n id: true,\n title: true\n },\n where: { title },\n orderBy: { createdAt: 'asc' },\n take: 2\n });\n\n return notes.map((note) => ({\n id: String(note.id),\n title: note.title\n }));\n }\n};\n\nfunction stripUnsupportedMarkdownBlocks(blocks: BlockNote[]): BlockNote[] {\n return blocks\n .filter((block) => !UNSUPPORTED_MARKDOWN_BLOCK_TYPES.has(block.type))\n .map((block) => ({\n ...block,\n children: block.children?.length\n ? stripUnsupportedMarkdownBlocks(block.children)\n : []\n }));\n}\n\nfunction preprocessCustomInlineContent(blocks: BlockNote[]): BlockNote[] {\n return blocks.map((block) => ({\n ...block,\n content: block.content?.map((inline) => {\n if (inline.type === 'reference') {\n return {\n type: 'text',\n text: `[[${inline.props?.title || inline.props?.id || ''}]]`,\n styles: {}\n };\n }\n if (inline.type === 'tag') {\n const tag = (inline.props?.tag as string)?.replace(/^@/, '') || '';\n return {\n type: 'text',\n text: `#${tag}`,\n styles: {}\n };\n }\n return inline;\n }),\n children: block.children?.length\n ? preprocessCustomInlineContent(block.children)\n : []\n }));\n}\n\nfunction createTextInline(text: string, styles: Record<string, unknown> = {}): BlockNoteInline {\n return {\n type: 'text',\n text,\n styles\n };\n}\n\nfunction appendInline(target: BlockNoteInline[], inline: BlockNoteInline) {\n const previous = target.at(-1);\n\n if (\n previous?.type === 'text' &&\n inline.type === 'text' &&\n previous.text !== undefined &&\n inline.text !== undefined &&\n JSON.stringify(previous.styles ?? {}) === JSON.stringify(inline.styles ?? {})\n ) {\n previous.text += inline.text;\n return;\n }\n\n target.push(inline);\n}\n\nasync function restoreCustomInlineContent(\n blocks: BlockNote[],\n deps: MarkdownImportDeps\n): Promise<BlockNote[]> {\n const tagCache = new Map<string, Promise<{ id: string; tag: string }>>();\n const noteCache = new Map<string, Promise<Array<{ id: string; title: string }>>>();\n\n const getTag = (token: string) => {\n let existing = tagCache.get(token);\n\n if (!existing) {\n existing = deps.ensureTag(token.slice(1)).then((result) => ({\n id: 'tag' in result ? result.tag.id : result.id,\n tag: 'tag' in result ? result.tag.name : result.name\n }));\n tagCache.set(token, existing);\n }\n\n return existing;\n };\n\n const getNotesByTitle = (title: string) => {\n let existing = noteCache.get(title);\n\n if (!existing) {\n existing = deps.findNotesByTitle(title);\n noteCache.set(title, existing);\n }\n\n return existing;\n };\n\n const restoreTextInline = async (inline: BlockNoteInline): Promise<BlockNoteInline[]> => {\n if (\n inline.type !== 'text' ||\n typeof inline.text !== 'string' ||\n !inline.text ||\n inline.styles?.code === true\n ) {\n return [inline];\n }\n\n const restored: BlockNoteInline[] = [];\n const styles = inline.styles ?? {};\n let cursor = 0;\n\n while (cursor < inline.text.length) {\n if (\n inline.text.startsWith('[[', cursor)\n ) {\n const closeIndex = inline.text.indexOf(']]', cursor + 2);\n\n if (closeIndex !== -1) {\n const title = inline.text.slice(cursor + 2, closeIndex);\n const matchingNotes = await getNotesByTitle(title);\n\n if (matchingNotes.length === 1) {\n appendInline(restored, {\n type: 'reference',\n props: {\n id: matchingNotes[0].id,\n title: matchingNotes[0].title\n }\n });\n cursor = closeIndex + 2;\n continue;\n }\n }\n }\n\n if (\n inline.text[cursor] === '#' &&\n (cursor === 0 || /\\s/.test(inline.text[cursor - 1]))\n ) {\n const remainder = inline.text.slice(cursor);\n const tagMatch = remainder.match(/^#[^\\s[\\]]+/);\n\n if (tagMatch) {\n const tag = await getTag(tagMatch[0]);\n appendInline(restored, {\n type: 'tag',\n props: tag\n });\n cursor += tagMatch[0].length;\n continue;\n }\n }\n\n let nextCursor = cursor + 1;\n\n while (\n nextCursor < inline.text.length &&\n !inline.text.startsWith('[[', nextCursor) &&\n !(\n inline.text[nextCursor] === '#' &&\n /\\s/.test(inline.text[nextCursor - 1] ?? '')\n )\n ) {\n nextCursor += 1;\n }\n\n appendInline(restored, createTextInline(inline.text.slice(cursor, nextCursor), styles));\n cursor = nextCursor;\n }\n\n return restored;\n };\n\n return Promise.all(\n blocks.map(async (block) => ({\n ...block,\n content: block.content\n ? (await Promise.all(block.content.map((inline) => restoreTextInline(inline)))).flat()\n : undefined,\n children: block.children?.length\n ? await restoreCustomInlineContent(block.children, deps)\n : []\n }))\n );\n}\n\nfunction collectTagIds(blocks: BlockNote[]): string[] {\n const tagIds = new Set<string>();\n\n const visit = (items: BlockNote[]) => {\n for (const block of items) {\n for (const inline of block.content ?? []) {\n if (inline.type === 'tag' && typeof inline.props?.id === 'string') {\n tagIds.add(inline.props.id);\n }\n }\n\n if (block.children?.length) {\n visit(block.children);\n }\n }\n };\n\n visit(blocks);\n return [...tagIds];\n}\n\nlet editorInstance: ServerBlockNoteEditor | null = null;\n\nfunction getEditor(): ServerBlockNoteEditor {\n if (!editorInstance) {\n editorInstance = ServerBlockNoteEditor.create();\n }\n return editorInstance;\n}\n\nexport async function blocksToMarkdown(contentJson: string): Promise<string> {\n try {\n const blocks = JSON.parse(contentJson);\n const supportedBlocks = stripUnsupportedMarkdownBlocks(blocks);\n const processed = preprocessCustomInlineContent(supportedBlocks);\n const editor = getEditor();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return await editor.blocksToMarkdownLossy(processed as any);\n } catch {\n return '';\n }\n}\n\nexport async function markdownToBlocksJson(\n markdown: string,\n deps: MarkdownImportDeps = defaultMarkdownImportDeps\n): Promise<string> {\n const editor = getEditor();\n const blocks = await editor.tryParseMarkdownToBlocks(markdown);\n const restoredBlocks = await restoreCustomInlineContent(blocks as BlockNote[], deps);\n return JSON.stringify(restoredBlocks);\n}\n\nexport function extractTagIdsFromContentJson(contentJson: string): string[] {\n const blocks = JSON.parse(contentJson) as BlockNote[];\n return collectTagIds(blocks);\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,8 @@
1
1
  import models from "../models.js";
2
- import { markdownToBlocksJson } from "./blocknote.js";
2
+ import {
3
+ extractTagIdsFromContentJson,
4
+ markdownToBlocksJson
5
+ } from "./blocknote.js";
3
6
  import { captureNoteBaseline } from "./note-snapshot.js";
4
7
  class InvalidNoteAuthoringInputError extends Error {
5
8
  constructor(message) {
@@ -51,9 +54,11 @@ const createNoteAuthoringService = (deps) => {
51
54
  const replacedTitle = await replacePlaceholders(title);
52
55
  const replacedMarkdown = await replacePlaceholders(input.markdown ?? "");
53
56
  const content = await deps.parseMarkdownToContentJson(replacedMarkdown);
57
+ const tagIds = deps.extractTagIds(content);
54
58
  const note = await deps.createNote({
55
59
  title: replacedTitle,
56
60
  content,
61
+ tagIds,
57
62
  ...input.layout ? { layout: input.layout } : {}
58
63
  });
59
64
  return serializeNote(note);
@@ -77,6 +82,7 @@ const createNoteAuthoringService = (deps) => {
77
82
  if (input.markdown !== void 0) {
78
83
  const replacedMarkdown = await replacePlaceholders(input.markdown);
79
84
  nextData.content = await deps.parseMarkdownToContentJson(replacedMarkdown);
85
+ nextData.tagIds = deps.extractTagIds(nextData.content);
80
86
  }
81
87
  if (input.layout !== void 0) {
82
88
  nextData.layout = input.layout;
@@ -97,7 +103,8 @@ const defaultNoteAuthoringService = createNoteAuthoringService({
97
103
  data: {
98
104
  title: input.title,
99
105
  content: input.content,
100
- ...input.layout ? { layout: input.layout } : {}
106
+ ...input.layout ? { layout: input.layout } : {},
107
+ ...input.tagIds ? { tags: { connect: input.tagIds.map((id) => ({ id: Number(id) })) } } : {}
101
108
  }
102
109
  });
103
110
  },
@@ -117,11 +124,17 @@ const defaultNoteAuthoringService = createNoteAuthoringService({
117
124
  });
118
125
  },
119
126
  parseMarkdownToContentJson: markdownToBlocksJson,
127
+ extractTagIds: extractTagIdsFromContentJson,
120
128
  captureBaseline: captureNoteBaseline,
121
129
  updateNote: async (id, input) => {
122
130
  return models.note.update({
123
131
  where: { id },
124
- data: input
132
+ data: {
133
+ title: input.title,
134
+ content: input.content,
135
+ layout: input.layout,
136
+ ...input.tagIds ? { tags: { set: input.tagIds.map((tagId) => ({ id: Number(tagId) })) } } : {}
137
+ }
125
138
  });
126
139
  }
127
140
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/modules/note-authoring.ts"],"sourcesContent":["import models, { type NoteLayout } from '~/models.js';\nimport { markdownToBlocksJson } from './blocknote.js';\nimport { captureNoteBaseline } from './note-snapshot.js';\n\ninterface PlaceholderRecord {\n template: string;\n replacement: string;\n}\n\ninterface NoteRecord {\n id: number;\n title: string;\n content: string;\n layout: NoteLayout;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface NoteAuthoringDeps {\n createNote: (input: {\n title: string;\n content: string;\n layout?: NoteLayout;\n }) => Promise<NoteRecord>;\n findNoteById: (id: number) => Promise<NoteRecord | null>;\n findPlaceholders: (templates: string[]) => Promise<PlaceholderRecord[]>;\n parseMarkdownToContentJson: (markdown: string) => Promise<string>;\n captureBaseline: (input: {\n noteId: number;\n editSessionId?: string;\n meta?: string;\n }) => Promise<unknown>;\n updateNote: (id: number, input: {\n title?: string;\n content?: string;\n layout?: NoteLayout;\n }) => Promise<NoteRecord>;\n}\n\nexport interface CreateNoteAuthoringInput {\n title: string;\n markdown?: string;\n layout?: NoteLayout;\n}\n\nexport interface UpdateNoteAuthoringInput {\n id: number;\n title?: string;\n markdown?: string;\n layout?: NoteLayout;\n editSessionId?: string;\n snapshotMeta?: string;\n}\n\nexport interface AuthoredNoteSummary {\n id: string;\n title: string;\n layout: NoteLayout;\n createdAt: string;\n updatedAt: string;\n}\n\nexport class InvalidNoteAuthoringInputError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidNoteAuthoringInputError';\n }\n}\n\nconst PLACEHOLDER_PREFIX = '{%';\nconst PLACEHOLDER_SUFFIX = '%}';\n\nconst serializeNote = (note: NoteRecord): AuthoredNoteSummary => ({\n id: String(note.id),\n title: note.title,\n layout: note.layout,\n createdAt: note.createdAt.toISOString(),\n updatedAt: note.updatedAt.toISOString()\n});\n\nconst extractPlaceholderTemplates = (value: string) => {\n return Array.from(\n new Set(\n Array.from(\n value.matchAll(new RegExp(`${PLACEHOLDER_PREFIX}([^}]+)${PLACEHOLDER_SUFFIX}`, 'g')),\n (match) => match[1]\n )\n )\n );\n};\n\nexport const createNoteAuthoringService = (deps: NoteAuthoringDeps) => {\n const replacePlaceholders = async (value: string) => {\n const templates = extractPlaceholderTemplates(value);\n\n if (templates.length === 0) {\n return value;\n }\n\n const placeholders = await deps.findPlaceholders(templates);\n let replacedValue = value;\n\n for (const placeholder of placeholders) {\n replacedValue = replacedValue.replace(\n new RegExp(`${PLACEHOLDER_PREFIX}${placeholder.template}${PLACEHOLDER_SUFFIX}`, 'g'),\n placeholder.replacement\n );\n }\n\n return replacedValue;\n };\n\n return {\n createNote: async (input: CreateNoteAuthoringInput): Promise<AuthoredNoteSummary> => {\n const title = input.title.trim();\n\n if (!title) {\n throw new InvalidNoteAuthoringInputError('A note title is required.');\n }\n\n const replacedTitle = await replacePlaceholders(title);\n const replacedMarkdown = await replacePlaceholders(input.markdown ?? '');\n const content = await deps.parseMarkdownToContentJson(replacedMarkdown);\n const note = await deps.createNote({\n title: replacedTitle,\n content,\n ...(input.layout ? { layout: input.layout } : {})\n });\n\n return serializeNote(note);\n },\n\n updateNote: async (input: UpdateNoteAuthoringInput): Promise<AuthoredNoteSummary | null> => {\n if (\n input.title === undefined &&\n input.markdown === undefined &&\n input.layout === undefined\n ) {\n throw new InvalidNoteAuthoringInputError('At least one note field must be provided for update.');\n }\n\n const existingNote = await deps.findNoteById(input.id);\n\n if (!existingNote) {\n return null;\n }\n\n const nextData: {\n title?: string;\n content?: string;\n layout?: NoteLayout;\n } = {};\n\n if (input.title !== undefined) {\n const title = input.title.trim();\n\n if (!title) {\n throw new InvalidNoteAuthoringInputError('A note title is required.');\n }\n\n nextData.title = await replacePlaceholders(title);\n }\n\n if (input.markdown !== undefined) {\n const replacedMarkdown = await replacePlaceholders(input.markdown);\n nextData.content = await deps.parseMarkdownToContentJson(replacedMarkdown);\n }\n\n if (input.layout !== undefined) {\n nextData.layout = input.layout;\n }\n\n await deps.captureBaseline({\n noteId: input.id,\n ...(input.editSessionId ? { editSessionId: input.editSessionId } : {}),\n ...(input.snapshotMeta ? { meta: input.snapshotMeta } : {})\n });\n\n const updatedNote = await deps.updateNote(input.id, nextData);\n return serializeNote(updatedNote);\n }\n };\n};\n\nconst defaultNoteAuthoringService = createNoteAuthoringService({\n createNote: async (input) => {\n return models.note.create({\n data: {\n title: input.title,\n content: input.content,\n ...(input.layout ? { layout: input.layout } : {})\n }\n });\n },\n findNoteById: async (id) => {\n return models.note.findUnique({ where: { id } });\n },\n findPlaceholders: async (templates) => {\n if (templates.length === 0) {\n return [];\n }\n\n return models.placeholder.findMany({\n select: {\n template: true,\n replacement: true\n },\n where: { template: { in: templates } }\n });\n },\n parseMarkdownToContentJson: markdownToBlocksJson,\n captureBaseline: captureNoteBaseline,\n updateNote: async (id, input) => {\n return models.note.update({\n where: { id },\n data: input\n });\n }\n});\n\nexport const createNoteFromMarkdown = async (input: CreateNoteAuthoringInput) => {\n return defaultNoteAuthoringService.createNote(input);\n};\n\nexport const updateNoteFromMarkdown = async (input: UpdateNoteAuthoringInput) => {\n return defaultNoteAuthoringService.updateNote(input);\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/modules/note-authoring.ts"],"sourcesContent":["import models, { type NoteLayout } from '~/models.js';\nimport {\n extractTagIdsFromContentJson,\n markdownToBlocksJson\n} from './blocknote.js';\nimport { captureNoteBaseline } from './note-snapshot.js';\n\ninterface PlaceholderRecord {\n template: string;\n replacement: string;\n}\n\ninterface NoteRecord {\n id: number;\n title: string;\n content: string;\n layout: NoteLayout;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface NoteAuthoringDeps {\n createNote: (input: {\n title: string;\n content: string;\n layout?: NoteLayout;\n tagIds?: string[];\n }) => Promise<NoteRecord>;\n findNoteById: (id: number) => Promise<NoteRecord | null>;\n findPlaceholders: (templates: string[]) => Promise<PlaceholderRecord[]>;\n parseMarkdownToContentJson: (markdown: string) => Promise<string>;\n extractTagIds: (contentJson: string) => string[];\n captureBaseline: (input: {\n noteId: number;\n editSessionId?: string;\n meta?: string;\n }) => Promise<unknown>;\n updateNote: (id: number, input: {\n title?: string;\n content?: string;\n layout?: NoteLayout;\n tagIds?: string[];\n }) => Promise<NoteRecord>;\n}\n\nexport interface CreateNoteAuthoringInput {\n title: string;\n markdown?: string;\n layout?: NoteLayout;\n}\n\nexport interface UpdateNoteAuthoringInput {\n id: number;\n title?: string;\n markdown?: string;\n layout?: NoteLayout;\n editSessionId?: string;\n snapshotMeta?: string;\n}\n\nexport interface AuthoredNoteSummary {\n id: string;\n title: string;\n layout: NoteLayout;\n createdAt: string;\n updatedAt: string;\n}\n\nexport class InvalidNoteAuthoringInputError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidNoteAuthoringInputError';\n }\n}\n\nconst PLACEHOLDER_PREFIX = '{%';\nconst PLACEHOLDER_SUFFIX = '%}';\n\nconst serializeNote = (note: NoteRecord): AuthoredNoteSummary => ({\n id: String(note.id),\n title: note.title,\n layout: note.layout,\n createdAt: note.createdAt.toISOString(),\n updatedAt: note.updatedAt.toISOString()\n});\n\nconst extractPlaceholderTemplates = (value: string) => {\n return Array.from(\n new Set(\n Array.from(\n value.matchAll(new RegExp(`${PLACEHOLDER_PREFIX}([^}]+)${PLACEHOLDER_SUFFIX}`, 'g')),\n (match) => match[1]\n )\n )\n );\n};\n\nexport const createNoteAuthoringService = (deps: NoteAuthoringDeps) => {\n const replacePlaceholders = async (value: string) => {\n const templates = extractPlaceholderTemplates(value);\n\n if (templates.length === 0) {\n return value;\n }\n\n const placeholders = await deps.findPlaceholders(templates);\n let replacedValue = value;\n\n for (const placeholder of placeholders) {\n replacedValue = replacedValue.replace(\n new RegExp(`${PLACEHOLDER_PREFIX}${placeholder.template}${PLACEHOLDER_SUFFIX}`, 'g'),\n placeholder.replacement\n );\n }\n\n return replacedValue;\n };\n\n return {\n createNote: async (input: CreateNoteAuthoringInput): Promise<AuthoredNoteSummary> => {\n const title = input.title.trim();\n\n if (!title) {\n throw new InvalidNoteAuthoringInputError('A note title is required.');\n }\n\n const replacedTitle = await replacePlaceholders(title);\n const replacedMarkdown = await replacePlaceholders(input.markdown ?? '');\n const content = await deps.parseMarkdownToContentJson(replacedMarkdown);\n const tagIds = deps.extractTagIds(content);\n const note = await deps.createNote({\n title: replacedTitle,\n content,\n tagIds,\n ...(input.layout ? { layout: input.layout } : {})\n });\n\n return serializeNote(note);\n },\n\n updateNote: async (input: UpdateNoteAuthoringInput): Promise<AuthoredNoteSummary | null> => {\n if (\n input.title === undefined &&\n input.markdown === undefined &&\n input.layout === undefined\n ) {\n throw new InvalidNoteAuthoringInputError('At least one note field must be provided for update.');\n }\n\n const existingNote = await deps.findNoteById(input.id);\n\n if (!existingNote) {\n return null;\n }\n\n const nextData: {\n title?: string;\n content?: string;\n layout?: NoteLayout;\n tagIds?: string[];\n } = {};\n\n if (input.title !== undefined) {\n const title = input.title.trim();\n\n if (!title) {\n throw new InvalidNoteAuthoringInputError('A note title is required.');\n }\n\n nextData.title = await replacePlaceholders(title);\n }\n\n if (input.markdown !== undefined) {\n const replacedMarkdown = await replacePlaceholders(input.markdown);\n nextData.content = await deps.parseMarkdownToContentJson(replacedMarkdown);\n nextData.tagIds = deps.extractTagIds(nextData.content);\n }\n\n if (input.layout !== undefined) {\n nextData.layout = input.layout;\n }\n\n await deps.captureBaseline({\n noteId: input.id,\n ...(input.editSessionId ? { editSessionId: input.editSessionId } : {}),\n ...(input.snapshotMeta ? { meta: input.snapshotMeta } : {})\n });\n\n const updatedNote = await deps.updateNote(input.id, nextData);\n return serializeNote(updatedNote);\n }\n };\n};\n\nconst defaultNoteAuthoringService = createNoteAuthoringService({\n createNote: async (input) => {\n return models.note.create({\n data: {\n title: input.title,\n content: input.content,\n ...(input.layout ? { layout: input.layout } : {}),\n ...(input.tagIds\n ? { tags: { connect: input.tagIds.map((id) => ({ id: Number(id) })) } }\n : {})\n }\n });\n },\n findNoteById: async (id) => {\n return models.note.findUnique({ where: { id } });\n },\n findPlaceholders: async (templates) => {\n if (templates.length === 0) {\n return [];\n }\n\n return models.placeholder.findMany({\n select: {\n template: true,\n replacement: true\n },\n where: { template: { in: templates } }\n });\n },\n parseMarkdownToContentJson: markdownToBlocksJson,\n extractTagIds: extractTagIdsFromContentJson,\n captureBaseline: captureNoteBaseline,\n updateNote: async (id, input) => {\n return models.note.update({\n where: { id },\n data: {\n title: input.title,\n content: input.content,\n layout: input.layout,\n ...(input.tagIds\n ? { tags: { set: input.tagIds.map((tagId) => ({ id: Number(tagId) })) } }\n : {})\n }\n });\n }\n});\n\nexport const createNoteFromMarkdown = async (input: CreateNoteAuthoringInput) => {\n return defaultNoteAuthoringService.createNote(input);\n};\n\nexport const updateNoteFromMarkdown = async (input: UpdateNoteAuthoringInput) => {\n return defaultNoteAuthoringService.updateNote(input);\n};\n"],"mappings":"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","names":[]}
@@ -1,28 +0,0 @@
1
- import{j as e}from"./note-vendor-BofYbzmZ.js";import{L as K,N as V,d as p,s as W,M as $,B as E,a as J,b as G,u as _,q as L,g as q,P as X,S as Z,T as ee,c as Y,e as te,C as se}from"./index-40Y2UsVr.js";import{a as y}from"./graph-vendor-CUxe67Lr.js";import{p as I}from"./color-wpu7wT_s.js";import{C as ae}from"./Callout-B2kPcDrq.js";import"./note-core-BCgMq5QA.js";const ne=({day:s,cellClassName:t,dayNumberClassName:a,isCurrentMonth:o,items:i,overflowCount:d,onOpenOverflow:u})=>e.jsxs("div",{className:`min-h-[140px] rounded-[14px] border p-2 ${t}`.trim(),children:[e.jsx("div",{className:"mb-2 flex justify-end",children:e.jsx("span",{className:`flex h-7 w-7 items-center justify-center rounded-[10px] text-sm ${a}`.trim(),children:s})}),o&&i.length>0?e.jsxs("div",{className:"flex flex-col gap-1",children:[i,d>0?e.jsxs("button",{type:"button",onClick:u,className:"rounded-[10px] py-1 text-center text-[10px] font-semibold text-fg-tertiary transition-colors hover:bg-hover-subtle hover:text-fg-muted",children:["+",d," more"]}):null]}):null]}),F=({params:s,toneClassName:t="",header:a,title:o,meta:i,titleClassName:d=""})=>e.jsx(K,{to:V,params:s,className:"group block min-h-[44px]",children:e.jsxs("div",{className:`surface-base flex h-full flex-col justify-center px-2 py-1.5 transition-colors group-hover:bg-hover-subtle ${t}`.trim(),children:[a?e.jsx("div",{className:"mb-0.5 flex items-center gap-1 text-fg-muted",children:a}):null,e.jsx("div",{className:`line-clamp-1 text-xs font-semibold text-fg-default ${d}`.trim(),children:o}),i?e.jsx("div",{className:"text-[10px] font-medium text-fg-secondary",children:i}):null]})}),re=({note:s,type:t})=>e.jsx(F,{params:{id:s.id},title:s.title,meta:p(Number(t==="create"?s.createdAt:s.updatedAt)).format("HH:mm")}),oe=({reminder:s})=>e.jsx(F,{params:{id:String(s.note?.id??s.noteId)},header:e.jsx(W,{size:12}),title:s.content||s.note?.title||"No title",titleClassName:s.completed?"line-through":"",meta:p(Number(s.reminderDate)).format("HH:mm")}),T=3,P=(s,t)=>s.map(a=>a.type==="note"?e.jsx(re,{note:a.item,type:t},`note-${a.item.id}`):e.jsx(oe,{reminder:a.item},`reminder-${a.item.id}`)),ie=({day:s,isCurrentMonth:t,isSunday:a,isToday:o,isPast:i,notes:d,reminders:u,type:c})=>{const[f,D]=y.useState(!1),g=y.useMemo(()=>{const C=d.map(N=>({type:"note",item:N})),v=u.map(N=>({type:"reminder",item:N}));return i?[...C,...v]:[...v,...C]},[i,d,u]),M=g.length>T,w=y.useMemo(()=>P(g.slice(0,T),c),[g,c]),n=y.useMemo(()=>P(g,c),[g,c]),l=y.useCallback(()=>D(!0),[]),m=y.useCallback(()=>D(!1),[]),j=()=>t?o?"border-border-secondary/70 bg-[color:color-mix(in_srgb,var(--surface)_88%,var(--accent-soft-primary)_12%)]":"bg-surface border-border-subtle":"bg-muted/18 border-border-subtle/70",S=()=>o?"bg-cta text-fg-on-filled font-semibold":t?a?"text-fg-weekend font-bold":"text-fg-secondary font-bold":"text-fg-disabled opacity-55";return e.jsxs(e.Fragment,{children:[e.jsx(ne,{day:s,cellClassName:j(),dayNumberClassName:S(),isCurrentMonth:t,items:w,overflowCount:M?g.length-T:0,onOpenOverflow:l}),M&&e.jsxs($,{isOpen:f,onClose:m,children:[e.jsx($.Header,{title:`Day ${s}`,onClose:m}),e.jsxs($.Body,{children:[e.jsxs($.Description,{className:"sr-only",children:["View all notes and reminders scheduled for day ",s,"."]}),e.jsx("div",{className:"flex max-h-[60vh] flex-col gap-2 overflow-y-auto",children:n})]})]})]})},le=y.memo(ie),de=["January","February","March","April","May","June","July","August","September","October","November","December"],ce=({month:s,year:t,onPrevMonth:a,onNextMonth:o,onToday:i})=>e.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:de[s-1]}),e.jsx("span",{className:"text-xl sm:text-2xl text-fg-placeholder",children:t})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{variant:"ghost",size:"sm",onClick:i,children:"Today"}),e.jsx(E,{variant:"ghost",size:"icon-sm",onClick:a,children:e.jsx(J,{width:18,height:18})}),e.jsx(E,{variant:"ghost",size:"icon-sm",onClick:o,children:e.jsx(G,{width:18,height:18})})]})]}),me=[{label:"High",className:I.high},{label:"Medium",className:I.medium},{label:"Low",className:I.low},{label:"Overdue",className:"bg-accent-soft-danger/70 dark:bg-emphasis/70"}],xe=()=>e.jsx("div",{className:"flex flex-wrap items-center gap-3 text-xs",children:me.map(({label:s,className:t})=>e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:`h-3 w-3 rounded-full border border-border-subtle ${t}`}),e.jsx("span",{className:"text-fg-tertiary font-medium",children:s})]},s))}),ue=`
2
- query NotesInDateRange($dateRange: DateRangeInput) {
3
- notesInDateRange(dateRange: $dateRange) {
4
- id
5
- title
6
- createdAt
7
- updatedAt
8
- }
9
- }
10
- `,he=`
11
- query RemindersInDateRange($dateRange: DateRangeInput) {
12
- remindersInDateRange(dateRange: $dateRange) {
13
- id
14
- noteId
15
- reminderDate
16
- completed
17
- priority
18
- content
19
- note {
20
- id
21
- title
22
- }
23
- }
24
- }
25
- `,pe=async s=>{const t=await q(ue,{dateRange:s});if(t.type==="error")throw t;return t.notesInDateRange},ge=async s=>{const t=await q(he,{dateRange:s});if(t.type==="error")throw t;return t.remindersInDateRange},ye=({year:s,month:t})=>{const a=`${s}-${String(t).padStart(2,"0")}-01`,o=t===12?1:t+1,d=`${t===12?s+1:s}-${String(o).padStart(2,"0")}-01`,u={start:a,end:d},c=_({queryKey:L.calendar.notesInDateRange(s,t),queryFn:()=>pe(u)}),f=_({queryKey:L.reminders.inDateRange(s,t),queryFn:()=>ge(u)});return{notes:c.data??[],reminders:f.data??[],isLoading:c.isLoading||f.isLoading,isError:c.isError||f.isError}},fe=["SUN","MON","TUE","WED","THU","FRI","SAT"],be=[],Ne=[],H=te(se);function $e(){const s=H.useNavigate(),{year:t,month:a,type:o}=H.useSearch(),{notes:i,reminders:d,isLoading:u,isError:c}=ye({year:t,month:a}),f=y.useMemo(()=>{const n=p(),l=`${n.year()}-${n.month()+1}-${n.date()}`,m=new Map;for(const r of i){const h=o==="create"?p(Number(r.createdAt)):p(Number(r.updatedAt)),x=`${h.year()}-${h.month()+1}-${h.date()}`,b=m.get(x)||[];b.push(r),m.set(x,b)}const j=new Map;for(const r of d){const h=p(Number(r.reminderDate)),x=`${h.year()}-${h.month()+1}-${h.date()}`,b=j.get(x)||[];b.push(r),j.set(x,b)}const S=new Date(t,a-1,1),C=new Date(t,a,0),v=S.getDay(),N=C.getDate(),R=[],k=a===1?12:a-1,O=a===1?t-1:t,U=new Date(O,k,0).getDate();for(let r=v-1;r>=0;r--)R.push({day:U-r,isCurrentMonth:!1,year:O,month:k});for(let r=1;r<=N;r++)R.push({day:r,isCurrentMonth:!0,year:t,month:a});const A=(v+N)%7,Q=A===0?0:7-A,z=a===12?1:a+1,B=a===12?t+1:t;for(let r=1;r<=Q;r++)R.push({day:r,isCurrentMonth:!1,year:B,month:z});return R.map((r,h)=>{const x=`${r.year}-${r.month}-${r.day}`,b=p(`${r.year}-${String(r.month).padStart(2,"0")}-${String(r.day).padStart(2,"0")}`);return{key:x,day:r.day,isCurrentMonth:r.isCurrentMonth,isSunday:h%7===0,isToday:x===l,isPast:b.isBefore(n,"day"),notes:m.get(x)||be,reminders:j.get(x)||Ne}})},[t,a,i,d,o]),D=()=>{const n=a===1?12:a-1,l=a===1?t-1:t;s({search:m=>({...m,month:n,year:l})})},g=()=>{const n=a===12?1:a+1,l=a===12?t+1:t;s({search:m=>({...m,month:n,year:l})})},M=()=>{s({search:n=>({...n,month:p().month()+1,year:p().year()})})},w=n=>{n&&s({search:l=>({...l,type:n})})};return e.jsx(X,{title:"Calendar",variant:"none",children:e.jsxs("div",{className:"w-full px-4 sm:px-6 py-6 sm:py-10 max-w-screen-2xl mx-auto",children:[c?e.jsx(ae,{children:"Failed to load calendar data. Please try again later."}):e.jsxs("div",{className:"surface-base overflow-x-auto p-3 sm:p-4",children:[e.jsx(ce,{month:a,year:t,onPrevMonth:D,onNextMonth:g,onToday:M}),e.jsxs("div",{className:"min-w-[900px]",children:[e.jsx("div",{className:"grid grid-cols-7 gap-1 mb-2",children:fe.map((n,l)=>e.jsx("div",{className:`
26
- py-2 text-center text-xs font-bold tracking-wider
27
- ${l===0?"text-fg-weekend":"text-fg-secondary"}
28
- `,children:n},n))}),u?e.jsx("div",{className:"grid grid-cols-7 gap-1",children:Array.from({length:35}).map((n,l)=>e.jsx(Z,{height:140},l))}):e.jsx("div",{className:"grid grid-cols-7 gap-1",children:f.map(n=>e.jsx(le,{day:n.day,isCurrentMonth:n.isCurrentMonth,isSunday:n.isSunday,isToday:n.isToday,isPast:n.isPast,notes:n.notes,reminders:n.reminders,type:o},n.key))})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mt-6",children:[e.jsx(xe,{}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-sm text-fg-tertiary font-bold",children:"Display by:"}),e.jsxs(ee,{type:"single",variant:"pills",size:"sm",value:o,onValueChange:w,children:[e.jsx(Y,{value:"create",children:"Create date"}),e.jsx(Y,{value:"update",children:"Update date"})]})]})]})]})})}export{$e as default};