@canvas-digital/blog-sdk 2.0.1 → 2.0.4

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.
@@ -1 +1 @@
1
- (function(a){"use strict";class c extends Error{constructor(e,t={status:0}){super(e),this.name="ApiError",this.status=t.status,this.code=t.code??"API_ERROR",this.details=t.details??null}}function p(o){return o instanceof c}function U(o){return p(o)&&(o.status===401||o.status===403)}function B(o){return p(o)||o instanceof Error?o.message:"Unexpected error"}function _(o,e){const t=o.replace(/\/+$/,""),n=e.startsWith("/")?e:`/${e}`;return`${t}${n}`}function r(o){if(!o)return"";const e=new URLSearchParams;for(const[n,s]of Object.entries(o))s==null||s===""||e.set(n,String(s));const t=e.toString();return t?`?${t}`:""}function O(o,e,t){if(e&&typeof e=="object"){const n=e;if(typeof n.message=="string"&&n.message)return new c(n.message,{status:o,code:typeof n.code=="string"?n.code:"API_ERROR",details:n.details??null});if(typeof n.detail=="string"&&n.detail)return new c(n.detail,{status:o,code:"API_ERROR"});if(Array.isArray(n.detail)){const s=n.detail.map(d=>d&&typeof d=="object"&&"msg"in d?String(d.msg):JSON.stringify(d)).join("; ");return new c(s||t,{status:o,code:"VALIDATION_ERROR",details:n.detail})}}return new c(t,{status:o,code:"API_ERROR"})}function C(o){return o&&typeof o=="object"&&"success"in o&&"data"in o?o.data:o}async function f(o,e,t,n={}){var w,A,$,S,P;if(typeof fetch!="function")throw new c("fetch is not available in this environment",{status:0,code:"FETCH_UNAVAILABLE"});const s=n.timeoutMs??3e4,d=new AbortController,k=setTimeout(()=>d.abort(),s),E=()=>d.abort();(w=n.signal)==null||w.addEventListener("abort",E);const l={Accept:"application/json",...n.headers};t&&(l.Authorization=t);const I=(A=n.email)==null?void 0:A.trim();I&&(l.email=I.toLowerCase());const R=($=n.apiKey)==null?void 0:$.trim();R&&(l.apiKey=R);const b=(S=n.domain)==null?void 0:S.trim();b&&(l.domain=b,l["X-Client-Domain"]=b);let q;typeof FormData<"u"&&n.body instanceof FormData?q=n.body:n.body!==void 0&&(l["Content-Type"]=l["Content-Type"]??"application/json",q=JSON.stringify(n.body));try{const u=await fetch(_(o,e),{method:n.method??"GET",headers:l,body:q,signal:d.signal,credentials:"omit"}),h=await u.text(),N=(u.headers.get("content-type")??"").includes("application/json")||h.startsWith("{")||h.startsWith("[");let m=h||null;if(h&&N)try{m=JSON.parse(h)}catch{m=h}if(!u.ok)throw O(u.status,m,`Blog API error: ${u.status}`);return m===null||m===""?void 0:C(m)}catch(u){throw u instanceof c?u:u instanceof Error&&u.name==="AbortError"?new c("Request timed out",{status:408,code:"REQUEST_TIMEOUT"}):new c(u instanceof Error?u.message:"Network error",{status:0,code:"NETWORK_ERROR"})}finally{clearTimeout(k),(P=n.signal)==null||P.removeEventListener("abort",E)}}async function T(o,e,t,n={}){return f(o,e,null,{...n,email:t.email,apiKey:t.apiKey,domain:t.domain??n.domain})}function i(o,e,t){if(Array.isArray(o))return{items:o,page:e,pageSize:t,total:o.length};if(o&&typeof o=="object"){const n=o,s=n.items??n.results??n.data??[],d=Array.isArray(s)?s:[];return{items:d,page:Number(n.page??e)||e,pageSize:Number(n.page_size??n.pageSize??t)||t,total:Number(n.total??n.count??d.length)||d.length}}return{items:[],page:e,pageSize:t,total:0}}function z(o){return o.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function v(o,e,t){return r({page:e,page_size:t,search:o.search,status:o.status,category_id:o.category_id,tag_id:o.tag_id,published_after:o.published_after,published_before:o.published_before,sort:o.sort,order:o.order})}class L{constructor(e){this.config=e}request(e,t={}){return f(this.config.apiUrl,e,null,{timeoutMs:this.config.timeoutMs,email:this.config.email,apiKey:this.config.publicApiKey,domain:this.config.domain,...t})}async getBlogs(e={}){const t=e.page??1,n=e.page_size??12,s=await this.request(`/blogs${v(e,t,n)}`);return i(s,t,n)}getBlogById(e){return this.request(`/blogs/${encodeURIComponent(e)}`)}getBlogBySlug(e){return this.request(`/blogs/slug/${encodeURIComponent(e)}`)}getBlog(e){return this.getBlogBySlug(e)}async searchBlogs(e,t={}){return this.getBlogs({...t,search:e})}async getFeaturedBlogs(e=3){return(await this.getBlogs({page:1,page_size:e,sort:"published_at",order:"desc"})).items}async getRelatedBlogs(e,t=3){return e.category_id?(await this.getBlogs({category_id:e.category_id,page:1,page_size:t+1,sort:"published_at",order:"desc"})).items.filter(s=>s.id!==e.id).slice(0,t):[]}async getCategories(){const e=await this.request("/categories");return Array.isArray(e)?e:i(e,1,100).items}async getTags(){const e=await this.request("/tags");return Array.isArray(e)?e:i(e,1,100).items}trackView(e,t){return this.request("/analytics/views",{method:"POST",body:{blog_id:e,referrer:t??void 0}})}getPopularBlogs(e=10){return this.request(`/analytics/popular${r({limit:e})}`)}}function M(o){return`Bearer ${o.adminApiKey}`}function D(o,e,t){return r({page:e,page_size:t,search:o.search,status:o.status,category_id:o.category_id,tag_id:o.tag_id,published_after:o.published_after,published_before:o.published_before,sort:o.sort,order:o.order})}function y(o){const e={};for(const[t,n]of Object.entries(o))n===void 0||n===""||(e[t]=n);return e}class j{constructor(e){this.config=e}request(e,t={}){return f(this.config.apiUrl,e,M(this.config),{timeoutMs:this.config.timeoutMs,domain:this.config.domain,...t})}async getBlogs(e={}){const t=e.page??1,n=e.page_size??20,s=await this.request(`/blogs${D(e,t,n)}`);return i(s,t,n)}getBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}`)}createBlog(e){return this.request("/blogs",{method:"POST",body:y({...e})})}updateBlog(e,t){return this.request(`/blogs/${encodeURIComponent(e)}`,{method:"PUT",body:y({...t})})}patchBlog(e,t){return this.request(`/blogs/${encodeURIComponent(e)}`,{method:"PATCH",body:y({...t})})}deleteBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}`,{method:"DELETE"})}publishBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}/publish`,{method:"POST"})}unpublishBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}/unpublish`,{method:"POST"})}scheduleBlog(e,t){return this.request(`/blogs/${encodeURIComponent(e)}/schedule`,{method:"POST",body:{scheduled_at:t}})}archiveBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}/archive`,{method:"POST"})}async getCategories(){const e=await this.request("/categories");return Array.isArray(e)?e:i(e,1,100).items}createCategory(e){return this.request("/categories",{method:"POST",body:y({...e})})}updateCategory(e,t){return this.request(`/categories/${encodeURIComponent(e)}`,{method:"PUT",body:t})}deleteCategory(e){return this.request(`/categories/${encodeURIComponent(e)}`,{method:"DELETE"})}async getTags(){const e=await this.request("/tags");return Array.isArray(e)?e:i(e,1,100).items}createTag(e){return this.request("/tags",{method:"POST",body:y({...e})})}updateTag(e,t){return this.request(`/tags/${encodeURIComponent(e)}`,{method:"PUT",body:t})}deleteTag(e){return this.request(`/tags/${encodeURIComponent(e)}`,{method:"DELETE"})}async getMedia(e={}){const t=e.page??1,n=e.page_size??20,s=await this.request(`/media${r({page:t,page_size:n})}`);return i(s,t,n)}async listMediaAssets(e={}){return(await this.getMedia(e)).items}uploadMedia(e){const t=new FormData;return t.append("file",e),this.request("/media",{method:"POST",body:t})}deleteMedia(e){return this.request(`/media/${encodeURIComponent(e)}`,{method:"DELETE"})}}function g(o){const e={};for(const[t,n]of Object.entries(o))n!==void 0&&(e[t]=n);return e}class K{constructor(e){this.config=e}credentials(){return{email:this.config.email,apiKey:this.config.adminApiKey,domain:this.config.domain}}request(e,t={}){return T(this.config.apiUrl,e,this.credentials(),{timeoutMs:this.config.timeoutMs,...t})}me(){return this.request("/admin/admins/me")}async listBrands(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/brands${r({page:t,pageSize:n,status:e.status})}`);return i(s,t,n)}createBrand(e){return this.request("/admin/brands",{method:"POST",body:g(e)})}async listPosts(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/posts${r({page:t,pageSize:n,brandId:e.brandId,status:e.status,q:e.q,categoryId:e.categoryId,includeTrash:e.includeTrash?"true":void 0})}`);return i(s,t,n)}getPost(e){return this.request(`/admin/posts/${encodeURIComponent(e)}`)}createPost(e){return this.request("/admin/posts",{method:"POST",body:g({...e})})}updatePost(e,t){return this.request(`/admin/posts/${encodeURIComponent(e)}`,{method:"PATCH",body:g({...t})})}deletePost(e,t=!1){return this.request(`/admin/posts/${encodeURIComponent(e)}${r({forever:t?"true":void 0})}`,{method:"DELETE"})}publishPost(e){return this.request(`/admin/posts/${encodeURIComponent(e)}/publish`,{method:"POST"})}unpublishPost(e){return this.request(`/admin/posts/${encodeURIComponent(e)}/unpublish`,{method:"POST"})}async listCategories(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/categories${r({page:t,pageSize:n,brandId:e.brandId,q:e.q,status:e.status})}`);return i(s,t,n)}createCategory(e){return this.request("/admin/categories",{method:"POST",body:g(e)})}updateCategory(e,t){return this.request(`/admin/categories/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteCategory(e,t=!1){return this.request(`/admin/categories/${encodeURIComponent(e)}${r({hard:t?"true":void 0})}`,{method:"DELETE"})}async listComments(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/comments${r({page:t,pageSize:n,brandId:e.brandId,postId:e.postId,status:e.status})}`);return i(s,t,n)}setCommentStatus(e,t){return this.request(`/admin/comments/${encodeURIComponent(e)}/status`,{method:"PATCH",body:{status:t}})}deleteComment(e){return this.request(`/admin/comments/${encodeURIComponent(e)}`,{method:"DELETE"})}async listTags(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/tags${r({page:t,pageSize:n,brandId:e.brandId,q:e.q,status:e.status})}`);return i(s,t,n)}createTag(e){return this.request("/admin/tags",{method:"POST",body:g(e)})}updateTag(e,t){return this.request(`/admin/tags/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteTag(e,t=!1){return this.request(`/admin/tags/${encodeURIComponent(e)}${r({hard:t?"true":void 0})}`,{method:"DELETE"})}async listAuthors(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/authors${r({page:t,pageSize:n,brandId:e.brandId,q:e.q,status:e.status})}`);return i(s,t,n)}createAuthor(e){return this.request("/admin/authors",{method:"POST",body:g(e)})}updateAuthor(e,t){return this.request(`/admin/authors/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteAuthor(e,t=!1){return this.request(`/admin/authors/${encodeURIComponent(e)}${r({hard:t?"true":void 0})}`,{method:"DELETE"})}async listMedia(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/media${r({page:t,pageSize:n,brandId:e.brandId,q:e.q})}`);return i(s,t,n)}uploadMedia(e,t){const n=new FormData;return n.append("file",e),n.append("brandId",t),this.request("/admin/media",{method:"POST",body:n})}updateMedia(e,t){return this.request(`/admin/media/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteMedia(e){return this.request(`/admin/media/${encodeURIComponent(e)}`,{method:"DELETE"})}async resolveBrandByDomain(e){const t=e.trim().toLowerCase().replace(/^www\./,""),n=await this.listBrands({page:1,pageSize:100});return n.items.find(s=>(s.domain??"").toLowerCase().replace(/^www\./,"")===t)??n.items.find(s=>{try{return new URL(s.url||`https://${s.domain||""}`).hostname.toLowerCase().replace(/^www\./,"")===t}catch{return!1}})??n.items[0]??null}}a.AdminSdkClient=K,a.ApiError=c,a.BlogAdminClient=j,a.BlogClient=L,a.adminSdkRequest=T,a.getErrorMessage=B,a.httpRequest=f,a.isApiError=p,a.isAuthError=U,a.normalizePage=i,a.slugify=z,a.toQuery=r,a.unwrapData=C,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})})(this.BlogPlatform=this.BlogPlatform||{});
1
+ (function(d){"use strict";class c extends Error{constructor(e,t={status:0}){super(e),this.name="ApiError",this.status=t.status,this.code=t.code??"API_ERROR",this.details=t.details??null}}function b(o){return o instanceof c}function B(o){return b(o)&&(o.status===401||o.status===403)}function _(o){return b(o)||o instanceof Error?o.message:"Unexpected error"}function z(o,e){const t=o.replace(/\/+$/,""),n=e.startsWith("/")?e:`/${e}`;return`${t}${n}`}function i(o){if(!o)return"";const e=new URLSearchParams;for(const[n,s]of Object.entries(o))s==null||s===""||e.set(n,String(s));const t=e.toString();return t?`?${t}`:""}function O(o,e,t){if(e&&typeof e=="object"){const n=e;if(typeof n.message=="string"&&n.message)return new c(n.message,{status:o,code:typeof n.code=="string"?n.code:"API_ERROR",details:n.details??null});if(typeof n.detail=="string"&&n.detail)return new c(n.detail,{status:o,code:"API_ERROR"});if(Array.isArray(n.detail)){const s=n.detail.map(r=>r&&typeof r=="object"&&"msg"in r?String(r.msg):JSON.stringify(r)).join("; ");return new c(s||t,{status:o,code:"VALIDATION_ERROR",details:n.detail})}}return new c(t,{status:o,code:"API_ERROR"})}function T(o){return o&&typeof o=="object"&&"success"in o&&"data"in o?o.data:o}async function f(o,e,t,n={}){var A,$,S,P,U;if(typeof fetch!="function")throw new c("fetch is not available in this environment",{status:0,code:"FETCH_UNAVAILABLE"});const s=n.timeoutMs??3e4,r=new AbortController,p=setTimeout(()=>r.abort(),s),w=()=>r.abort();(A=n.signal)==null||A.addEventListener("abort",w);const l={Accept:"application/json",...n.headers};t&&(l.Authorization=t);const I=($=n.email)==null?void 0:$.trim();I&&(l.email=I.toLowerCase());const R=(S=n.apiKey)==null?void 0:S.trim();R&&(l.apiKey=R);const q=(P=n.domain)==null?void 0:P.trim();q&&(l.domain=q,l["X-Client-Domain"]=q);let C;typeof FormData<"u"&&n.body instanceof FormData?C=n.body:n.body!==void 0&&(l["Content-Type"]=l["Content-Type"]??"application/json",C=JSON.stringify(n.body));try{const u=await fetch(z(o,e),{method:n.method??"GET",headers:l,body:C,signal:r.signal,credentials:"omit"}),h=await u.text(),N=(u.headers.get("content-type")??"").includes("application/json")||h.startsWith("{")||h.startsWith("[");let m=h||null;if(h&&N)try{m=JSON.parse(h)}catch{m=h}if(!u.ok)throw O(u.status,m,`Blog API error: ${u.status}`);return m===null||m===""?void 0:T(m)}catch(u){throw u instanceof c?u:u instanceof Error&&u.name==="AbortError"?new c("Request timed out",{status:408,code:"REQUEST_TIMEOUT"}):new c(u instanceof Error?u.message:"Network error",{status:0,code:"NETWORK_ERROR"})}finally{clearTimeout(p),(U=n.signal)==null||U.removeEventListener("abort",w)}}async function E(o,e,t,n={}){return f(o,e,null,{...n,email:t.email,apiKey:t.apiKey,domain:t.domain??n.domain})}function a(o,e,t){if(Array.isArray(o))return{items:o,page:e,pageSize:t,total:o.length};if(o&&typeof o=="object"){const n=o,s=n.items??n.results??n.data??[],r=Array.isArray(s)?s:[];return{items:r,page:Number(n.page??e)||e,pageSize:Number(n.page_size??n.pageSize??t)||t,total:Number(n.total??n.count??r.length)||r.length}}return{items:[],page:e,pageSize:t,total:0}}function v(o){return o.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function L(o,e,t){return i({page:e,page_size:t,search:o.search,status:o.status,category_id:o.category_id,tag_id:o.tag_id,published_after:o.published_after,published_before:o.published_before,sort:o.sort,order:o.order})}class M{constructor(e){this.config=e}request(e,t={}){return f(this.config.apiUrl,e,null,{timeoutMs:this.config.timeoutMs,email:this.config.email,apiKey:this.config.publicApiKey,domain:this.config.domain,...t})}async getBlogs(e={}){const t=e.page??1,n=e.page_size??12,s=await this.request(`/blogs${L(e,t,n)}`);return a(s,t,n)}getBlogById(e){return this.request(`/blogs/${encodeURIComponent(e)}`)}getBlogBySlug(e){return this.request(`/blogs/slug/${encodeURIComponent(e)}`)}getBlog(e){return this.getBlogBySlug(e)}async searchBlogs(e,t={}){return this.getBlogs({...t,search:e})}async getFeaturedBlogs(e=3){return(await this.getBlogs({page:1,page_size:e,sort:"published_at",order:"desc"})).items}async getRelatedBlogs(e,t=3){return e.category_id?(await this.getBlogs({category_id:e.category_id,page:1,page_size:t+1,sort:"published_at",order:"desc"})).items.filter(s=>s.id!==e.id).slice(0,t):[]}async getCategories(){const e=await this.request("/categories");return Array.isArray(e)?e:a(e,1,100).items}async getTags(){const e=await this.request("/tags");return Array.isArray(e)?e:a(e,1,100).items}trackView(e,t){return this.request("/analytics/views",{method:"POST",body:{blog_id:e,referrer:t??void 0}})}getPopularBlogs(e=10){return this.request(`/analytics/popular${i({limit:e})}`)}}function D(o){return`Bearer ${o.adminApiKey}`}function j(o,e,t){return i({page:e,page_size:t,search:o.search,status:o.status,category_id:o.category_id,tag_id:o.tag_id,published_after:o.published_after,published_before:o.published_before,sort:o.sort,order:o.order})}function y(o){const e={};for(const[t,n]of Object.entries(o))n===void 0||n===""||(e[t]=n);return e}class k{constructor(e){this.config=e}request(e,t={}){return f(this.config.apiUrl,e,D(this.config),{timeoutMs:this.config.timeoutMs,domain:this.config.domain,...t})}async getBlogs(e={}){const t=e.page??1,n=e.page_size??20,s=await this.request(`/blogs${j(e,t,n)}`);return a(s,t,n)}getBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}`)}createBlog(e){return this.request("/blogs",{method:"POST",body:y({...e})})}updateBlog(e,t){return this.request(`/blogs/${encodeURIComponent(e)}`,{method:"PUT",body:y({...t})})}patchBlog(e,t){return this.request(`/blogs/${encodeURIComponent(e)}`,{method:"PATCH",body:y({...t})})}deleteBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}`,{method:"DELETE"})}publishBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}/publish`,{method:"POST"})}unpublishBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}/unpublish`,{method:"POST"})}scheduleBlog(e,t){return this.request(`/blogs/${encodeURIComponent(e)}/schedule`,{method:"POST",body:{scheduled_at:t}})}archiveBlog(e){return this.request(`/blogs/${encodeURIComponent(e)}/archive`,{method:"POST"})}async getCategories(){const e=await this.request("/categories");return Array.isArray(e)?e:a(e,1,100).items}createCategory(e){return this.request("/categories",{method:"POST",body:y({...e})})}updateCategory(e,t){return this.request(`/categories/${encodeURIComponent(e)}`,{method:"PUT",body:t})}deleteCategory(e){return this.request(`/categories/${encodeURIComponent(e)}`,{method:"DELETE"})}async getTags(){const e=await this.request("/tags");return Array.isArray(e)?e:a(e,1,100).items}createTag(e){return this.request("/tags",{method:"POST",body:y({...e})})}updateTag(e,t){return this.request(`/tags/${encodeURIComponent(e)}`,{method:"PUT",body:t})}deleteTag(e){return this.request(`/tags/${encodeURIComponent(e)}`,{method:"DELETE"})}async getMedia(e={}){const t=e.page??1,n=e.page_size??20,s=await this.request(`/media${i({page:t,page_size:n})}`);return a(s,t,n)}async listMediaAssets(e={}){return(await this.getMedia(e)).items}uploadMedia(e){const t=new FormData;return t.append("file",e),this.request("/media",{method:"POST",body:t})}deleteMedia(e){return this.request(`/media/${encodeURIComponent(e)}`,{method:"DELETE"})}}function g(o){const e={};for(const[t,n]of Object.entries(o))n!==void 0&&(e[t]=n);return e}class K{constructor(e){this.config=e}credentials(){return{email:this.config.email,apiKey:this.config.adminApiKey,domain:this.config.domain}}request(e,t={}){return E(this.config.apiUrl,e,this.credentials(),{timeoutMs:this.config.timeoutMs,...t})}me(){return this.request("/admin/admins/me")}async listBrands(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/brands${i({page:t,pageSize:n,status:e.status})}`);return a(s,t,n)}createBrand(e){return this.request("/admin/brands",{method:"POST",body:g(e)})}async listPosts(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/posts${i({page:t,pageSize:n,brandId:e.brandId,status:e.status,q:e.q,categoryId:e.categoryId,includeTrash:e.includeTrash?"true":void 0})}`);return a(s,t,n)}async listPostsAll(e={}){const t=Math.min(e.pageSize??100,100);let n=1;const s=[];let r=0;for(;;){const p=await this.listPosts({...e,page:n,pageSize:t});if(r=p.total,s.push(...p.items),s.length>=r||p.items.length===0)break;n+=1}return{items:s,page:1,pageSize:s.length||t,total:r||s.length}}getPost(e){return this.request(`/admin/posts/${encodeURIComponent(e)}`)}createPost(e){return this.request("/admin/posts",{method:"POST",body:g({...e})})}updatePost(e,t){return this.request(`/admin/posts/${encodeURIComponent(e)}`,{method:"PATCH",body:g({...t})})}deletePost(e,t=!1){return this.request(`/admin/posts/${encodeURIComponent(e)}${i({forever:t?"true":void 0})}`,{method:"DELETE"})}publishPost(e){return this.request(`/admin/posts/${encodeURIComponent(e)}/publish`,{method:"POST"})}unpublishPost(e){return this.request(`/admin/posts/${encodeURIComponent(e)}/unpublish`,{method:"POST"})}async listCategories(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/categories${i({page:t,pageSize:n,brandId:e.brandId,q:e.q,status:e.status})}`);return a(s,t,n)}createCategory(e){return this.request("/admin/categories",{method:"POST",body:g(e)})}updateCategory(e,t){return this.request(`/admin/categories/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteCategory(e,t=!1){return this.request(`/admin/categories/${encodeURIComponent(e)}${i({hard:t?"true":void 0})}`,{method:"DELETE"})}async listComments(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/comments${i({page:t,pageSize:n,brandId:e.brandId,postId:e.postId,status:e.status})}`);return a(s,t,n)}setCommentStatus(e,t){return this.request(`/admin/comments/${encodeURIComponent(e)}/status`,{method:"PATCH",body:{status:t}})}deleteComment(e){return this.request(`/admin/comments/${encodeURIComponent(e)}`,{method:"DELETE"})}async listTags(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/tags${i({page:t,pageSize:n,brandId:e.brandId,q:e.q,status:e.status})}`);return a(s,t,n)}createTag(e){return this.request("/admin/tags",{method:"POST",body:g(e)})}updateTag(e,t){return this.request(`/admin/tags/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteTag(e,t=!1){return this.request(`/admin/tags/${encodeURIComponent(e)}${i({hard:t?"true":void 0})}`,{method:"DELETE"})}async listAuthors(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/authors${i({page:t,pageSize:n,brandId:e.brandId,q:e.q,status:e.status})}`);return a(s,t,n)}createAuthor(e){return this.request("/admin/authors",{method:"POST",body:g(e)})}updateAuthor(e,t){return this.request(`/admin/authors/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteAuthor(e,t=!1){return this.request(`/admin/authors/${encodeURIComponent(e)}${i({hard:t?"true":void 0})}`,{method:"DELETE"})}async listMedia(e={}){const t=e.page??1,n=e.pageSize??100,s=await this.request(`/admin/media${i({page:t,pageSize:n,brandId:e.brandId,q:e.q})}`);return a(s,t,n)}uploadMedia(e,t){const n=new FormData;return n.append("file",e),n.append("brandId",t),this.request("/admin/media",{method:"POST",body:n})}updateMedia(e,t){return this.request(`/admin/media/${encodeURIComponent(e)}`,{method:"PATCH",body:g(t)})}deleteMedia(e){return this.request(`/admin/media/${encodeURIComponent(e)}`,{method:"DELETE"})}async resolveBrandByDomain(e){const t=e.trim().toLowerCase().replace(/^www\./,""),n=await this.listBrands({page:1,pageSize:100});return n.items.find(s=>(s.domain??"").toLowerCase().replace(/^www\./,"")===t)??n.items.find(s=>{try{return new URL(s.url||`https://${s.domain||""}`).hostname.toLowerCase().replace(/^www\./,"")===t}catch{return!1}})??n.items[0]??null}}d.AdminSdkClient=K,d.ApiError=c,d.BlogAdminClient=k,d.BlogClient=M,d.adminSdkRequest=E,d.getErrorMessage=_,d.httpRequest=f,d.isApiError=b,d.isAuthError=B,d.normalizePage=a,d.slugify=v,d.toQuery=i,d.unwrapData=T,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})})(this.BlogPlatform=this.BlogPlatform||{});
@@ -1 +1 @@
1
- {"version":3,"file":"AdminPostDetail.d.ts","sourceRoot":"","sources":["../../../app/components/admin/AdminPostDetail.tsx"],"names":[],"mappings":"AAcA,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,MAAM,EAAE,OAAO,EACf,aAAa,GACd,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,+BAqNA"}
1
+ {"version":3,"file":"AdminPostDetail.d.ts","sourceRoot":"","sources":["../../../app/components/admin/AdminPostDetail.tsx"],"names":[],"mappings":"AAcA,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,MAAM,EAAE,OAAO,EACf,aAAa,GACd,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,+BAuOA"}
@@ -14,10 +14,29 @@ export function AdminPostDetail({ postId, onBack, onEdit: _onEdit, onViewRelated
14
14
  const media = useMemo(() => {
15
15
  if (!post?.featuredImageId)
16
16
  return null;
17
+ const ref = post.featuredImageId;
17
18
  const hit = store
18
19
  .listMedia(post.brandId, "", 1, 200)
19
- .items.find((m) => m.id === post.featuredImageId);
20
- return hit ?? null;
20
+ .items.find((m) => m.id === ref || m.url === ref);
21
+ if (hit)
22
+ return hit;
23
+ if (/^(https?:|data:|blob:|\/)/i.test(ref)) {
24
+ return {
25
+ id: ref,
26
+ url: ref,
27
+ thumbUrl: ref,
28
+ alt: post.title,
29
+ filename: "",
30
+ width: null,
31
+ height: null,
32
+ filesize: null,
33
+ createdAt: post.updatedAt,
34
+ brandId: post.brandId,
35
+ caption: "",
36
+ credit: "",
37
+ };
38
+ }
39
+ return null;
21
40
  }, [post, store]);
22
41
  const authors = useMemo(() => {
23
42
  if (!post)
@@ -1 +1 @@
1
- {"version":3,"file":"MediaLibrary.d.ts","sourceRoot":"","sources":["../../../app/components/admin/MediaLibrary.tsx"],"names":[],"mappings":"AAMA,wBAAgB,YAAY,gCAmR3B;AAED,uEAAuE;AACvE,wBAAgB,YAAY,gCAE3B"}
1
+ {"version":3,"file":"MediaLibrary.d.ts","sourceRoot":"","sources":["../../../app/components/admin/MediaLibrary.tsx"],"names":[],"mappings":"AAMA,wBAAgB,YAAY,gCAiT3B;AAED,uEAAuE;AACvE,wBAAgB,YAAY,gCAE3B"}
@@ -4,8 +4,8 @@ import { useAdminMock } from "./mock/store";
4
4
  const kb = (n) => (n ? `${Math.round(n / 1024)} KB` : "—");
5
5
  export function MediaLibrary() {
6
6
  const store = useAdminMock();
7
- const tenant = store.activeBrandId;
8
- const tenantName = store.activeBrand?.name ?? "all brands";
7
+ const tenant = store.activeBrandId ?? store.brands[0]?.id ?? null;
8
+ const tenantName = store.brands.find((b) => b.id === tenant)?.name ?? store.activeBrand?.name ?? "all brands";
9
9
  const [items, setItems] = useState([]);
10
10
  const [count, setCount] = useState(0);
11
11
  const [query, setQuery] = useState("");
@@ -15,6 +15,7 @@ export function MediaLibrary() {
15
15
  const [uploading, setUploading] = useState(null);
16
16
  const [dragging, setDragging] = useState(false);
17
17
  const [error, setError] = useState(null);
18
+ const [flash, setFlash] = useState(null);
18
19
  const [open, setOpen] = useState(null);
19
20
  const [meta, setMeta] = useState({ alt: "", caption: "", credit: "" });
20
21
  const [saving, startSaving] = useTransition();
@@ -39,13 +40,29 @@ export function MediaLibrary() {
39
40
  return () => clearTimeout(id);
40
41
  }, [query, load]);
41
42
  const upload = async (files) => {
43
+ if (!tenant) {
44
+ setError("Select a brand before uploading images.");
45
+ return;
46
+ }
42
47
  const total = Array.from(files).length;
43
48
  setError(null);
49
+ setFlash(null);
44
50
  setUploading({ done: 0, total });
45
51
  const res = await store.uploadMedia(files, tenant);
46
52
  setUploading(null);
47
- if (!res.ok)
48
- setError(res.error ?? "Upload failed.");
53
+ if (!res.ok) {
54
+ setError(res.error ?? "Upload failed. Please try again.");
55
+ return;
56
+ }
57
+ setFlash(res.images.length === 1
58
+ ? "Image uploaded successfully."
59
+ : `${res.images.length} images uploaded successfully.`);
60
+ // Show uploaded items immediately (absolute URLs), then refresh list
61
+ setItems((prev) => {
62
+ const ids = new Set(res.images.map((i) => i.id));
63
+ return [...res.images, ...prev.filter((p) => !ids.has(p.id))];
64
+ });
65
+ setCount((c) => c + res.images.length);
49
66
  setPage(1);
50
67
  load(1, query, false);
51
68
  const first = res.images[0];
@@ -96,7 +113,7 @@ export function MediaLibrary() {
96
113
  if (e.target.files?.length)
97
114
  void upload(e.target.files);
98
115
  e.target.value = "";
99
- } }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, _jsxs("p", { className: "explain", children: ["Mock uploads create local object URLs via ", _jsx("b", { children: "FileReader" }), " \u2014 no server re-encoding in this package demo."] }), _jsxs("section", { className: `panel dropzone${dragging ? " is-dragging" : ""}`, onDragOver: (e) => {
116
+ } }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsx("p", { className: "explain", children: "Uploaded images are stored on the Blog Platform API and shown here for every brand." }), _jsxs("section", { className: `panel dropzone${dragging ? " is-dragging" : ""}`, onDragOver: (e) => {
100
117
  e.preventDefault();
101
118
  setDragging(true);
102
119
  }, onDragLeave: () => setDragging(false), onDrop: (e) => {
@@ -104,7 +121,7 @@ export function MediaLibrary() {
104
121
  setDragging(false);
105
122
  if (e.dataTransfer.files?.length)
106
123
  void upload(e.dataTransfer.files);
107
- }, children: [items.length === 0 && !loading ? (_jsx("p", { className: "d-empty", children: "Nothing here yet \u2014 drop images anywhere on this panel to upload." })) : (_jsx("div", { className: "media-grid", children: items.map((item) => (_jsxs("button", { type: "button", className: "media-card", onClick: () => openDetail(item), children: [item.thumbUrl ? _jsx("img", { src: item.thumbUrl, alt: "", loading: "lazy" }) : _jsx("span", { className: "pick-blank" }), _jsxs("span", { className: "media-meta", children: [_jsx("span", { className: "media-alt", children: item.alt || item.filename || "Image" }), _jsxs("span", { className: "media-sub", children: [item.width && item.height ? `${item.width}×${item.height}` : "—", " \u00B7 ", kb(item.filesize)] })] })] }, item.id))) })), hasMore ? (_jsx("div", { className: "modal-more", children: _jsx("button", { type: "button", className: "btn", disabled: loading, onClick: () => {
124
+ }, children: [items.length === 0 && !loading ? (_jsx("p", { className: "d-empty", children: "Nothing here yet \u2014 drop images anywhere on this panel to upload." })) : (_jsx("div", { className: "media-grid", children: items.map((item) => (_jsxs("button", { type: "button", className: "media-card", onClick: () => openDetail(item), children: [item.thumbUrl || item.url ? (_jsx("img", { src: item.thumbUrl || item.url, alt: "", loading: "lazy" })) : (_jsx("span", { className: "pick-blank" })), _jsxs("span", { className: "media-meta", children: [_jsx("span", { className: "media-alt", children: item.alt || item.filename || "Image" }), _jsxs("span", { className: "media-sub", children: [item.width && item.height ? `${item.width}×${item.height}` : "—", " \u00B7 ", kb(item.filesize)] })] })] }, item.id))) })), hasMore ? (_jsx("div", { className: "modal-more", children: _jsx("button", { type: "button", className: "btn", disabled: loading, onClick: () => {
108
125
  const next = page + 1;
109
126
  setPage(next);
110
127
  load(next, query, true);
@@ -1 +1 @@
1
- {"version":3,"file":"MediaPicker.d.ts","sourceRoot":"","sources":["../../../app/components/admin/MediaPicker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,OAAO,EACP,QAAQ,EACR,KAAyB,GAC1B,EAAE,gBAAgB,sCAyMlB"}
1
+ {"version":3,"file":"MediaPicker.d.ts","sourceRoot":"","sources":["../../../app/components/admin/MediaPicker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,OAAO,EACP,QAAQ,EACR,KAAyB,GAC1B,EAAE,gBAAgB,sCAgNlB"}
@@ -56,8 +56,14 @@ export function MediaPicker({ open, brandId, onClose, onSelect, title = "Choose
56
56
  setUploading(true);
57
57
  const res = await store.uploadMedia(files, brandId);
58
58
  setUploading(false);
59
- if (!res.ok)
60
- setError(res.error ?? "Upload failed");
59
+ if (!res.ok) {
60
+ setError(res.error ?? "Upload failed. Please try again.");
61
+ return;
62
+ }
63
+ setItems((prev) => {
64
+ const ids = new Set(res.images.map((i) => i.id));
65
+ return [...res.images, ...prev.filter((p) => !ids.has(p.id))];
66
+ });
61
67
  load(1, query, false);
62
68
  setPage(1);
63
69
  const last = res.images[res.images.length - 1];
@@ -78,7 +84,7 @@ export function MediaPicker({ open, brandId, onClose, onSelect, title = "Choose
78
84
  setDragging(false);
79
85
  if (e.dataTransfer.files?.length)
80
86
  void upload(e.dataTransfer.files);
81
- }, children: [items.length === 0 && !loading ? (_jsx("p", { className: "d-empty", children: "Nothing in the library yet. Drop an image here, or press Upload." })) : (_jsx("div", { className: "pick-grid", children: items.map((item) => (_jsxs("button", { type: "button", className: `pick${selected?.id === item.id ? " is-picked" : ""}`, onClick: () => setSelected(item), onDoubleClick: () => onSelect(item), children: [item.thumbUrl ? (_jsx("img", { src: item.thumbUrl, alt: "", loading: "lazy" })) : (_jsx("span", { className: "pick-blank" })), _jsxs("span", { className: "pick-meta", children: [_jsx("span", { className: `pick-alt${item.alt ? "" : " is-missing"}`, children: item.alt || "Image" }), _jsxs("span", { className: "pick-sub", children: [item.width && item.height ? `${item.width}×${item.height}` : "—", " \u00B7", " ", kb(item.filesize)] })] })] }, item.id))) })), hasMore ? (_jsx("div", { className: "modal-more", children: _jsx("button", { type: "button", className: "btn", disabled: loading, onClick: () => {
87
+ }, children: [items.length === 0 && !loading ? (_jsx("p", { className: "d-empty", children: "Nothing in the library yet. Drop an image here, or press Upload." })) : (_jsx("div", { className: "pick-grid", children: items.map((item) => (_jsxs("button", { type: "button", className: `pick${selected?.id === item.id ? " is-picked" : ""}`, onClick: () => setSelected(item), onDoubleClick: () => onSelect(item), children: [item.thumbUrl || item.url ? (_jsx("img", { src: item.thumbUrl || item.url, alt: "", loading: "lazy" })) : (_jsx("span", { className: "pick-blank" })), _jsxs("span", { className: "pick-meta", children: [_jsx("span", { className: `pick-alt${item.alt ? "" : " is-missing"}`, children: item.alt || "Image" }), _jsxs("span", { className: "pick-sub", children: [item.width && item.height ? `${item.width}×${item.height}` : "—", " \u00B7", " ", kb(item.filesize)] })] })] }, item.id))) })), hasMore ? (_jsx("div", { className: "modal-more", children: _jsx("button", { type: "button", className: "btn", disabled: loading, onClick: () => {
82
88
  const next = page + 1;
83
89
  setPage(next);
84
90
  load(next, query, true);
@@ -1 +1 @@
1
- {"version":3,"file":"PostList.d.ts","sourceRoot":"","sources":["../../../app/components/admin/PostList.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAsBlE,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EACvB,WAAmB,EACnB,MAAM,EACN,MAAM,EACN,YAAY,GACb,EAAE;IACD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAC9C,+BA0LA"}
1
+ {"version":3,"file":"PostList.d.ts","sourceRoot":"","sources":["../../../app/components/admin/PostList.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAwBlE,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EACvB,WAAmB,EACnB,MAAM,EACN,MAAM,EACN,YAAY,GACb,EAAE;IACD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAC9C,+BAqMA"}
@@ -17,7 +17,9 @@ const SORTS = [
17
17
  { key: "title", label: "Title A–Z" },
18
18
  { key: "oldest", label: "Oldest first" },
19
19
  ];
20
- const PER_PAGE = 20;
20
+ /** Rows per page in the posts table (BlogUploader-style lists use ~10–20). */
21
+ const PER_PAGE = 10;
22
+ const MIN_TABLE_ROWS = 10;
21
23
  export function PostList({ filterState = "all", onEdit, onView, onMetaChange, }) {
22
24
  const store = useAdminMock();
23
25
  const [tab, setTab] = useState(filterState);
@@ -35,6 +37,11 @@ export function PostList({ filterState = "all", onEdit, onView, onMetaChange, })
35
37
  setSort("published");
36
38
  setSortDraft("published");
37
39
  }
40
+ else {
41
+ // All Posts / drafts / etc. — recent edits, not published-only sort
42
+ setSort("recent");
43
+ setSortDraft("recent");
44
+ }
38
45
  }, [filterState]);
39
46
  const counts = store.postCounts();
40
47
  const categories = store.terms("categories");
@@ -63,6 +70,8 @@ export function PostList({ filterState = "all", onEdit, onView, onMetaChange, })
63
70
  onMetaChange?.({ total: rows.length, search });
64
71
  }, [rows.length, search, onMetaChange]);
65
72
  const totalPages = Math.max(1, Math.ceil(rows.length / PER_PAGE));
73
+ const pageStart = rows.length === 0 ? 0 : (page - 1) * PER_PAGE + 1;
74
+ const pageEnd = Math.min(page * PER_PAGE, rows.length);
66
75
  const pageRows = rows.slice((page - 1) * PER_PAGE, page * PER_PAGE);
67
76
  const showBrand = !store.activeBrandId && store.brands.length > 1;
68
77
  const isTrash = tab === "trash";
@@ -89,5 +98,5 @@ export function PostList({ filterState = "all", onEdit, onView, onMetaChange, })
89
98
  }, children: [t.label, _jsx("span", { className: "tab-count", children: counts[t.key] ?? 0 })] }, t.key))) }), _jsxs("form", { className: "filterbar", onSubmit: (e) => {
90
99
  e.preventDefault();
91
100
  applyFilters();
92
- }, children: [_jsx("input", { className: "fld", type: "search", name: "q", placeholder: "Search titles\u2026", value: searchDraft, onChange: (e) => setSearchDraft(e.target.value), "aria-label": "Search post titles" }), _jsxs("select", { className: "fld", name: "cat", "aria-label": "Filter by category", value: categoryDraft, onChange: (e) => setCategoryDraft(e.target.value), children: [_jsx("option", { value: "", children: "All categories" }), categories.map((c) => (_jsx("option", { value: c.id, children: c.name }, c.id)))] }), _jsx("select", { className: "fld", name: "sort", "aria-label": "Sort", value: sortDraft, onChange: (e) => setSortDraft(e.target.value), children: SORTS.map((s) => (_jsx("option", { value: s.key, children: s.label }, s.key))) }), _jsx("button", { className: "btn", type: "submit", children: "Filter" }), search || categoryId ? (_jsx("button", { type: "button", className: "btn btn-ghost", onClick: clearFilters, children: "Clear" })) : null] }), isTrash ? (_jsxs("p", { className: "explain", children: ["Trashed posts are ", _jsx("b", { children: "soft-deleted" }), ": they keep their versions, their slug and their redirects, and no ordinary query returns them. Restoring one puts it back exactly as it was. Deleting permanently is a brand-admin action and cannot be undone."] })) : null, _jsx("section", { className: "panel", children: _jsx(PostsTable, { rows: pageRows, categories: categories, state: tab, showBrand: showBrand, onEdit: onEdit, onView: onView }) }), totalPages > 1 ? (_jsxs("nav", { className: "pager", "aria-label": "Pagination", children: [page > 1 ? (_jsx("button", { type: "button", className: "btn", onClick: () => setPage((p) => p - 1), children: "\u2190 Newer" })) : (_jsx("span", {})), _jsxs("span", { className: "note", children: ["Page ", page, " of ", totalPages] }), page < totalPages ? (_jsx("button", { type: "button", className: "btn", onClick: () => setPage((p) => p + 1), children: "Older \u2192" })) : (_jsx("span", {}))] })) : null] }));
101
+ }, children: [_jsx("input", { className: "fld", type: "search", name: "q", placeholder: "Search titles\u2026", value: searchDraft, onChange: (e) => setSearchDraft(e.target.value), "aria-label": "Search post titles" }), _jsxs("select", { className: "fld", name: "cat", "aria-label": "Filter by category", value: categoryDraft, onChange: (e) => setCategoryDraft(e.target.value), children: [_jsx("option", { value: "", children: "All categories" }), categories.map((c) => (_jsx("option", { value: c.id, children: c.name }, c.id)))] }), _jsx("select", { className: "fld", name: "sort", "aria-label": "Sort", value: sortDraft, onChange: (e) => setSortDraft(e.target.value), children: SORTS.map((s) => (_jsx("option", { value: s.key, children: s.label }, s.key))) }), _jsx("button", { className: "btn", type: "submit", children: "Filter" }), search || categoryId ? (_jsx("button", { type: "button", className: "btn btn-ghost", onClick: clearFilters, children: "Clear" })) : null] }), isTrash ? (_jsxs("p", { className: "explain", children: ["Trashed posts are ", _jsx("b", { children: "soft-deleted" }), ": they keep their versions, their slug and their redirects, and no ordinary query returns them. Restoring one puts it back exactly as it was. Deleting permanently is a brand-admin action and cannot be undone."] })) : null, _jsx("section", { className: "panel", children: _jsx(PostsTable, { rows: pageRows, minRows: MIN_TABLE_ROWS, totalCount: rows.length, page: page, pageSize: PER_PAGE, categories: categories, state: tab, showBrand: showBrand, onEdit: onEdit, onView: onView }) }), rows.length > 0 ? (_jsxs("nav", { className: "pager", "aria-label": "Pagination", children: [page > 1 ? (_jsx("button", { type: "button", className: "btn", onClick: () => setPage((p) => p - 1), children: "\u2190 Newer" })) : (_jsx("span", {})), _jsxs("span", { className: "note", children: ["Showing ", pageStart, "\u2013", pageEnd, " of ", rows.length, totalPages > 1 ? ` · Page ${page} of ${totalPages}` : ""] }), page < totalPages ? (_jsx("button", { type: "button", className: "btn", onClick: () => setPage((p) => p + 1), children: "Older \u2192" })) : (_jsx("span", {}))] })) : null] }));
93
102
  }
@@ -1,6 +1,11 @@
1
1
  import type { PostRow } from "./mock/fixtures";
2
2
  type Props = {
3
3
  rows: PostRow[];
4
+ /** Pad tbody so the list keeps a consistent height (e.g. 10 rows). */
5
+ minRows?: number;
6
+ totalCount?: number;
7
+ page?: number;
8
+ pageSize?: number;
4
9
  categories: {
5
10
  id: string;
6
11
  name: string;
@@ -10,6 +15,6 @@ type Props = {
10
15
  onEdit: (id: string) => void;
11
16
  onView?: (id: string) => void;
12
17
  };
13
- export declare const PostsTable: ({ rows, categories, state, showBrand, onEdit, onView }: Props) => import("react").JSX.Element;
18
+ export declare const PostsTable: ({ rows, minRows, totalCount, page, pageSize, categories, state, showBrand, onEdit, onView, }: Props) => import("react").JSX.Element;
14
19
  export {};
15
20
  //# sourceMappingURL=PostsTable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PostsTable.d.ts","sourceRoot":"","sources":["../../../app/components/admin/PostsTable.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B,CAAC;AAuBF,eAAO,MAAM,UAAU,GAAI,wDAAwD,KAAK,gCA4avF,CAAC"}
1
+ {"version":3,"file":"PostsTable.d.ts","sourceRoot":"","sources":["../../../app/components/admin/PostsTable.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B,CAAC;AAuBF,eAAO,MAAM,UAAU,GAAI,8FAWxB,KAAK,gCA0bP,CAAC"}
@@ -24,7 +24,7 @@ const StateChip = ({ row }) => {
24
24
  const cls = rs === "in-review" ? "chip-review" : rs === "approved" ? "chip-approved" : "chip-writing";
25
25
  return _jsx("span", { className: `chip ${cls}`, children: REVIEW_LABELS[rs] ?? "Draft" });
26
26
  };
27
- export const PostsTable = ({ rows, categories, state, showBrand, onEdit, onView }) => {
27
+ export const PostsTable = ({ rows, minRows = 0, totalCount, page, pageSize, categories, state, showBrand, onEdit, onView, }) => {
28
28
  const store = useAdminMock();
29
29
  const [pending, start] = useTransition();
30
30
  const [selected, setSelected] = useState([]);
@@ -86,7 +86,11 @@ export const PostsTable = ({ rows, categories, state, showBrand, onEdit, onView
86
86
  }
87
87
  run(() => store.bulkPostAction(selected, bulk), `${selected.length} post(s) updated.`);
88
88
  };
89
- return (_jsxs("div", { className: "list", children: [_jsxs("div", { className: "list-bar", children: [_jsxs("div", { className: "bulk", children: [_jsxs("select", { className: "fld fld-sm", value: bulk, onChange: (e) => setBulk(e.target.value), "aria-label": "Bulk action", children: [_jsx("option", { value: "", children: "Bulk actions\u2026" }), isTrash ? (_jsxs(_Fragment, { children: [_jsx("option", { value: "restore", children: "Restore" }), _jsx("option", { value: "delete", children: "Delete permanently" })] })) : (_jsxs(_Fragment, { children: [_jsx("option", { value: "submit", children: "Submit for review" }), _jsx("option", { value: "approve", children: "Approve" }), _jsx("option", { value: "send-back", children: "Send back to writing" }), _jsx("option", { value: "publish", children: "Publish" }), _jsx("option", { value: "draft", children: "Switch to draft" }), _jsx("option", { value: "trash", children: "Move to trash" })] }))] }), _jsx("button", { type: "button", className: "btn", disabled: !bulk || !selected.length || pending, onClick: applyBulk, children: "Apply" }), _jsx("span", { className: "note", children: selected.length ? `${selected.length} selected` : `${rows.length} shown` })] }), pending ? _jsx("span", { className: "note", children: "Working\u2026" }) : null] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl tbl-list", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "col-check", children: _jsx("input", { type: "checkbox", checked: allChecked, "aria-label": "Select all posts", onChange: (e) => setSelected(e.target.checked ? rows.map((r) => r.id) : []) }) }), _jsx("th", { children: "Title" }), showBrand ? _jsx("th", { className: "col-narrow", children: "Brand" }) : null, _jsx("th", { className: "col-narrow", children: "Byline" }), _jsx("th", { className: "col-narrow", children: "Category" }), _jsx("th", { className: "col-narrow", children: "Date" }), _jsx("th", { className: "col-narrow num", children: "Views 30d" }), _jsx("th", { className: "col-narrow", children: "Status" })] }) }), _jsxs("tbody", { children: [rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: showBrand ? 8 : 7, children: _jsx("p", { className: "d-empty", children: "No posts match this view." }) }) })) : null, rows.map((row) => (_jsxs(Fragment, { children: [_jsxs("tr", { className: selected.includes(row.id) ? "is-selected" : undefined, children: [_jsx("td", { className: "col-check", children: _jsx("input", { type: "checkbox", checked: selected.includes(row.id), "aria-label": `Select ${row.title}`, onChange: (e) => setSelected((list) => e.target.checked ? [...list, row.id] : list.filter((id) => id !== row.id)) }) }), _jsxs("td", { className: "col-title", children: [_jsx("button", { type: "button", className: "row-title", onClick: () => onEdit(row.id), children: row.title || "(no title)" }), row.blockers.length && row.status !== "published" && !row.trashed ? (_jsx("ul", { className: "blockers", children: row.blockers.map((b) => (_jsxs("li", { children: ["needs ", b] }, b))) })) : null, _jsx("div", { className: "row-actions", children: isTrash ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => run(() => store.bulkPostAction([row.id], "restore"), "Restored."), children: "Restore" }), _jsx("button", { type: "button", className: "danger", onClick: () => {
89
+ return (_jsxs("div", { className: "list", children: [_jsxs("div", { className: "list-bar", children: [_jsxs("div", { className: "bulk", children: [_jsxs("select", { className: "fld fld-sm", value: bulk, onChange: (e) => setBulk(e.target.value), "aria-label": "Bulk action", children: [_jsx("option", { value: "", children: "Bulk actions\u2026" }), isTrash ? (_jsxs(_Fragment, { children: [_jsx("option", { value: "restore", children: "Restore" }), _jsx("option", { value: "delete", children: "Delete permanently" })] })) : (_jsxs(_Fragment, { children: [_jsx("option", { value: "submit", children: "Submit for review" }), _jsx("option", { value: "approve", children: "Approve" }), _jsx("option", { value: "send-back", children: "Send back to writing" }), _jsx("option", { value: "publish", children: "Publish" }), _jsx("option", { value: "draft", children: "Switch to draft" }), _jsx("option", { value: "trash", children: "Move to trash" })] }))] }), _jsx("button", { type: "button", className: "btn", disabled: !bulk || !selected.length || pending, onClick: applyBulk, children: "Apply" }), _jsx("span", { className: "note", children: selected.length
90
+ ? `${selected.length} selected`
91
+ : totalCount != null && page != null && pageSize != null
92
+ ? `${rows.length} on this page · ${totalCount} total`
93
+ : `${rows.length} shown` })] }), pending ? _jsx("span", { className: "note", children: "Working\u2026" }) : null] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl tbl-list", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "col-check", children: _jsx("input", { type: "checkbox", checked: allChecked, "aria-label": "Select all posts", onChange: (e) => setSelected(e.target.checked ? rows.map((r) => r.id) : []) }) }), _jsx("th", { children: "Title" }), showBrand ? _jsx("th", { className: "col-narrow", children: "Brand" }) : null, _jsx("th", { className: "col-narrow", children: "Byline" }), _jsx("th", { className: "col-narrow", children: "Category" }), _jsx("th", { className: "col-narrow", children: "Date" }), _jsx("th", { className: "col-narrow num", children: "Views 30d" }), _jsx("th", { className: "col-narrow", children: "Status" })] }) }), _jsxs("tbody", { children: [rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: showBrand ? 8 : 7, children: _jsx("p", { className: "d-empty", children: "No posts match this view." }) }) })) : null, rows.map((row) => (_jsxs(Fragment, { children: [_jsxs("tr", { className: selected.includes(row.id) ? "is-selected" : undefined, children: [_jsx("td", { className: "col-check", children: _jsx("input", { type: "checkbox", checked: selected.includes(row.id), "aria-label": `Select ${row.title}`, onChange: (e) => setSelected((list) => e.target.checked ? [...list, row.id] : list.filter((id) => id !== row.id)) }) }), _jsxs("td", { className: "col-title", children: [_jsx("button", { type: "button", className: "row-title", onClick: () => onEdit(row.id), children: row.title || "(no title)" }), row.blockers.length && row.status !== "published" && !row.trashed ? (_jsx("ul", { className: "blockers", children: row.blockers.map((b) => (_jsxs("li", { children: ["needs ", b] }, b))) })) : null, _jsx("div", { className: "row-actions", children: isTrash ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => run(() => store.bulkPostAction([row.id], "restore"), "Restored."), children: "Restore" }), _jsx("button", { type: "button", className: "danger", onClick: () => {
90
94
  if (window.confirm("Delete this post permanently? This cannot be undone.")) {
91
95
  run(() => store.bulkPostAction([row.id], "delete"), "Deleted.");
92
96
  }
@@ -102,5 +106,7 @@ export const PostsTable = ({ rows, categories, state, showBrand, onEdit, onView
102
106
  publishedAt: draft.date ? new Date(draft.date).toISOString() : null,
103
107
  scheduledFor: row.scheduledFor,
104
108
  status: draft.status,
105
- }), "Saved."), children: "Save" }), _jsx("button", { type: "button", className: "btn", onClick: () => setEditing(null), children: "Cancel" }), _jsx("span", { className: "note", children: "Changing the slug of a live post writes a 301 from the old URL automatically." })] })] }) }) })) : null] }, row.id)))] })] }) })] }));
109
+ }), "Saved."), children: "Save" }), _jsx("button", { type: "button", className: "btn", onClick: () => setEditing(null), children: "Cancel" }), _jsx("span", { className: "note", children: "Changing the slug of a live post writes a 301 from the old URL automatically." })] })] }) }) })) : null] }, row.id))), minRows > 0 && rows.length > 0 && rows.length < minRows
110
+ ? Array.from({ length: minRows - rows.length }).map((_, i) => (_jsx("tr", { className: "tbl-row-pad", "aria-hidden": "true", children: _jsx("td", { colSpan: showBrand ? 8 : 7 }) }, `pad-${i}`)))
111
+ : null] })] }) })] }));
106
112
  };
