PageSourceSearch

https://smartedu.ai/build/assets/Index-asjxxD_B.js

js smartedu.ai collected 2026-10-05 15:07:21 UTC 8,066 bytes, 1 lines download raw bytes

1import{i as Z,t as ee}from"./react-C6JdJxIB.js";import{a as A,i as f}from"./index.esm-DxXUb9DD.js";import{t as te}from"./jsx-runtime-CGXBp6bb.js";import{t as n}from"./trans-PZ_OsZUf.js";import{c as r,n as q}from"./notifications-jZ9I4Nty.js";import{t as ne}from"./CentralLayout-B7lm4y_K.js";import se from"./CreateForm-BeKJQRjm.js";import ae from"./EditForm-Bh2B-ZSU.js";import oe from"./DataTable-C2yqjMQw.js";import re from"./DeleteModal-CPneTrH_.js";var l=Z(ee(),1),t=te();function ie({children:o,color:c="indigo"}){const s={indigo:"bg-indigo-100 text-indigo-700",violet:"bg-violet-100 text-violet-700",sky:"bg-sky-100 text-sky-700",amber:"bg-amber-100 text-amber-700"};return(0,t.jsx)("span",{className:`inline-flex rounded-full px-2.5 py-0.5 text-xs font-semibold ${s[c]??s.indigo}`,children:o})}function N(){return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content")||""}function h(o,c){let s=String(o||c||"/");try{if(/^https?:\/\//i.test(s)){const u=new URL(s);s=`${u.pathname}${u.search}`}}catch{s=c||"/"}return s.startsWith("/")||(s=`/${s}`),new URL(s,window.location.origin).toString()}function F(o,c){const s=new Blob([c??""],{type:"application/json;charset=utf-8"}),u=URL.createObjectURL(s),a=document.createElement("a");a.href=u,a.download=o||"translations.json",document.body.appendChild(a),a.click(),a.remove(),URL.revokeObjectURL(u)}async function x(o,c){try{const s=await o.json();return s.message||s.error||(Array.isArray(s.errors?.file)?s.errors.file[0]:null)||c}catch{return`${c} (${o.status})`}}function ge({translationKeys:o,groups:c,languages:s,filters:u}){const[a,X]=(0,l.useState)(u.context??"central"),_=(0,l.useMemo)(()=>o.filter(e=>e.context===a),[o,a]),k=(0,l.useRef)(null),[y,T]=(0,l.useState)(!1),[g,C]=(0,l.useState)(!1),[D,O]=(0,l.useState)(!1),[E,R]=(0,l.useState)(!1),[$,b]=(0,l.useState)(!1),p=A({key:"",group:"general",context:a,values:{}}),U=e=>{e.preventDefault(),p.post(route("admin.translations.store"),{preserveScroll:!0,preserveState:!0,onSuccess:()=>{b(!1),p.reset()}})},[M,j]=(0,l.useState)(!1),[B,S]=(0,l.useState)(null),v=A({id:null,key:"",group:"",context:"",values:{}}),W=e=>{S(e),v.setData({id:e.id,key:e.key,group:e.group,context:e.context,values:{...e.values}}),j(!0)},H=e=>{e.preventDefault(),v.put(route("admin.translations.update",B.id),{preserveScroll:!0,preserveState:!0,onSuccess:()=>{j(!1),S(null)}})},[K,w]=(0,l.useState)(!1),[I,L]=(0,l.useState)(null),J=e=>{L(e),w(!0)},P=()=>{f.delete(route("admin.translations.destroy",I.id),{preserveScroll:!0,preserveState:!0,onSuccess:()=>{w(!1),L(null)}})},G=async()=>{T(!0);try{const e=await fetch(h(route("admin.translations.export",{},!1),"/admin/translations/export"),{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json","X-Requested-With":"XMLHttpRequest","X-CSRF-TOKEN":N()},body:JSON.stringify({context:a})});if(!e.ok){r("error",await x(e,n("Export failed")));return}const i=await e.json();F(i.filename||`${a}.json`,i.content??"{}"),r("success",i.message||n("Exported successfully"))}catch(e){r("error",e?.message||n("Export failed"))}finally{T(!1)}},z=async()=>{C(!0);try{const e=h(route("admin.translations.download",{},!1),"/admin/translations/download"),i=new URL(e);i.searchParams.set("context",a);const d=await fetch(i.toString(),{method:"GET",credentials:"same-origin",headers:{Accept:"application/json","X-Requested-With":"XMLHttpRequest"}});if(!d.ok){r("error",await x(d,n("Download failed")));return}const m=await d.json();F(m.filename||`${a}.json`,m.content??"{}"),r("success",m.message||n("Downloaded successfully"))}catch(e){r("error",e?.message||n("Download failed"))}finally{C(!1)}},Q=()=>{k.current?.click()},V=async e=>{const i=e.target.files?.[0];if(e.target.value="",!!i){if(!String(i.name||"").toLowerCase().endsWith(".json")){r("error",n("Only .json files are allowed."));return}if(await q({title:n("Import"),text:n("Import this JSON file into the database for the current context? This will overwrite matching DB values and save the file in the project."),confirmButtonText:n("Import"),icon:"question"})){O(!0);try{const d=new FormData;d.append("file",i),d.append("context",a);const m=await fetch(h(route("admin.translations.import",{},!1),"/admin/translations/import"),{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","X-Requested-With":"XMLHttpRequest","X-CSRF-TOKEN":N()},body:d});if(!m.ok){r("error",await x(m,n("Import failed")));return}r("success",(await m.json()).message||n("Translations imported successfully.")),f.reload({only:["translationKeys","groups","filters"],preserveScroll:!0,preserveState:!0})}catch(d){r("error",d?.message||n("Import failed"))}finally{O(!1)}}}},Y=async()=>
1{if(await q({title:n("Sync"),text:n("Import translations from lang/central.json (or tenant.json) into the database? This will overwrite DB values with file values."),confirmButtonText:n("Sync"),icon:"question"})){R(!0);try{const e=await fetch(h(route("admin.translations.sync",{},!1),"/admin/translations/sync"),{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json","X-Requested-With":"XMLHttpRequest","X-CSRF-TOKEN":N()},body:JSON.stringify({context:a})});if(!e.ok){r("error",await x(e,n("Sync failed")));return}r("success",(await e.json()).message||n("Synced successfully")),f.reload({only:["translationKeys","groups","filters"],preserveScroll:!0,preserveState:!0})}catch(e){r("error",e?.message||n("Sync failed"))}finally{R(!1)}}};return(0,t.jsxs)(ne,{title:"Translations",section:"admin",children:[(0,t.jsx)("input",{ref:k,type:"file",accept:".json,application/json",className:"d-none",onChange:V}),(0,t.jsxs)("div",{className:"space-y-5 p-4 md:p-6",children:[(0,t.jsxs)("div",{className:"d-flex align-items-center justify-content-between gap-2 mb-4 flex-wrap",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"mb-1",children:"Translations"}),(0,t.jsx)("p",{className:"mb-0 text-muted",children:"Manage translation keys and values."})]}),(0,t.jsxs)("div",{className:"gap-2 d-flex align-items-center flex-wrap",children:[(0,t.jsxs)("button",{type:"button",onClick:G,disabled:y||g,className:"btn btn-sm btn-light",children:[(0,t.jsx)("i",{className:"ti ti-file-export me-1"}),y?n("Exporting..."):n("Export")]}),(0,t.jsxs)("button",{type:"button",onClick:z,disabled:g||y,className:"btn btn-sm btn-light",children:[(0,t.jsx)("i",{className:"ti ti-download me-1"}),g?n("Downloading..."):n("Download")]}),(0,t.jsxs)("button",{type:"button",onClick:Q,disabled:D,className:"btn btn-sm btn-light",children:[(0,t.jsx)("i",{className:"ti ti-upload me-1"}),D?n("Importing..."):n("Import")]}),(0,t.jsxs)("button",{type:"button",onClick:Y,disabled:E,className:"btn btn-sm btn-light",children:[(0,t.jsx)("i",{className:"ti ti-refresh me-1"}),E?n("Syncing..."):n("Sync")]})]})]}),(0,t.jsx)("div",{className:"card border-0 mb-4",children:(0,t.jsx)("div",{className:"card-body pb-0 pt-0 px-2",children:(0,t.jsx)("ul",{className:"nav nav-tabs nav-bordered nav-bordered-primary",children:["central","tenant"].map(e=>(0,t.jsx)("li",{className:"nav-item me-3",children:(0,t.jsxs)("button",{type:"button",onClick:()=>{X(e),p.setData("context",e),f.get(route("admin.translations.index"),{context:e},{preserveState:!0,replace:!0})},className:`nav-link p-2 ${a===e?"active":""}`,children:[(0,t.jsx)("i",{className:`ti ti-${e==="central"?"building":"users"} me-2`}),e.charAt(0).toUpperCase()+e.slice(1),(0,t.jsx)(ie,{color:e==="central"?"indigo":"violet",children:o.filter(i=>i.context===e).length})]})},e))})})}),(0,t.jsx)(oe,{translationKeys:o,visibleKeys:_,languages:s,context:a,onAdd:()=>{p.reset(),p.setData("context",a),b(!0)},onEdit:W,onDelete:J})]}),(0,t.jsx)(se,{isOpen:$,onClose:()=>b(!1),title:"Add Translation Key",form:p,languages:s,onSubmit:U,contextLocked:!1}),(0,t.jsx)(ae,{isOpen:M,onClose:()=>{j(!1),S(null)},title:"Edit Translations",form:v,languages:s,onSubmit:H,contextLocked:!0}),(0,t.jsx)(re,{isOpen:K,onClose:()=>w(!1),onConfirm:P,item:I})]})}export{ge as default};

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.