diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b274d2..ac40fad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,19 @@ jobs: with: dotnet-version: 8.0.x + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install client dependencies + run: npm ci + working-directory: src/Client + + - name: Build client assets + run: npm run build + working-directory: src/Client + - name: Restore dependencies run: dotnet restore diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dae5576..e01b02b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,6 +20,19 @@ jobs: with: dotnet-version: 8.0.x + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install client dependencies + run: npm ci + working-directory: src/Client + + - name: Build client assets + run: npm run build + working-directory: src/Client + - name: Restore dependencies run: dotnet restore diff --git a/.gitignore b/.gitignore index 6809986..caadb66 100644 --- a/.gitignore +++ b/.gitignore @@ -400,6 +400,9 @@ FodyWeavers.xsd # Exclude the entire .idea folder for JetBrains IDEs .idea/ +# Client build artifacts +src/Client/dist/* + # Include specific project configuration files !.idea/misc.xml !.idea/modules.xml diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22 diff --git a/src/Client/dist/entry.kxh.2f8ca3a4baf4f24f2fb3.js b/src/Client/dist/entry.kxh.2f8ca3a4baf4f24f2fb3.js deleted file mode 100644 index ade17ea..0000000 --- a/src/Client/dist/entry.kxh.2f8ca3a4baf4f24f2fb3.js +++ /dev/null @@ -1 +0,0 @@ -System.register(["react","@kentico/xperience-admin-components","@kentico/xperience-admin-base"],(function(e,t){var a={},r={},o={};return{setters:[function(e){a.default=e.default||e,a.useState=e.useState},function(e){r.Button=e.Button,r.ButtonColor=e.ButtonColor,r.ButtonSize=e.ButtonSize,r.Card=e.Card,r.Column=e.Column,r.Headline=e.Headline,r.HeadlineSize=e.HeadlineSize,r.Icon=e.Icon,r.Row=e.Row,r.Spacing=e.Spacing,r.Stack=e.Stack},function(e){o.usePageCommand=e.usePageCommand}],execute:function(){e((()=>{var e={90:e=>{"use strict";e.exports=o},126:(e,t,a)=>{const r=a(358).y;t.w=function(e){if(e||(e=1),!a.y.meta||!a.y.meta.url)throw console.error("__system_context__",a.y),Error("systemjs-webpack-interop was provided an unknown SystemJS context. Expected context.meta.url, but none was provided");a.p=r(a.y.meta.url,e)}},267:e=>{"use strict";e.exports=r},358:(e,t,a)=>{t.y=function(e,t){var a=document.createElement("a");a.href=e;for(var r="/"===a.pathname[0]?a.pathname:"/"+a.pathname,o=0,n=r.length;o!==t&&n>=0;)"/"===r[--n]&&o++;if(o!==t)throw Error("systemjs-webpack-interop: rootDirectoryLevel ("+t+") is greater than the number of directories ("+o+") in the URL path "+e);var l=r.slice(0,n+1);return a.protocol+"//"+a.host+l};Number.isInteger},726:e=>{"use strict";e.exports=a}},n={};function l(t){var a=n[t];if(void 0!==a)return a.exports;var r=n[t]={exports:{}};return e[t](r,r.exports,l),r.exports}l.y=t,l.d=(e,t)=>{for(var a in t)l.o(t,a)&&!l.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},l.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),l.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.p="";var i={};return(0,l(126).w)(1),(()=>{"use strict";l.r(i),l.d(i,{SustainabilityDashboardTemplate:()=>t,SustainabilityTabTemplate:()=>h});var e=l(726);const t=({label:t})=>{const[a,r]=(0,e.useState)(t);return e.default.createElement("div",null,e.default.createElement("h1",null,a),e.default.createElement("p",null,"Coming soon: https://github.com/liamgold/xperience-community-sustainability/issues/4."))};var a=l(267),r=l(90);let o=function(e){return e[e.Available=0]="Available",e[e.NotAvailable=1]="NotAvailable",e}({});const n={"A+":"Extremely efficient",A:"Very efficient",B:"Efficient",C:"Moderate efficiency",D:"Low efficiency",E:"Poor efficiency",F:"Very poor efficiency"},d={"A+":{primary:"#059669",bg:"#d1fae5",border:"#6ee7b7"},A:{primary:"#16a34a",bg:"#dcfce7",border:"#86efac"},B:{primary:"#65a30d",bg:"#ecfccb",border:"#bef264"},C:{primary:"#ca8a04",bg:"#fef9c3",border:"#fde047"},D:{primary:"#ea580c",bg:"#ffedd5",border:"#fdba74"},E:{primary:"#dc2626",bg:"#fee2e2",border:"#fca5a5"},F:{primary:"#b91c1c",bg:"#fee2e2",border:"#f87171"}},s=e=>({Images:"xp-picture",Scripts:"xp-braces",CSS:"xp-brush",Links:"xp-chain",Other:"xp-file"}[e]||"xp-file"),c=e=>{const t={Images:{bg:"#dbeafe",color:"#1e40af",border:"#bfdbfe"},Scripts:{bg:"#ede9fe",color:"#7c3aed",border:"#ddd6fe"},CSS:{bg:"#fce7f3",color:"#db2777",border:"#fbcfe8"},Links:{bg:"#d1fae5",color:"#059669",border:"#a7f3d0"},Other:{bg:"#f3f4f6",color:"#6b7280",border:"#e5e7eb"}};return t[e]||t.Other},u=({label:t,value:a,subtitle:r})=>e.default.createElement("div",{style:{padding:"20px",background:"white",border:"1px solid #e5e7eb",borderRadius:"8px",boxShadow:"0 1px 2px 0 rgba(0, 0, 0, 0.05)"}},e.default.createElement("div",{style:{fontSize:"13px",fontWeight:600,color:"#6b7280",textTransform:"uppercase",letterSpacing:"0.5px",marginBottom:"8px"}},t),e.default.createElement("div",{style:{fontSize:"28px",fontWeight:700,color:"#111827",marginBottom:r?"4px":"0"}},a),r&&e.default.createElement("div",{style:{fontSize:"12px",color:"#9ca3af"}},r)),p={container:{background:"white",border:"1px solid #e5e7eb",borderRadius:"8px",overflow:"hidden"},header:{padding:"16px 20px",background:"#f9fafb",borderBottom:"1px solid #e5e7eb",display:"flex",justifyContent:"space-between",alignItems:"center"},title:{fontSize:"15px",fontWeight:600,color:"#111827"},subtitle:{fontSize:"13px",color:"#6b7280",marginTop:"2px"},badge:{padding:"4px 12px",background:"#eff6ff",color:"#1e40af",fontSize:"13px",fontWeight:600,borderRadius:"12px"},listContainer:{padding:"12px 20px"},resourceItem:e=>({padding:"12px 0",borderBottom:e?"none":"1px solid #f3f4f6"}),resourceRow:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"12px"},resourceInfo:{flex:1,minWidth:0},fileName:{fontSize:"13px",fontWeight:500,color:"#111827",marginBottom:"2px",wordBreak:"break-word"},filePath:{fontSize:"12px",color:"#9ca3af",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},fileSize:{fontSize:"13px",fontWeight:600,color:"#6b7280",whiteSpace:"nowrap"},expandButtonContainer:{marginTop:"12px",width:"100%",display:"flex",justifyContent:"center"}},f=({group:t,totalPageSize:r})=>{const[o,n]=(0,e.useState)(!1),l=o?t.resources.length:3;return e.default.createElement("div",{style:p.container},e.default.createElement("div",{style:p.header},e.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:"12px"}},(()=>{const r=c(t.name);return e.default.createElement("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",width:"48px",height:"48px",borderRadius:"8px",backgroundColor:r.bg,color:r.color,border:`1px solid ${r.border}`,flexShrink:0,fontSize:"24px"}},e.default.createElement(a.Icon,{name:s(t.name)}))})(),e.default.createElement("div",null,e.default.createElement("div",{style:p.title},t.name),e.default.createElement("div",{style:p.subtitle},t.resources.length," resource",1!==t.resources.length?"s":""," •"," ",t.totalSize.toFixed(2)," KB"))),e.default.createElement("div",{style:p.badge},(t.totalSize/r*100).toFixed(1),"% of page")),t.resources.length>0&&e.default.createElement("div",{style:p.listContainer},t.resources.slice(0,l).map(((t,r)=>{const o=t.url.split("/").pop()||t.url,n=t.url.substring(0,t.url.lastIndexOf("/")+1),i=r===l-1;return e.default.createElement("div",{key:r,style:p.resourceItem(i)},e.default.createElement("div",{style:p.resourceRow},e.default.createElement("div",{style:p.resourceInfo},e.default.createElement("div",{style:p.fileName},o,t.contentHubUrl&&e.default.createElement("a",{href:t.contentHubUrl,target:"_blank",rel:"noopener noreferrer",title:"View in Content Hub",style:{marginLeft:"8px",display:"inline-flex",alignItems:"center",verticalAlign:"top",textDecoration:"none",cursor:"pointer",fontSize:"14px",color:"var(--color-text-secondary)",opacity:.7},onMouseEnter:e=>{e.currentTarget.style.opacity="1"},onMouseLeave:e=>{e.currentTarget.style.opacity="0.7"}},e.default.createElement(a.Icon,{name:"xp-arrow-right-top-square"}))),e.default.createElement("div",{style:p.filePath,title:n},n)),e.default.createElement("div",{style:p.fileSize},t.size.toFixed(2)," KB")))})),t.resources.length>3&&e.default.createElement("div",{style:p.expandButtonContainer},e.default.createElement(a.Button,{label:o?"Show less":`Show ${t.resources.length-3} more`,trailingIcon:o?"xp-chevron-up":"xp-chevron-down",onClick:()=>n(!o),color:a.ButtonColor.Secondary,size:a.ButtonSize.S}))))},m=({data:t,ratingColor:r,totalResources:o,hostingStatus:l})=>e.default.createElement(e.default.Fragment,null,e.default.createElement("div",{style:{background:`linear-gradient(135deg, ${r.bg} 0%, white 100%)`,border:`2px solid ${r.border}`,borderRadius:"12px",padding:"40px",position:"relative",overflow:"hidden"}},e.default.createElement("div",{style:{position:"absolute",top:"-50px",right:"-50px",width:"200px",height:"200px",background:r.bg,borderRadius:"50%",opacity:.3}}),e.default.createElement(a.Row,{spacing:a.Spacing.XL},e.default.createElement(a.Column,{colsLg:6,colsMd:12},e.default.createElement("div",{style:{position:"relative",zIndex:1}},e.default.createElement("div",{style:{fontSize:"14px",fontWeight:600,color:r.primary,textTransform:"uppercase",letterSpacing:"1px",marginBottom:"12px"}},"Carbon Rating"),e.default.createElement("div",{style:{fontSize:"120px",fontWeight:900,color:r.primary,lineHeight:1,marginBottom:"16px",textShadow:`0 2px 8px ${r.bg}`}},t.carbonRating),e.default.createElement("div",{style:{fontSize:"18px",fontWeight:600,color:"#111827",marginBottom:"8px"}},n[t.carbonRating]),e.default.createElement("div",{style:{fontSize:"14px",color:"#6b7280"}},"A+"===t.carbonRating||"A"===t.carbonRating?"This page has excellent carbon efficiency.":"B"===t.carbonRating||"C"===t.carbonRating?"This page has room for improvement.":"This page needs significant optimization."),e.default.createElement("div",{style:{fontSize:"12px",color:"#9ca3af",marginTop:"12px",paddingTop:"12px",borderTop:"1px solid #e5e7eb"}},"Rating based on"," ",e.default.createElement("a",{href:"https://sustainablewebdesign.org/digital-carbon-ratings/",target:"_blank",rel:"noopener noreferrer",style:{color:r.primary,textDecoration:"underline",fontWeight:500}},"Sustainable Web Design Model v4")))),e.default.createElement(a.Column,{colsLg:6,colsMd:12},e.default.createElement(a.Row,{spacing:a.Spacing.L,spacingY:a.Spacing.L},e.default.createElement(a.Column,{colsLg:6,colsMd:6},e.default.createElement(u,{label:"CO₂ Emissions",value:`${t.totalEmissions.toFixed(3)}g`,subtitle:"per page view"})),e.default.createElement(a.Column,{colsLg:6,colsMd:6},e.default.createElement(u,{label:"Page Weight",value:`${(t.totalSize/1024).toFixed(2)}MB`,subtitle:`${t.totalSize.toFixed(0)} KB total`})),e.default.createElement(a.Column,{colsLg:6,colsMd:6},e.default.createElement(u,{label:"Resources",value:`${o}`,subtitle:`${t.resourceGroups.length} categories`})),e.default.createElement(a.Column,{colsLg:6,colsMd:6},e.default.createElement(u,{label:"Efficiency",value:t.totalEmissions<.1?"Excellent":t.totalEmissions<.2?"Good":t.totalEmissions<.3?"Fair":"Poor",subtitle:"Overall rating"})))))),e.default.createElement("div",{style:{padding:"16px 20px",background:l.bgColor,border:`1px solid ${l.borderColor}`,borderRadius:"8px",display:"flex",alignItems:"center",gap:"12px"}},e.default.createElement("span",{style:{fontSize:"20px",color:l.color,lineHeight:1}},l.icon),e.default.createElement("div",null,e.default.createElement("div",{style:{fontSize:"14px",fontWeight:600,color:l.color,marginBottom:"2px"}},l.text),e.default.createElement("div",{style:{fontSize:"13px",color:"#6b7280"}},l.description))),e.default.createElement("div",null,e.default.createElement(a.Headline,{size:a.HeadlineSize.M,spacingBottom:a.Spacing.L},"Resource Breakdown"),e.default.createElement(a.Stack,{spacing:a.Spacing.L},t.resourceGroups.sort(((e,t)=>{const a=["Images","CSS","Scripts","Links","Other"];return a.indexOf(e.name)-a.indexOf(t.name)})).map((a=>e.default.createElement(f,{key:a.type,group:a,totalPageSize:t.totalSize}))))),e.default.createElement("div",{style:{padding:"24px",background:"#f0f9ff",border:"1px solid #bae6fd",borderRadius:"8px"}},e.default.createElement("div",{style:{fontSize:"15px",fontWeight:600,color:"#0c4a6e",marginBottom:"12px"}},"💡 Tips to improve your carbon footprint"),e.default.createElement("ul",{style:{margin:0,paddingLeft:"20px",color:"#075985"}},e.default.createElement("li",{style:{marginBottom:"6px"}},e.default.createElement("strong",null,"Use Image Variants")," - Configure responsive image variants with specific dimensions and aspect ratios to serve optimized versions for different contexts (hero banners, thumbnails, social media)"),e.default.createElement("li",{style:{marginBottom:"6px"}},e.default.createElement("strong",null,"Enable AIRA's Smart Optimization")," - Leverage AIRA's AI-powered features for automatic image format conversion, smart focal point detection, and automated quality optimization during uploads"),e.default.createElement("li",{style:{marginBottom:"6px"}},e.default.createElement("strong",null,"Automate Image Metadata")," - Use AIRA to automatically generate alt texts, descriptions, and tags for better SEO while reducing manual work"),e.default.createElement("li",{style:{marginBottom:"6px"}},e.default.createElement("strong",null,"Minimize CSS & JavaScript")," - Bundle and minify your assets to reduce file sizes and decrease the number of HTTP requests"),e.default.createElement("li",{style:{marginBottom:"6px"}},e.default.createElement("strong",null,"Enable Browser Caching")," - Configure cache headers for static resources to reduce repeat downloads and server load"),e.default.createElement("li",null,e.default.createElement("strong",null,"Implement Lazy Loading")," - Load images and resources only when they're needed, improving initial page load performance")))),g=({title:t,data:a,color:r,unit:o,formatValue:n})=>{const l=550,i=200,d=50,s=Math.max(...a),c=Math.min(...a),u=s-c||1,p=s+.1*u,f=Math.max(0,c-.1*u),m=p-f,g=e=>d+e/(a.length-1)*480,x=e=>170-(e-f)/m*140,b=a.map(((e,t)=>{const a=g(t),r=x(e);return 0===t?`M ${a} ${r}`:`L ${a} ${r}`})).join(" ");return e.default.createElement("div",{style:{flex:1,background:"white",border:"1px solid #e5e7eb",borderRadius:"8px",padding:"16px"}},e.default.createElement("div",{style:{fontSize:"14px",fontWeight:600,color:"#111827",marginBottom:"12px",textAlign:"center"}},t),e.default.createElement("svg",{width:l,height:i,style:{overflow:"visible"}},[0,1,2,3,4].map((t=>{const a=30+35*t;return e.default.createElement("line",{key:t,x1:d,y1:a,x2:530,y2:a,stroke:"#f3f4f6",strokeWidth:"1"})})),e.default.createElement("path",{d:b,fill:"none",stroke:r,strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"}),a.map(((t,a)=>e.default.createElement("circle",{key:a,cx:g(a),cy:x(t),r:"4",fill:r,stroke:"white",strokeWidth:"2"}))),e.default.createElement("text",{x:42,y:25,textAnchor:"end",fontSize:"11",fill:"#6b7280"},n(p)),e.default.createElement("text",{x:42,y:175,textAnchor:"end",fontSize:"11",fill:"#6b7280"},n(f)),e.default.createElement("line",{x1:d,y1:170,x2:530,y2:170,stroke:"#d1d5db",strokeWidth:"2"}),e.default.createElement("line",{x1:d,y1:30,x2:d,y2:170,stroke:"#d1d5db",strokeWidth:"2"}),e.default.createElement("text",{x:15,y:100,textAnchor:"middle",fontSize:"11",fill:"#6b7280",transform:"rotate(-90, 15, 100)"},o)))},x=({currentReport:t,historicalReports:a})=>{const r=[t,...a].slice(0,10).reverse();if(r.length<2)return e.default.createElement("div",{style:{background:"white",border:"1px solid #e5e7eb",borderRadius:"8px",padding:"24px",textAlign:"center",color:"#6b7280",marginBottom:"20px"}},"Trend analysis requires at least 2 data points for a trend chart.");const o=r.map((e=>e.totalEmissions)),n=r.map((e=>e.totalSize/1024));return e.default.createElement("div",{style:{marginBottom:"20px"}},e.default.createElement("div",{style:{fontSize:"15px",fontWeight:600,color:"#111827",marginBottom:"8px"}},"Trend Analysis"),e.default.createElement("div",{style:{fontSize:"13px",color:"#6b7280",marginBottom:"16px"}},"Showing trends for the last ",r.length," report",1!==r.length?"s":""," (oldest to newest)"),e.default.createElement("div",{style:{display:"flex",gap:"20px",justifyContent:"space-between",flexWrap:"wrap"}},e.default.createElement(g,{title:"CO₂ Emissions",data:o,color:"#dc2626",unit:"Grams (g)",formatValue:e=>e.toFixed(3)}),e.default.createElement(g,{title:"Page Weight",data:n,color:"#2563eb",unit:"Megabytes (MB)",formatValue:e=>e.toFixed(2)})))},b=({report:t,isExpanded:r,onToggle:o})=>{const n=d[t.carbonRating]||d.C,l=t.resourceGroups.reduce(((e,t)=>e+t.resources.length),0);return e.default.createElement("div",{style:{background:"white",border:"1px solid #e5e7eb",borderRadius:"8px",overflow:"hidden"}},e.default.createElement("div",{style:{padding:"16px 20px",display:"flex",justifyContent:"space-between",alignItems:"center",cursor:"pointer",background:"#fafafa",borderBottom:r?"1px solid #e5e7eb":"none"},onClick:o},e.default.createElement("div",null,e.default.createElement("div",{style:{fontSize:"13px",fontWeight:600,color:"#111827",marginBottom:"2px"}},t.lastRunDate),e.default.createElement("div",{style:{fontSize:"12px",color:"#9ca3af"}},l," resources • ",t.totalSize.toFixed(2)," KB")),e.default.createElement("div",{style:{display:"flex",gap:"16px",alignItems:"center"}},e.default.createElement("div",{style:{padding:"6px 12px",background:n.bg,color:n.primary,fontSize:"16px",fontWeight:700,borderRadius:"6px",border:`1px solid ${n.border}`}},t.carbonRating),e.default.createElement("div",{style:{textAlign:"center",minWidth:"60px"}},e.default.createElement("div",{style:{fontSize:"11px",color:"#6b7280",textTransform:"uppercase",letterSpacing:"0.5px",marginBottom:"2px"}},"CO₂"),e.default.createElement("div",{style:{fontSize:"13px",fontWeight:600,color:"#111827"}},t.totalEmissions.toFixed(3),"g")),e.default.createElement("div",{style:{textAlign:"center",minWidth:"60px"}},e.default.createElement("div",{style:{fontSize:"11px",color:"#6b7280",textTransform:"uppercase",letterSpacing:"0.5px",marginBottom:"2px"}},"Weight"),e.default.createElement("div",{style:{fontSize:"13px",fontWeight:600,color:"#111827"}},(t.totalSize/1024).toFixed(2),"MB")),e.default.createElement("div",{style:{color:"#6b7280",display:"flex",alignItems:"center"}},e.default.createElement(a.Icon,{name:r?"xp-chevron-up":"xp-chevron-down"})))),r&&e.default.createElement("div",{style:{padding:"20px"}},e.default.createElement(a.Stack,{spacing:a.Spacing.M},t.resourceGroups.sort(((e,t)=>t.totalSize-e.totalSize)).slice(0,3).map(((t,r)=>e.default.createElement("div",{key:r,style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"12px",background:"#f9fafb",borderRadius:"6px"}},e.default.createElement("div",{style:{display:"flex",alignItems:"center",gap:"8px"}},e.default.createElement("div",{style:{width:"32px",height:"32px",borderRadius:"6px",backgroundColor:c(t.name).bg,color:c(t.name).color,border:`1px solid ${c(t.name).border}`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:"16px"}},e.default.createElement(a.Icon,{name:s(t.name)})),e.default.createElement("div",null,e.default.createElement("div",{style:{fontSize:"13px",fontWeight:600,color:"#111827"}},t.name),e.default.createElement("div",{style:{fontSize:"12px",color:"#6b7280"}},t.resources.length," resource",1!==t.resources.length?"s":""))),e.default.createElement("div",{style:{fontSize:"13px",fontWeight:600,color:"#6b7280"}},t.totalSize.toFixed(2)," KB")))))))},y=({currentReport:t,historicalReports:r,expandedReportIndex:o,setExpandedReportIndex:n,isLoadingMore:l,hasMoreHistory:i,nextPageIndex:d,onLoadMore:s})=>e.default.createElement(e.default.Fragment,null,e.default.createElement(x,{currentReport:t,historicalReports:r}),e.default.createElement(a.Stack,{spacing:a.Spacing.M},r.map(((t,a)=>e.default.createElement(b,{key:a,report:t,isExpanded:o===a,onToggle:()=>n(o===a?null:a)}))),i&&e.default.createElement("div",{style:{display:"flex",justifyContent:"center",marginTop:"16px"}},e.default.createElement(a.Button,{label:"Load More History",color:a.ButtonColor.Secondary,size:a.ButtonSize.M,trailingIcon:"xp-chevron-down",disabled:l,inProgress:l,onClick:()=>s(d)})))),h=t=>{const[n,l]=(0,e.useState)(!1),[i,s]=(0,e.useState)(!1),[c,u]=(0,e.useState)(null),[p,f]=(0,e.useState)(t?.sustainabilityData),[g,x]=(0,e.useState)(t?.historicalReports||[]),[b,h]=(0,e.useState)(null),[E,S]=(0,e.useState)(!1),[v,z]=(0,e.useState)(t?.hasMoreHistory??!1),[w,C]=(0,e.useState)(!1),[R,k]=(0,e.useState)(1),{execute:B}=(0,r.usePageCommand)("RunReport",{after:e=>{f(e?.sustainabilityData),l(!1),u(null),e?.historicalReports&&(x(e.historicalReports),k(1),z(e.hasMoreHistory??!1))},onError:e=>{l(!1),u("Failed to run sustainability report. Please try again."),console.error("Sustainability report error:",e)}}),{execute:I}=(0,r.usePageCommand)("LoadMoreHistory",{after:e=>{e?.historicalReports&&e.historicalReports.length>0?(x((t=>[...t,...e.historicalReports])),k((e=>e+1)),z(e.hasMoreHistory??!1)):z(!1),S(!1)},onError:e=>{console.error("Load more history error:",e),S(!1)}}),L=(0,r.usePageCommand)("ExportReportAsPdf",{after:e=>{if(e){const t=atob(e.pdfBase64),a=new Uint8Array(t.length);for(let e=0;e{console.error("PDF export error:",e),s(!1)}});if(null==p)return e.default.createElement("div",{style:{padding:"32px",maxWidth:"1400px",margin:"0 auto"}},e.default.createElement(a.Stack,{spacing:a.Spacing.XL},e.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"}},e.default.createElement(a.Headline,{size:a.HeadlineSize.L},"Sustainability Report")),e.default.createElement("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",minHeight:"400px"}},e.default.createElement(a.Card,{headline:"No Data Available",fullHeight:!1},e.default.createElement(a.Stack,{spacing:a.Spacing.L},e.default.createElement("p",{style:{fontSize:"14px",color:"#6b7280"}},t?.pageAvailability===o.Available?"Run a sustainability analysis to see your page's environmental impact.":"This page is not available for analysis."),c&&e.default.createElement("div",{style:{padding:"12px 16px",background:"#fef2f2",border:"1px solid #fecaca",borderRadius:"6px",fontSize:"13px",color:"#dc2626"}},c),t?.pageAvailability===o.Available&&e.default.createElement(a.Button,{label:"Run Analysis",color:a.ButtonColor.Primary,size:a.ButtonSize.L,disabled:n,inProgress:n,onClick:()=>{l(!0),u(null),B()}}))))));const M=d[p.carbonRating]||d.C,A=p.resourceGroups.reduce(((e,t)=>e+t.resources.length),0),W=(e=>{switch(e){case"Green":return{text:"Green hosting",color:"#059669",icon:"●",bgColor:"#f0fdf4",borderColor:"#86efac",description:"This site is hosted on a green energy provider"};case"NotGreen":return{text:"Standard hosting",color:"#f97316",icon:"●",bgColor:"#fff7ed",borderColor:"#fdba74",description:"This site uses standard grid energy hosting"};default:return{text:"Unknown hosting",color:"#6b7280",icon:"●",bgColor:"#f3f4f6",borderColor:"#d1d5db",description:"Unable to verify the hosting provider's energy source"}}})(p.greenHostingStatus);return e.default.createElement("div",{style:{padding:"32px",maxWidth:"1400px",margin:"0 auto"}},e.default.createElement(a.Stack,{spacing:a.Spacing.XL},e.default.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:"16px"}},e.default.createElement("div",null,e.default.createElement(a.Headline,{size:a.HeadlineSize.L},w?"Report History":"Sustainability Report"),!w&&e.default.createElement("div",{style:{fontSize:"14px",color:"#6b7280",marginTop:"4px"}},"Last analyzed: ",p.lastRunDate)),e.default.createElement("div",{style:{display:"flex",gap:"12px"}},w?e.default.createElement(a.Button,{label:"Back to Current Report",color:a.ButtonColor.Secondary,size:a.ButtonSize.M,icon:"xp-arrow-left",onClick:()=>C(!1)}):e.default.createElement(e.default.Fragment,null,e.default.createElement(a.Button,{label:"Export as PDF",color:a.ButtonColor.Secondary,size:a.ButtonSize.M,icon:"xp-file-pdf",disabled:i,inProgress:i,onClick:()=>{s(!0),L.execute()}}),g.length>0&&e.default.createElement(a.Button,{label:"View History",color:a.ButtonColor.Secondary,size:a.ButtonSize.M,icon:"xp-clock",onClick:()=>C(!0)}),e.default.createElement(a.Button,{label:"Run New Analysis",color:a.ButtonColor.Primary,size:a.ButtonSize.M,icon:"xp-rotate-right",disabled:n,inProgress:n,onClick:()=>{l(!0),u(null),B()}})))),c&&e.default.createElement("div",{style:{padding:"16px",background:"#fef2f2",border:"1px solid #fecaca",borderRadius:"8px",fontSize:"14px",color:"#dc2626"}},c),w?e.default.createElement(y,{currentReport:p,historicalReports:g,expandedReportIndex:b,setExpandedReportIndex:h,isLoadingMore:E,hasMoreHistory:v,nextPageIndex:R,onLoadMore:e=>{S(!0),I({pageIndex:e})}}):e.default.createElement(m,{data:p,ratingColor:M,totalResources:A,hostingStatus:W})))}})(),i})())}}})); \ No newline at end of file diff --git a/src/Client/package.json b/src/Client/package.json index e340417..ba0536c 100644 --- a/src/Client/package.json +++ b/src/Client/package.json @@ -3,6 +3,9 @@ "version": "1.0.0", "description": "Custom Kentico Xperience administration project.", "private": true, + "engines": { + "node": ">=22" + }, "scripts": { "start": "webpack serve --mode development", "dev:buildlike": "webpack serve --mode development --env buildlike=true", diff --git a/src/XperienceCommunity.Sustainability.csproj b/src/XperienceCommunity.Sustainability.csproj index ff5cd05..7dcc1bd 100644 --- a/src/XperienceCommunity.Sustainability.csproj +++ b/src/XperienceCommunity.Sustainability.csproj @@ -11,7 +11,7 @@ Xperience by Kentico Sustainability XperienceCommunity.Sustainability - 2.7.0 + 2.7.1 Liam Goldfinch Liam Goldfinch icon.png