@@ -1,11 +1,13 @@
1
1
  import type { AdminSdkAuthor, AdminSdkBrand, AdminSdkCategory, AdminSdkComment, AdminSdkMe, AdminSdkMedia, AdminSdkPost, AdminSdkTag } from "../../../services/admin-sdk-client";
2
2
  import type { BrandForm, CommentRow, MediaHit, MockProfile, PostRow, TermRow } from "../mock/fixtures";
3
+ /** Turn API-relative `/media/...` paths into absolute URLs for `<img src>`. */
4
+ export declare function resolveMediaUrl(url: string | null | undefined, apiBaseUrl?: string): string;
3
5
  export declare function mapAdminMeToProfile(me: AdminSdkMe): MockProfile;
4
6
  export declare function mapBrandToForm(brand: AdminSdkBrand): BrandForm;
5
7
  export declare function mapCategoryToTerm(cat: AdminSdkCategory): TermRow;
6
8
  export declare function mapTagToTerm(tag: AdminSdkTag): TermRow;
7
9
  export declare function mapAuthorToTerm(author: AdminSdkAuthor): TermRow;
8
- export declare function mapMediaToHit(media: AdminSdkMedia): MediaHit;
10
+ export declare function mapMediaToHit(media: AdminSdkMedia, apiBaseUrl?: string): MediaHit;
9
11
  export declare function mapPostToRow(post: AdminSdkPost, brands: BrandForm[], categories: TermRow[], tags?: TermRow[], authors?: TermRow[]): PostRow;
