1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1004],{23578:function(e,n,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/admin/community/custom-emojis",function(){return t(45331)}])},27936:function(e,n,t){"use strict";var r=t(82729),o=t(85893),i=t(19521);function _templateObject(){let e=(0,r._)(["\n position: absolute;\n width: 30vw;\n height: 0px;\n z-index: 10;\n overflow: hidden;\n\n h1,\n p {\n height: 10rem;\n }\n"]);return _templateObject=function(){return e},e}let l=i.default.main.withConfig({componentId:"sc-e8309d9d-0"})(_templateObject());n.Z=function(e){let{h1:n,description:t="",canonical:r=""}=e;return n?(0,o.jsxs)(l,{children:[(0,o.jsx)("h1",{children:n}),t?(0,o.jsx)("p",{className:"description",children:t}):null,r?(0,o.jsx)("link",{rel:"canonical",href:r}):null]}):null}},94646:function(e,n,t){"use strict";t.d(n,{i:function(){return useCustomEmojis}});var r=t(67294);function useCustomEmojis(){let[e,n]=(0,r.useState)([]),[t,o]=(0,r.useState)(!0),[i,l]=(0,r.useState)(null);async function fetchCustomEmojis(){try{o(!0);let e=await fetch("/api/community/customEmojis/list");if(!e.ok)throw Error("Failed to fetch custom emojis");let t=await e.json();n(t),l(null)}catch(e){console.error("Error fetching custom emojis:",e),l(e)}finally{o(!1)}}return(0,r.useEffect)(()=>{fetchCustomEmojis()},[]),{customEmojis:e,loading:t,error:i,refetch:fetchCustomEmojis}}},45331:function(e,n,t){"use strict";t.r(n),t.d(n,{__N_SSP:function(){return S},default:function(){return CustomEmojisAdminPage}});var r=t(85893),o=t(67294),i=t(82729),l=t(19521),c=t(94646);let a=/^[a-z0-9_-]{2,32}$/,s=["image/png","image/jpeg","image/jpg","image/webp","image/gif"];function validateShortcode(e,n){if(!a.test(e))return{valid:!1,error:"Use only lowercase letters, numbers, dashes, and underscores (2-32 chars)"};let t=n.find(n=>n.shortcode.toLowerCase()===e.toLowerCase());return t?{valid:!1,error:"Shortcode :".concat(e,": already exists")}:{valid:!0}}function validateFile(e){return e.size>524288?{valid:!1,error:"File must be under 512KB (current: ".concat(Math.round(e.size/1024),"KB)")}:s.includes(e.type)?{valid:!0}:{valid:!1,error:"Only PNG, JPG, WebP, and GIF files are supported"}}function _templateObject(){let e=(0,i._)(["\n max-width: 1200px;\n margin: 0 auto;\n padding: 24px;\n"]);return _templateObject=function(){return e},e}function _templateObject1(){let e=(0,i._)(["\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 32px;\n\n h1 {\n font-size: 32px;\n font-weight: 700;\n color: ",";\n }\n"]);return _templateObject1=function(){return e},e}function _templateObject2(){let e=(0,i._)(["\n padding: 12px 24px;\n background: ",";\n color: white;\n border: none;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: opacity 0.2s;\n\n &:hover {\n opacity: 0.9;\n }\n"]);return _templateObject2=function(){return e},e}function _templateObject3(){let e=(0,i._)(["\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 24px;\n"]);return _templateObject3=function(){return e},e}function _templateObject4(){let e=(0,i._)(["\n background: ",";\n border: 2px solid ",";\n border-radius: 12px;\n padding: 20px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n .emoji-preview {\n width: 64px;\n height: 64px;\n margin: 0 auto;\n display: flex;\n align-items: center;\n justify-content: center;\n\n img {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n }\n }\n\n .emoji-shortcode {\n text-align: center;\n font-size: 18px;\n font-weight: 600;\n color: ",";\n }\n\n .emoji-details {\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: 14px;\n color: ",";\n\n .detail-row {\n display: flex;\n justify-content: space-between;\n }\n }\n\n .emoji-actions {\n margin-top: 8px;\n display: flex;\n justify-content: flex-end;\n }\n"]);return _templateObject4=function(){return e},e}
1function _templateObject5(){let e=(0,i._)(["\n padding: 8px 16px;\n background: #ef4444;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: opacity 0.2s;\n\n &:hover {\n opacity: 0.9;\n }\n"]);return _templateObject5=function(){return e},e}function _templateObject6(){let e=(0,i._)(["\n text-align: center;\n padding: 64px 24px;\n color: ",";\n\n h2 {\n font-size: 24px;\n margin-bottom: 12px;\n }\n\n p {\n font-size: 16px;\n margin-bottom: 24px;\n }\n"]);return _templateObject6=function(){return e},e}function _templateObject7(){let e=(0,i._)(["\n display: ",";\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 24px;\n"]);return _templateObject7=function(){return e},e}function _templateObject8(){let e=(0,i._)(["\n background: ",";\n border-radius: 16px;\n padding: 32px;\n max-width: 600px;\n width: 100%;\n max-height: 90vh;\n overflow-y: auto;\n\n h2 {\n font-size: 24px;\n font-weight: 700;\n color: ",";\n margin-bottom: 24px;\n }\n"]);return _templateObject8=function(){return e},e}function _templateObject9(){let e=(0,i._)(["\n display: flex;\n flex-direction: column;\n gap: 24px;\n"]);return _templateObject9=function(){return e},e}function _templateObject10(){let e=(0,i._)(["\n display: flex;\n flex-direction: column;\n gap: 8px;\n\n label {\n font-size: 14px;\n font-weight: 600;\n color: ",";\n }\n\n .hint {\n font-size: 12px;\n color: ",";\n }\n\n .error {\n font-size: 12px;\n color: #ef4444;\n }\n"]);return _templateObject10=function(){return e},e}function _templateObject11(){let e=(0,i._)(["\n padding: 12px;\n border: 2px solid ",";\n border-radius: 8px;\n font-size: 16px;\n background: ",";\n color: ",";\n\n &:focus {\n outline: none;\n border-color: ",";\n }\n\n &.error {\n border-color: #ef4444;\n }\n"]);return _templateObject11=function(){return e},e}function _templateObject12(){let e=(0,i._)(["\n border: 2px dashed\n ",";\n border-radius: 8px;\n padding: 32px;\n text-align: center;\n cursor: pointer;\n transition: all 0.2s;\n background: ",";\n\n &:hover {\n border-color: ",";\n background: ",";\n }\n\n .upload-icon {\n font-size: 48px;\n margin-bottom: 16px;\n }\n\n .upload-text {\n font-size: 16px;\n color: ",";\n margin-bottom: 8px;\n }\n\n .upload-hint {\n font-size: 14px;\n color: ",";\n }\n\n &.error {\n border-color: #ef4444;\n }\n"]);return _templateObject12=function(){return e},e}function _templateObject13(){let e=(0,i._)(["\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 16px;\n background: ",";\n border: 2px solid ",";\n border-radius: 8px;\n\n img {\n width: 64px;\n height: 64px;\n object-fit: contain;\n }\n\n .file-info {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 4px;\n\n .file-name {\n font-size: 14px;\n font-weight: 600;\n color: ",";\n }\n\n .file-size {\n font-size: 12px;\n color: ",";\n }\n }\n\n .remove-button {\n padding: 8px 12px;\n background: transparent;\n color: #ef4444;\n border: 1px solid #ef4444;\n border-radius: 6px;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n\n &:hover {\n background: #ef4444;\n color: white;\n }\n }\n"]);return _templateObject13=function(){return e},e}function _templateObject14(){let e=(0,i._)(["\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n margin-top: 24px;\n"]);return _templateObject14=function(){return e},e}function _templateObject15(){let e=(0,i._)(["\n padding: 12px 24px;\n background: transparent;\n color: ",";\n border: 2px solid ",";\n border-radius: 8px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s;\n\n &:hover {\n background: ",";\n }\n"]);return _templateObject15=function(){return e},e}
1function _templateObject16(){let e=(0,i._)(["\n padding: 12px 24px;\n background: ",";\n color: white;\n border: none;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: opacity 0.2s;\n\n &:hover:not(:disabled) {\n opacity: 0.9;\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n"]);return _templateObject16=function(){return e},e}let d=l.default.div.withConfig({componentId:"sc-efcf53d-0"})(_templateObject()),u=l.default.div.withConfig({componentId:"sc-efcf53d-1"})(_templateObject1(),e=>{let{theme:n}=e;return n.colors.text.primary}),p=l.default.button.withConfig({componentId:"sc-efcf53d-2"})(_templateObject2(),e=>{let{theme:n}=e;return n.colors.primary}),f=l.default.div.withConfig({componentId:"sc-efcf53d-3"})(_templateObject3()),m=l.default.div.withConfig({componentId:"sc-efcf53d-4"})(_templateObject4(),e=>{let{theme:n}=e;return n.colors.background.grey.secondary},e=>{let{theme:n}=e;return n.colors.border.grey.light},e=>{let{theme:n}=e;return n.colors.text.primary},e=>{let{theme:n}=e;return n.colors.text.secondary}),h=l.default.button.withConfig({componentId:"sc-efcf53d-5"})(_templateObject5()),x=l.default.div.withConfig({componentId:"sc-efcf53d-6"})(_templateObject6(),e=>{let{theme:n}=e;return n.colors.text.secondary}),j=l.default.div.withConfig({componentId:"sc-efcf53d-7"})(_templateObject7(),e=>{let{open:n}=e;return n?"flex":"none"}),g=l.default.div.withConfig({componentId:"sc-efcf53d-8"})(_templateObject8(),e=>{let{theme:n}=e;return n.colors.background.grey.primary},e=>{let{theme:n}=e;return n.colors.text.primary}),b=l.default.form.withConfig({componentId:"sc-efcf53d-9"})(_templateObject9()),y=l.default.div.withConfig({componentId:"sc-efcf53d-10"})(_templateObject10(),e=>{let{theme:n}=e;return n.colors.text.primary},e=>{let{theme:n}=e;return n.colors.text.secondary}),_=l.default.input.withConfig({componentId:"sc-efcf53d-11"})(_templateObject11(),e=>{let{theme:n}=e;return n.colors.border.grey.light},e=>{let{theme:n}=e;return n.colors.background.grey.secondary},e=>{let{theme:n}=e;return n.colors.text.primary},e=>{let{theme:n}=e;return n.colors.primary}),v=l.default.div.withConfig({componentId:"sc-efcf53d-12"})(_templateObject12(),e=>{let{theme:n,isDragging:t}=e;return t?n.colors.primary:n.colors.border.grey.light},e=>{let{theme:n,isDragging:t}=e;return t?n.colors.background.grey.secondary:"transparent"},e=>{let{theme:n}=e;return n.colors.primary},e=>{let{theme:n}=e;return n.colors.background.grey.secondary},e=>{let{theme:n}=e;return n.colors.text.primary},e=>{let{theme:n}=e;return n.colors.text.secondary}),w=l.default.div.withConfig({componentId:"sc-efcf53d-13"})(_templateObject13(),e=>{let{theme:n}=e;return n.colors.background.grey.secondary},e=>{let{theme:n}=e;return n.colors.border.grey.light},e=>{let{theme:n}=e;return n.colors.text.primary},e=>{let{theme:n}=e;return n.colors.text.secondary}),O=l.default.div.withConfig({componentId:"sc-efcf53d-14"})(_templateObject14()),C=l.default.button.withConfig({componentId:"sc-efcf53d-15"})(_templateObject15(),e=>{let{theme:n}=e;return n.colors.text.secondary},e=>{let{theme:n}=e;return n.colors.border.grey.light},e=>{let{theme:n}=e;return n.colors.background.grey.secondary}),k=l.default.button.withConfig({componentId:"sc-efcf53d-16"})(_templateObject16(),e=>{let{theme:n}=e;return n.colors.primary});function CustomEmojiManager(){let{customEmojis:e,loading:n,refetch:t}=(0,c.i)(),[i,l]=(0,o.useState)(!1),[a,s]=(0,o.useState)(null),[E,N]=(0,o.useState)(null),[z,S]=(0,o.useState)(""),[I,D]=(0,o.useState)({}),[F,P]=(0,o.useState)(!1),[M,A]=(0,o.useState)(!1),T=(0,o.useRef)(null);function handleFileChange(e){if(!e){s(null),N(null),D(e=>({...e,file:void 0}));return}let n=validateFile(e);if(!n.valid){D(e=>({...e,file:n.error})),s(null),N(null);return}s(e),D(e=>({...e,file:void 0}));let t=new FileReader;t.onloadend=()=>{N(t.result)},t.readAsDataURL(e)}function closeModal(){l(!1),s(null),N(null),S(""),D({}),T.current&&(T.current.value="")}async function handleSubmit(n){n.preventDefault();let r=a?validateFile(a):{valid:!1,error:"Please select a file"},o=validateShortcode(z,e);if(!r.valid||!o.valid){D({file:r.error,shortcode:o.error});return}P(!0),D({});try{let e=new FormData;e.append("file",a),e.append("shortcode",z);let n=await fetch("/api/community/customEmojis/create",{method:"POST",body:e});if(!n.ok){let e=await n.json();throw Error(e.error||"Failed to upload emoji")}await t(),closeModal()}catch(e){console.error("Error uploading emoji:",e),D({submit:e instanceof Error?e.message:"Failed to upload emoji"})}finally{P(!1)}}async function handleDelete(e){let n=window.confirm("Delete :".concat(e.shortcode,":? This cannot be undone. Existing posts will show :").concat(e.shortcode,": as plain text."));if(n)try{let n=await fetch("/api/community/customEmojis/delete",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({emojiId:e.id})});if(!n.ok){let e=await n.json();throw Error(e.error||"Failed to delete emoji")}await t()}catch(e){console.error("Error deleting emoji:",e),alert("Failed to delete emoji")}}return n?(0,r.jsxs)(d,{children:[(0,r.jsx)(u,{children:(0,r.jsx)("h1",{children:"Custom Emojis"})}),(0,r.jsx)("p",{children:"Loading..."})]}):(0,r.jsxs)(d,{children:[(0,r.jsxs)(u,{children:[(0,r.jsx)("h1",{children:"Custom Emojis"}),(0,r.jsx)(p,{onClick:()=>l(!0),children:"Add New Emoji"})]}),0===e.length?(0,r.jsxs)(x,{children:[(0,r.jsx)("h2",{children:"No custom emojis yet"}),(0,r.jsx)("p",{children:"Add your first custom emoji to get started"}),(0,r.jsx)(p,{onClick:()=>l(!0),children:"Add Custom Emoji"})]}):(0,r.jsx)(f,{children:e.map(e=>(0,r.jsxs)(m,{children:[(0,r.jsx)("div",{className:"emoji-preview",children:(0,r.jsx)("img",{src:e.imageUrl,alt:":".concat(e.shortcode,":")})}),(0,r.jsxs)("div",{className:"emoji-shortcode",children:[":",e.
1shortcode,":"]}),(0,r.jsxs)("div",{className:"emoji-details",children:[(0,r.jsxs)("div",{className:"detail-row",children:[(0,r.jsx)("span",{children:"Size:"}),(0,r.jsxs)("span",{children:[Math.round(e.fileSize/1024),"KB"]})]}),(0,r.jsxs)("div",{className:"detail-row",children:[(0,r.jsx)("span",{children:"Dimensions:"}),(0,r.jsxs)("span",{children:[e.dimensions.width,"x",e.dimensions.height]})]})]}),(0,r.jsx)("div",{className:"emoji-actions",children:(0,r.jsx)(h,{onClick:()=>handleDelete(e),children:"Delete"})})]},e.id))}),(0,r.jsx)(j,{open:i,onClick:closeModal,children:(0,r.jsxs)(g,{onClick:e=>e.stopPropagation(),children:[(0,r.jsx)("h2",{children:"Add Custom Emoji"}),(0,r.jsxs)(b,{onSubmit:handleSubmit,children:[(0,r.jsxs)(y,{children:[(0,r.jsx)("label",{children:"Emoji Image"}),(0,r.jsx)("input",{ref:T,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",onChange:e=>{var n;return handleFileChange((null===(n=e.target.files)||void 0===n?void 0:n[0])||null)},style:{display:"none"}}),a?(0,r.jsxs)(w,{children:[E&&(0,r.jsx)("img",{src:E,alt:"Preview"}),(0,r.jsxs)("div",{className:"file-info",children:[(0,r.jsx)("div",{className:"file-name",children:a.name}),(0,r.jsxs)("div",{className:"file-size",children:[Math.round(a.size/1024),"KB"]})]}),(0,r.jsx)("button",{type:"button",className:"remove-button",onClick:function(){s(null),N(null),D(e=>({...e,file:void 0})),T.current&&(T.current.value="")},children:"Remove"})]}
1):(0,r.jsxs)(v,{isDragging:M,onClick:()=>{var e;return null===(e=T.current)||void 0===e?void 0:e.click()},onDragOver:function(e){e.preventDefault(),A(!0)},onDragLeave:function(e){e.preventDefault(),A(!1)},onDrop:function(e){e.preventDefault(),A(!1);let n=e.dataTransfer.files[0];n&&handleFileChange(n)},className:I.file?"error":"",children:[(0,r.jsx)("div",{className:"upload-icon",children:"\uD83D\uDCC1"}),(0,r.jsx)("div",{className:"upload-text",children:"Click to upload or drag and drop"}),(0,r.jsx)("div",{className:"upload-hint",children:"PNG, JPG, WebP, or GIF (max 512KB)"})]}),I.file&&(0,r.jsx)("div",{className:"error",children:I.file}),(0,r.jsx)("div",{className:"hint",children:"Images will be resized to max 128x128px"})]}),(0,r.jsxs)(y,{children:[(0,r.jsx)("label",{children:"Shortcode"}),(0,r.jsx)(_,{type:"text",value:z,onChange:n=>(function(n){if(S(n),!n){D(e=>({...e,shortcode:void 0}));return}let t=validateShortcode(n,e);t.valid?D(e=>({...e,shortcode:void 0})):D(e=>({...e,shortcode:t.error}))})(n.target.value),placeholder:"e.g., codedex",className:I.shortcode?"error":""}),I.shortcode&&(0,r.jsx)("div",{className:"error",children:I.shortcode}),(0,r.jsx)("div",{className:"hint",children:"2-32 characters, lowercase letters, numbers, dashes, and underscores only"}),z&&!I.shortcode&&(0,r.jsxs)("div",{className:"hint",children:["Will be used as :",z,":"]})]}),I.submit&&(0,r.jsx)(y,{children:(0,r.jsx)("div",{className:"error",children:I.submit})}),(0,r.jsxs)(O,{children:[(0,r.jsx)(C,{type:"button",onClick:closeModal,disabled:F,children:"Cancel"}),(0,r.jsx)(k,{type:"submit",disabled:F||!!I.file||!!I.shortcode,children:F?"Uploading...":"Add Emoji"})]})]})]})})]})}var E=t(62069),N=t(99428),z=t(27936),S=!0;function CustomEmojisAdminPage(){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(z.Z,{h1:"Custom Emojis Admin",description:"Manage custom emojis for the community"}),(0,r.jsx)(N.Z,{}),(0,r.jsx)(E.Z,{children:(0,r.jsx)(CustomEmojiManager,{})})]})}}},function(e){e.O(0,[1272,8700,4153,1622,9280,9428,9774,2888,179],function(){return e(e.s=23578)}),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.