10
12
  export declare function mapCommentToRow(comment: AdminSdkComment, posts: PostRow[], brands: BrandForm[]): CommentRow;
11
13
  export declare function postRowToWrite(input: Partial<PostRow> & {
@@ -1 +1 @@
1
- {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../../app/components/admin/api/mappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACZ,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAKvG,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,UAAU,GAAG,WAAW,CAO/D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAgB9D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAWhE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAWtD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAW/D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,CAe5D;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,SAAS,EAAE,EACnB,UAAU,EAAE,OAAO,EAAE,EACrB,IAAI,GAAE,OAAO,EAAO,EACpB,OAAO,GAAE,OAAO,EAAO,GACtB,OAAO,CAsDT;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,OAAO,EAAE,EAChB,MAAM,EAAE,SAAS,EAAE,GAClB,UAAU,CAgBZ;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC5D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;EAyB7E"}
1
+ {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../../app/components/admin/api/mappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACZ,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAKvG,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAO3F;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,UAAU,GAAG,WAAW,CAO/D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAgB9D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAWhE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAWtD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAW/D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAiBjF;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,SAAS,EAAE,EACnB,UAAU,EAAE,OAAO,EAAE,EACrB,IAAI,GAAE,OAAO,EAAO,EACpB,OAAO,GAAE,OAAO,EAAO,GACtB,OAAO,CAsDT;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,OAAO,EAAE,EAChB,MAAM,EAAE,SAAS,EAAE,GAClB,UAAU,CAgBZ;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC5D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;EAyB7E"}
@@ -1,4 +1,17 @@
1
1
  const asIso = (value) => (value ? String(value) : null);
2
+ /** Turn API-relative `/media/...` paths into absolute URLs for `<img src>`. */
3
+ export function resolveMediaUrl(url, apiBaseUrl) {
4
+ if (!url)
5
+ return "";
6
+ if (/^(https?:|data:|blob:)/i.test(url))
7
+ return url;
8
+ if (!apiBaseUrl)
9
+ return url;
10
+ const origin = apiBaseUrl.replace(/\/api\/v\d+\/?$/i, "").replace(/\/+$/, "");
11
+ if (!origin)
12
+ return url;
13
+ return url.startsWith("/") ? `${origin}${url}` : `${origin}/${url}`;
14
+ }
2
15
  export function mapAdminMeToProfile(me) {
3
16
  return {
4
17
  id: me.id,
@@ -60,11 +73,13 @@ export function mapAuthorToTerm(author) {
60
73
  brandId: author.brandId ?? "",
61
74
  };
62
75
  }
63
- export function mapMediaToHit(media) {
76
+ export function mapMediaToHit(media, apiBaseUrl) {
77
+ const url = resolveMediaUrl(media.url, apiBaseUrl);
78
+ const thumbUrl = resolveMediaUrl(media.thumbUrl || media.url, apiBaseUrl);
64
79
  return {
65
80
  id: media.id,
66
- url: media.url,
67
- thumbUrl: media.thumbUrl || media.url,
81
+ url,
82
+ thumbUrl: thumbUrl || url,
68
83
  alt: media.alt ?? media.originalFilename ?? media.filename ?? "",
69
84
  filename: media.originalFilename || media.filename,
70
85
  width: media.width ?? null,
@@ -1 +1 @@
1
- {"version":3,"file":"PostEditor.d.ts","sourceRoot":"","sources":["../../../../app/components/admin/editor/PostEditor.tsx"],"names":[],"mappings":"AAwBA,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,MAAM,GACP,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,+BA6iCA"}
1
+ {"version":3,"file":"PostEditor.d.ts","sourceRoot":"","sources":["../../../../app/components/admin/editor/PostEditor.tsx"],"names":[],"mappings":"AAwBA,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,MAAM,GACP,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,+BAkkCA"}
@@ -43,10 +43,16 @@ export function PostEditor({ postId, onDone, }) {
43
43
  const [publishedAt, setPublishedAt] = useState(existing?.publishedAt ?? null);
44
44
  const [scheduleWhen, setScheduleWhen] = useState("");
45
45
  const [featuredImage, setFeaturedImage] = useState(() => {
46
- if (!existing?.featuredImageId)
46
+ const ref = existing?.featuredImageId;
47
+ if (!ref)
47
48
  return null;
48
- const hit = store.listMedia(brandId || null, "", 1, 200).items.find((m) => m.id === existing.featuredImageId);
49
- return hit ? { id: hit.id, url: hit.url, alt: hit.alt } : null;
49
+ const hit = store.listMedia(brandId || null, "", 1, 200).items.find((m) => m.id === ref || m.url === ref);
50
+ if (hit)
51
+ return { id: hit.id, url: hit.url, alt: hit.alt };
52
+ if (/^(https?:|data:|blob:|\/)/i.test(ref)) {
53
+ return { id: ref, url: ref, alt: "" };
54
+ }
55
+ return null;
50
56
  });
51
57
  const [seo, setSeo] = useState({
52
58
  metaTitle: existing?.seo.metaTitle ?? "",
@@ -186,60 +192,76 @@ export function PostEditor({ postId, onDone, }) {
186
192
  }
187
193
  start(() => {
188
194
  void (async () => {
189
- const createdTagIds = [];
190
- for (const name of newTags) {
191
- const term = await Promise.resolve(store.saveTerm({ collection: "tags", brandId, name }));
192
- if (term.ok && term.id)
193
- createdTagIds.push(term.id);
194
- }
195
- const mergedTagIds = [...tagIds, ...createdTagIds];
196
- const res = await Promise.resolve(store.savePost({
197
- id: existing?.id,
198
- title,
199
- slug: slug || slugify(title),
200
- brandId,
201
- excerpt,
202
- contentHtml,
203
- status: nextStatus,
204
- reviewState: nextReview,
205
- categoryIds,
206
- tagIds: mergedTagIds,
207
- authorIds,
208
- scheduledFor: nextScheduled,
209
- publishedAt: nextPublished,
210
- featuredImageId: featuredImage?.id ?? null,
211
- allowComments,
212
- visibility,
213
- template,
214
- authorBox,
215
- showInTableOfContents: showToc,
216
- postFormat,
217
- seo: {
218
- metaTitle: seo.metaTitle,
219
- metaDescription: seo.metaDescription,
220
- focusKeyphrase: seo.focusKeyphrase,
221
- noindex: seo.noindex,
222
- },
223
- }));
224
- if (!res.ok) {
225
- setError(res.error ?? "Save failed");
226
- return;
195
+ try {
196
+ const createdTagIds = [];
197
+ for (const name of newTags) {
198
+ const term = await Promise.resolve(store.saveTerm({ collection: "tags", brandId, name }));
199
+ if (!term.ok) {
200
+ setError(term.error ?? "Could not create tag.");
201
+ return;
202
+ }
203
+ if (term.id)
204
+ createdTagIds.push(term.id);
205
+ }
206
+ const mergedTagIds = [...tagIds, ...createdTagIds];
207
+ const res = await Promise.resolve(store.savePost({
208
+ id: existing?.id,
209
+ title,
210
+ slug: slug || slugify(title),
211
+ brandId,
212
+ excerpt,
213
+ contentHtml,
214
+ status: nextStatus,
215
+ reviewState: nextReview,
216
+ categoryIds,
217
+ tagIds: mergedTagIds,
218
+ authorIds,
219
+ scheduledFor: nextScheduled,
220
+ publishedAt: nextPublished,
221
+ // Backend stores a public image URL in featured_image
222
+ featuredImageId: featuredImage?.url ?? featuredImage?.id ?? null,
223
+ allowComments,
224
+ visibility,
225
+ template,
226
+ authorBox,
227
+ showInTableOfContents: showToc,
228
+ postFormat,
229
+ seo: {
230
+ metaTitle: seo.metaTitle,
231
+ metaDescription: seo.metaDescription,
232
+ focusKeyphrase: seo.focusKeyphrase,
233
+ noindex: seo.noindex,
234
+ },
235
+ }));
236
+ if (!res.ok) {
237
+ setError(res.error ?? "Failed to save post. Please try again.");
238
+ return;
239
+ }
240
+ if (createdTagIds.length) {
241
+ setTagIds(mergedTagIds);
242
+ setNewTags([]);
243
+ }
244
+ setStatus(nextStatus);
245
+ setReviewState(nextReview);
246
+ setScheduledFor(nextScheduled);
247
+ setPublishedAt(nextPublished);
248
+ const successMsg = intent === "publish"
249
+ ? existing?.id
250
+ ? "Post published successfully."
251
+ : "Post created and published successfully."
252
+ : intent === "schedule"
253
+ ? "Post scheduled successfully."
254
+ : intent === "unpublish"
255
+ ? "Post unpublished."
256
+ : existing?.id
257
+ ? "Post updated successfully."
258
+ : "Post created successfully.";
259
+ setFlash(successMsg);
260
+ window.setTimeout(() => onDone(), 900);
227
261
  }
228
- if (createdTagIds.length) {
229
- setTagIds(mergedTagIds);
230
- setNewTags([]);
262
+ catch (err) {
263
+ setError(err instanceof Error ? err.message : "Failed to save post. Please try again.");
231
264
  }
232
- setStatus(nextStatus);
233
- setReviewState(nextReview);
234
- setScheduledFor(nextScheduled);
235
- setPublishedAt(nextPublished);
236
- setFlash(intent === "publish"
237
- ? "Published."
238
- : intent === "schedule"
239
- ? "Scheduled."
240
- : intent === "unpublish"
241
- ? "Unpublished."
242
- : "Saved.");
243
265
  })();
244
266
  });
245
267
  };
@@ -275,14 +297,16 @@ export function PostEditor({ postId, onDone, }) {
275
297
  const uploadFeatured = async (files) => {
276
298
  setFeaturedBusy(true);
277
299
  setError(null);
300
+ setFlash(null);
278
301
  const res = await store.uploadMedia(files, brandId || null);
279
302
  setFeaturedBusy(false);
280
303
  if (!res.ok || !res.images[0]) {
281
- setError(res.error ?? "Upload failed");
304
+ setError(res.error ?? "Image upload failed. Please try again.");
282
305
  return;
283
306
  }
284
307
  const img = res.images[0];
285
308
  setFeaturedImage({ id: img.id, url: img.url, alt: img.alt });
309
+ setFlash("Image uploaded successfully.");
286
310
  };
287
311
  const choosePicked = (item) => {
288
312
  if (pickerFor === "og") {
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../app/components/admin/mock/store.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../app/components/admin/mock/store.tsx"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
3
3
  import { AdminSdkClient } from "../../../services/admin-sdk-client";
4
4
  import { getErrorMessage } from "../../../services/errors";
5
- import { mapAdminMeToProfile, mapAuthorToTerm, mapBrandToForm, mapCategoryToTerm, mapCommentToRow, mapMediaToHit, mapPostToRow, mapTagToTerm, postRowToWrite, } from "../api/mappers";
5
+ import { mapAdminMeToProfile, mapAuthorToTerm, mapBrandToForm, mapCategoryToTerm, mapCommentToRow, mapMediaToHit, mapPostToRow, mapTagToTerm, postRowToWrite, resolveMediaUrl, } from "../api/mappers";
6
6
  import { createInitialFixtures, nextId, slugify, } from "./fixtures";
7
7
  const syncTermCounts = (state) => {
8
8
  const countFor = (collection, termId) => state.posts.filter((p) => {
@@ -42,6 +42,7 @@ const AdminMockContext = createContext(null);
42
42
  const matchesPostFilter = (post, state) => {
43
43
  switch (state) {
44
44
  case "all":
45
+ // Every non-trashed post: drafts, in-review, scheduled, and published (not live-only).
45
46
  return !post.trashed;
46
47
  case "trash":
47
48
  return post.trashed;
@@ -52,7 +53,7 @@ const matchesPostFilter = (post, state) => {
52
53
  case "review":
53
54
  return !post.trashed && post.status === "draft" && post.reviewState === "in-review";
54
55
  case "scheduled":
55
- return !post.trashed && !!post.scheduledFor && post.status === "draft";
56
+ return !post.trashed && !!post.scheduledFor && post.status !== "published";
56
57
  case "attention":
57
58
  return (!post.trashed &&
58
59
  post.status === "draft" &&
@@ -95,7 +96,7 @@ export function AdminMockProvider({ children, config, }) {
95
96
  const [me, brandsPage, postsPage, catsPage, tagsPage, authorsPage, mediaPage, commentsPage] = await Promise.all([
96
97
  api.me(),
97
98
  api.listBrands({ pageSize: 100 }),
98
- api.listPosts({ pageSize: 100, includeTrash: true }),
99
+ api.listPostsAll({ pageSize: 100, includeTrash: true }),
99
100
  api.listCategories({ pageSize: 100 }),
100
101
  api.listTags({ pageSize: 100 }),
101
102
  api.listAuthors({ pageSize: 100 }),
@@ -106,8 +107,14 @@ export function AdminMockProvider({ children, config, }) {
106
107
  const categories = catsPage.items.map(mapCategoryToTerm);
107
108
  const tags = tagsPage.items.map(mapTagToTerm);
108
109
  const authors = authorsPage.items.map(mapAuthorToTerm);
109
- const media = mediaPage.items.map(mapMediaToHit);
110
- const posts = postsPage.items.map((p) => mapPostToRow(p, brands, categories, tags, authors));
110
+ const media = mediaPage.items.map((m) => mapMediaToHit(m, config.apiUrl));
111
+ const posts = postsPage.items.map((p) => {
112
+ const row = mapPostToRow(p, brands, categories, tags, authors);
113
+ if (row.featuredImageId) {
114
+ row.featuredImageId = resolveMediaUrl(row.featuredImageId, config.apiUrl);
115
+ }
116
+ return row;
117
+ });
111
118
  const comments = commentsPage.items.map((c) => mapCommentToRow(c, posts, brands));
112
119
  const profile = mapAdminMeToProfile(me);
113
120
  const domainHint = config.domain?.trim().toLowerCase().replace(/^www\./, "") ?? "";
@@ -630,9 +637,10 @@ export function AdminMockProvider({ children, config, }) {
630
637
  const images = [];
631
638
  for (const file of list) {
632
639
  const saved = await api.uploadMedia(file, brand);
633
- images.push(mapMediaToHit(saved));
640
+ images.push(mapMediaToHit(saved, config?.apiUrl));
634
641
  }
635
642
  await refreshFromApi();
643
+ // Prefer freshly mapped upload results (already absolute URLs)
636
644
  return { ok: true, images };
637
645
  }
638
646
  catch (error) {
@@ -666,7 +674,7 @@ export function AdminMockProvider({ children, config, }) {
666
674
  }
667
675
  update((prev) => ({ ...prev, media: [...images, ...prev.media] }));
668
676
  return { ok: true, images };
669
- }, [activeBrandId, data.brands, update, refreshFromApi]);
677
+ }, [activeBrandId, data.brands, update, refreshFromApi, config?.apiUrl]);
670
678
  const updateMedia = useCallback((id, meta) => {
671
679
  if (!meta.alt.trim())
672
680
  return { ok: false, error: "Alt text is required." };
@@ -1 +1 @@
1
- {"version":3,"file":"BlogAdmin.d.ts","sourceRoot":"","sources":["../../../app/pages/admin/BlogAdmin.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAuB9E,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA8WF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,+BAM/E"}
1
+ {"version":3,"file":"BlogAdmin.d.ts","sourceRoot":"","sources":["../../../app/pages/admin/BlogAdmin.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAuB9E,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA6XF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,+BAM/E"}
@@ -28,6 +28,8 @@ function BlogAdminInner({ theme, branding, className, }) {
28
28
  const [viewingId, setViewingId] = useState(undefined);
29
29
  const [redirectId, setRedirectId] = useState(undefined);
30
30
  const [settingsBrandId, setSettingsBrandId] = useState(undefined);
31
+ /** Bumps when opening a posts list so tab state resets (e.g. All Posts → not stuck on Published). */
32
+ const [postsListKey, setPostsListKey] = useState(0);
31
33
  const openEditor = (id) => {
32
34
  setViewingId(undefined);
33
35
  setEditingId(id);
@@ -38,11 +40,18 @@ function BlogAdminInner({ theme, branding, className, }) {
38
40
  setViewingId(id);
39
41
  };
40
42
  const navigate = (key) => {
41
- setActiveNav(key);
42
- if (key !== "posts-new")
43
+ const next = key === "posts" ? "posts-all" : key;
44
+ setActiveNav(next);
45
+ if (next === "posts-all" ||
46
+ next === "attention" ||
47
+ next === "scheduled" ||
48
+ next === "trash") {
49
+ setPostsListKey((n) => n + 1);
50
+ }
51
+ if (next !== "posts-new")
43
52
  setEditingId(undefined);
44
53
  setViewingId(undefined);
45
- if (key !== "redirects-new" && key !== "redirects-all" && key !== "redirects") {
54
+ if (next !== "redirects-new" && next !== "redirects-all" && next !== "redirects") {
46
55
  setRedirectId(undefined);
47
56
  }
48
57
  };
@@ -53,6 +62,7 @@ function BlogAdminInner({ theme, branding, className, }) {
53
62
  return "scheduled";
54
63
  if (nav === "trash")
55
64
  return "trash";
65
+ // posts / posts-all → every non-trashed status (draft, review, scheduled, published)
56
66
  return "all";
57
67
  };
58
68
  const requireBrand = (title, render) => {
@@ -114,12 +124,14 @@ function BlogAdminInner({ theme, branding, className, }) {
114
124
  return (_jsx(AdminPostDetail, { postId: viewingId, onBack: () => {
115
125
  setViewingId(undefined);
116
126
  setActiveNav("posts-all");
127
+ setPostsListKey((n) => n + 1);
117
128
  }, onEdit: (id) => openEditor(id), onViewRelated: (id) => setViewingId(id) }));
118
129
  }
119
130
  if (activeNav === "posts-new" || editingId) {
120
131
  return (_jsx(PostEditor, { postId: editingId, onDone: () => {
121
132
  setEditingId(undefined);
122
133
  setActiveNav("posts-all");
134
+ setPostsListKey((n) => n + 1);
123
135
  } }));
124
136
  }
125
137
  if (activeNav === "posts" ||
@@ -127,7 +139,7 @@ function BlogAdminInner({ theme, branding, className, }) {
127
139
  activeNav === "attention" ||
128
140
  activeNav === "scheduled" ||
129
141
  activeNav === "trash") {
130
- return (_jsx(PostList, { filterState: postFilterForNav(activeNav), onCreate: () => openEditor(), onEdit: (id) => openEditor(id), onView: (id) => openView(id) }));
142
+ return (_jsx(PostList, { filterState: postFilterForNav(activeNav), onCreate: () => openEditor(), onEdit: (id) => openEditor(id), onView: (id) => openView(id) }, `${activeNav}-${postsListKey}`));
131
143
  }
132
144
  switch (activeNav) {
133
145
  case "overview":
@@ -174,6 +174,15 @@ export declare class AdminSdkClient {
174
174
  categoryId?: string;
175
175
  includeTrash?: boolean;
176
176
  }): Promise<Paginated<AdminSdkPost>>;
177
+ /** Load every page until `total` is reached (admin list caps at 100/page). */
178
+ listPostsAll(params?: {
179
+ pageSize?: number;
180
+ brandId?: string;
181
+ status?: string;
182
+ q?: string;
183
+ categoryId?: string;
184
+ includeTrash?: boolean;
185
+ }): Promise<Paginated<AdminSdkPost>>;
177
186
  getPost(id: string): Promise<AdminSdkPost>;
178
187
  createPost(data: AdminPostWrite): Promise<AdminSdkPost>;
179
188
  updatePost(id: string, data: Partial<AdminPostWrite>): Promise<AdminSdkPost>;
@@ -1 +1 @@
1
- {"version":3,"file":"admin-sdk-client.d.ts","sourceRoot":"","sources":["../../app/services/admin-sdk-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEhE,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;CAC9E,CAAC;AAWF;;;GAGG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,qBAAqB;IAE1D,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,OAAO;IAOf,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC;IAInB,UAAU,CAAC,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAC3F,SAAS,CAAC,aAAa,CAAC,CACzB;IASD,WAAW,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAOnG,SAAS,CACb,MAAM,GAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,OAAO,CAAC;KACnB,GACL,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAiBnC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI1C,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAOvD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IAO5E,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAOrE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAM9C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAM1C,cAAc,CAClB,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/F,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAevC,cAAc,CAAC,IAAI,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO7B,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,GACD,OAAO,CAAC,gBAAgB,CAAC;IAO5B,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAMpD,YAAY,CAChB,MAAM,GAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACZ,GACL,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAetC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC;IAOnG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,QAAQ,CACZ,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/F,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAelC,SAAS,CAAC,IAAI,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,WAAW,CAAC;IAOxB,SAAS,CACP,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,GACD,OAAO,CAAC,WAAW,CAAC;IAOvB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAO/C,WAAW,CACf,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/F,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAerC,YAAY,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,cAAc,CAAC;IAO3B,YAAY,CACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,GACD,OAAO,CAAC,cAAc,CAAC;IAO1B,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAOlD,SAAS,CACb,MAAM,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAO,GAC9E,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAcpC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAUhE,WAAW,CACT,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,GACD,OAAO,CAAC,aAAa,CAAC;IAOzB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzC,iFAAiF;IAC3E,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;CAmB1E"}
1
+ {"version":3,"file":"admin-sdk-client.d.ts","sourceRoot":"","sources":["../../app/services/admin-sdk-client.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,23 @@ export class AdminSdkClient {
59
59
  })}`);
60
60
  return normalizePage(payload, page, pageSize);
61
61
  }
62
+ /** Load every page until `total` is reached (admin list caps at 100/page). */
63
+ async listPostsAll(params = {}) {
64
+ const pageSize = Math.min(params.pageSize ?? 100, 100);
65
+ let page = 1;
66
+ const items = [];
67
+ let total = 0;
68
+ for (;;) {
69
+ const batch = await this.listPosts({ ...params, page, pageSize });
70
+ total = batch.total;
71
+ items.push(...batch.items);
72
+ if (items.length >= total || batch.items.length === 0) {
73
+ break;
74
+ }
75
+ page += 1;
76
+ }
77
+ return { items, page: 1, pageSize: items.length || pageSize, total: total || items.length };
78
+ }
62
79
  getPost(id) {
63
80
  return this.request(`/admin/posts/${encodeURIComponent(id)}`);
64
81
  }
package/dist/style.css CHANGED
@@ -528,6 +528,13 @@ table.tbl { width: 100%; min-width: 560px; border-collapse: collapse; font-size:
528
528
  position: sticky; top: 0; z-index: 1;
529
529
  }
530
530
  .tbl tbody tr:last-child td { border-bottom: 0; }
531
+ .tbl tbody tr.tbl-row-pad td {
532
+ height: 44px;
533
+ padding-top: 11px;
534
+ padding-bottom: 11px;
535
+ border-bottom: 1px solid var(--d-rule-2);
536
+ }
537
+ .tbl tbody tr.tbl-row-pad:hover { background: transparent; }
531
538
  .tbl tbody tr:hover { background: var(--d-surface-2); }
532
539
  .tbl tbody tr.is-selected { background: var(--d-accent-soft); }
533
540
  .tbl td.num, .tbl th.num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canvas-digital/blog-sdk",
3
- "version": "2.0.1",
3
+ "version": "2.0.4",
4
4
  "description": "Unified Blog SDK — user (published blogs) and admin (CRUD) in one package.",
5
5
  "license": "MIT",
6
6
  "type": "module",