1import{p as te,v as ae,r as f,f as T,i as $,j as e,G as g,I as r,B as l}from"./index-QiiZ-xPT.js";import{N as ie}from"./Navigation-r93ZBuy6.js";import{F as re}from"./Footer-3JNsJayo.js";import{T as le}from"./textarea-Bd1mcSz8.js";import{L as i}from"./label-BA9Xin3m.js";import{T as ne,a as oe,b as I,c as D}from"./tabs-DPcdb2bX.js";import{D as q,f as M,a as O,b as E,c as B,e as J}from"./dialog-D2VXyQJN.js";import{C as m,b as z,c as H,d as W,a as p}from"./card-DkXabqFf.js";import{T as Q,a as G,b as v,c as h,d as V,e as x}from"./table-Cw2lhhMS.js";import{B as Y}from"./badge-IOHUIid2.js";import{u as de}from"./useTranslation-XedzLvcK.js";import{K as ce}from"./key-Bl2FgUjA.js";import{C as N}from"./copy-DPG-QUn2.js";import{B as U}from"./building-2-Bz-h5bHH.js";import{L as P}from"./link-2-CbRvItDK.js";import{P as X}from"./plus-BG3Uc6gN.js";import{C as me}from"./circle-check-BOGFOgJv.js";import{C as pe}from"./circle-alert-BZ1suj-l.js";import"./checkbox-CrGTwbPu.js";import"./index-DqZlRfV5.js";import"./check-KTa2Xihg.js";import"./select-B1P2Vx_w.js";import"./index-BMyKsIJE.js";import"./Combination-TP2Egp2x.js";import"./chevron-down-BWOHa16b.js";import"./save-BsB7cS8F.js";import"./dropdown-menu-D4zjGRmc.js";import"./index-Bj3iuRQR.js";import"./chevron-right-f4G5e4zR.js";import"./circle-2nw1jhuN.js";import"./globe-3tsuvpPT.js";import"./log-out-CqAuLeet.js";import"./BrandSponsor-DEW6i_On.js";import"./mail-Cr62Xklx.js";import"./twitter-BzZd48jL.js";function Ge(){const{t:d}=de(),{toast:u}=te(),R=ae(),[Z,b]=f.useState(!1),[_,L]=f.useState(!1),[t,ee]=f.useState(null),[a,c]=f.useState({name:"",issuer:"",clientId:"",authLoginUrl:"",authTokenUrl:"",keySetUrl:"",platformPublicKey:""}),[j,w]=f.useState({platformId:"",deploymentId:"",contextLabel:""}),{data:F=[],isLoading:se}=T({queryKey:["/api/lti/platforms"],queryFn:async()=>{const s=await fetch("/api/lti/platforms");if(!s.ok)throw new Error("Failed to fetch platforms");return s.json()}}),{data:A=[]}=T({queryKey:["/api/lti/deployments",t?.id],queryFn:async()=>{if(!t)return[];const s=await fetch(`/api/lti/platforms/${t.id}/deployments`);if(!s.ok)throw new Error("Failed to fetch deployments");return s.json()},enabled:!!t}),{data:K=[]}=T({queryKey:["/api/lti/resource-links",t?.id],queryFn:async()=>{if(!t)return[];const s=await fetch(`/api/lti/platforms/${t.id}/resource-links`);if(!s.ok)throw new Error("Failed to fetch resource links");return s.json()},enabled:!!t}),k=$({mutationFn:async s=>{const o=await fetch("/api/lti/platforms",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok){const S=await o.json();throw new Error(S.error||"Failed to register platform")}return o.json()},onSuccess:()=>{R.invalidateQueries({queryKey:["/api/lti/platforms"]}),b(!1),c({name:"",issuer:"",clientId:"",authLoginUrl:"",authTokenUrl:"",keySetUrl:"",platformPublicKey:""}),u({title:d("adminLti.toasts.platformRegistered"),description:d("adminLti.toasts.platformRegisteredDesc")})},onError:s=>{u({title:d("adminLti.toasts.registrationFailed"),description:s.message,variant:"destructive"})}}),C=$({mutationFn:async s=>{const o=await fetch("/api/lti/deployments",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok){const S=await o.json();throw new Error(S.error||"Failed to add deployment")}return o.json()},onSuccess:()=>{R.invalidateQueries({queryKey:["/api/lti/deployments"]}),L(!1),w({platformId:"",deploymentId:"",contextLabel:""}),u({title:d("adminLti.toasts.deploymentAdded"),description:d("adminLti.toasts.deploymentAddedDesc")})},onError:s=>{u({title:d("adminLti.toasts.failedAddDeployment"),description:s.message,variant:"destructive"})}}),y=(s,o)=>{navigator.clipboard.writeText(s),u({title:d("adminLti.toasts.copied"),description:d("adminLti.toasts.copiedToClipboard",{label:o})})},n=typeof window<"u"?window.location.origin:"";return e.jsxs("div",{className:"min-h-screen flex flex-col bg-background",children:[e.jsx(ie,{}),e.jsxs("main",{className:"flex-1 container mx-auto px-4 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsxs("h1",{className:"text-3xl font-bold flex items-center gap-2",children:[e.jsx(g,{className:"h-8 w-8"}),"LTI 1.3 Integration"]}),e.jsx("p",{className:"text-muted-foreground mt-2",children:"Manage LMS platform connections for enterprise learning integrations"})]}),e.jsxs(m,{className:"mb-8",children:[e.jsxs(z,{children:[e.jsxs(H,{
1className:"flex items-center gap-2",children:[e.jsx(ce,{className:"h-5 w-5"}),"Tool Configuration"]}),e.jsx(W,{children:"Use these URLs when configuring Living Corporate as an LTI 1.3 tool in your LMS"})]}),e.jsx(p,{children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{children:"Tool Launch URL"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(r,{value:`${n}/api/lti/launch`,readOnly:!0,"data-testid":"input-launch-url"}),e.jsx(l,{variant:"outline",size:"icon",onClick:()=>y(`${n}/api/lti/launch`,"Launch URL"),"data-testid":"button-copy-launch-url",children:e.jsx(N,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{children:"Login Initiation URL"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(r,{value:`${n}/api/lti/login`,readOnly:!0,"data-testid":"input-login-url"}),e.jsx(l,{variant:"outline",size:"icon",onClick:()=>y(`${n}/api/lti/login`,"Login URL"),"data-testid":"button-copy-login-url",children:e.jsx(N,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{children:"JWKS URL (per platform)"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(r,{value:`${n}/api/lti/jwks/{platformId}`,readOnly:!0,"data-testid":"input-jwks-url"}),e.jsx(l,{variant:"outline",size:"icon",onClick:()=>y(`${n}/api/lti/jwks/{platformId}`,"JWKS URL template"),"data-testid":"button-copy-jwks-url",children:e.jsx(N,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{children:"Deep Linking Response URL"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(r,{value:`${n}/api/lti/deep-linking/response`,readOnly:!0,"data-testid":"input-deeplink-url"}),e.jsx(l,{variant:"outline",size:"icon",onClick:()=>y(`${n}/api/lti/deep-linking/response`,"Deep Linking URL"),"data-testid":"button-copy-deeplink-url",children:e.jsx(N,{className:"h-4 w-4"})})]})]})]})})]}),e.jsxs(ne,{defaultValue:"platforms",className:"space-y-4",children:[e.jsxs(oe,{children:[e.jsxs(I,{value:"platforms","data-testid":"tab-platforms",children:[e.jsx(U,{className:"h-4 w-4 mr-2"}),"LMS Platforms"]}),e.jsxs(I,{value:"deployments","data-testid":"tab-deployments",children:[e.jsx(P,{className:"h-4 w-4 mr-2"}),"Deployments"]}),e.jsxs(I,{value:"resource-links","data-testid":"tab-resource-links",children:[e.jsx(g,{className:"h-4 w-4 mr-2"}),"Resource Links"]})]}),e.jsxs(D,{value:"platforms",className:"space-y-4",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("h2",{className:"text-xl font-semibold",children:"Registered LMS Platforms"}),e.jsxs(q,{open:Z,onOpenChange:b,children:[e.jsx(M,{asChild:!0,children:e.jsxs(l,{"data-testid":"button-add-platform",children:[e.jsx(X,{className:"h-4 w-4 mr-2"}),"Register Platform"]})}),e.jsxs(O,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[e.jsx(E,{children:e.jsx(B,{children:"Register LMS Platform"})}),e.jsxs("form",{onSubmit:s=>{s.preventDefault(),k.mutate(a)},className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"name",children:"Platform Name"}),e.jsx(r,{id:"name",placeholder:"e.g., Workday Learning",value:a.name,onChange:s=>c({...a,name:s.target.value}),required:!0,"data-testid":"input-platform-name"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"clientId",children:"Client ID"}),e.jsx(r,{id:"clientId",placeholder:"Provided by LMS",value:a.clientId,onChange:s=>c({...a,clientId:s.target.value}),required:!0,"data-testid":"input-client-id"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"issuer",children:"Issuer URL"}),e.jsx(r,{id:"issuer",placeholder:"https://lms.example.com",value:a.issuer,onChange:s=>c({...a,issuer:s.target.value}),required:!0,"data-testid":"input-issuer"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"authLoginUrl",children:"Authorization Login URL"}),e.jsx(r,{id:"authLoginUrl",placeholder:"https://lms.example.com/auth/login",value:a.authLoginUrl,onChange:s=>c({...a,authLoginUrl:s.target.value}),required:!0,"data-testid":"input-auth-login"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"authTokenUrl",children:"Token URL"}),e.jsx(r,{id:"authTokenUrl",placeholder:"https://lms.example.com/auth/token",value:a.authTokenUrl,onChange:s=>c({...a,authTokenUrl:s.target.value}),required:!0,"data-testid":"input-auth-token"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"keySetUrl",children:"JWKS URL"}),e.jsx(r,{id:"keySetUrl",placeholder:"https://lms.example.com/.well-known/jwks.json",value:a.keySetUrl,onChange:s=>c({...a,keySetUrl:s.target.value}),required:!0,"data-testid":"input-keyset"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"platformPublicKey",children:"Platform Public Key (optional)"}),e.jsx(le,{id:"platformPublicKey",placeholder:"-----BEGIN PUBLIC KEY-----...",value:a.platformPublicKey,onChange:s=>c({...a,platformPublicKey:s.target.value}),rows:4,"data-testid":"input-public-key"})]}),e.jsxs(J,{children:[e.jsx(l,{type:"button",variant:"outline",onClick:()=>b(!1),children:"Cancel"}),e.jsx(l,{type:"submit",disabled:k.isPending,"data-testid":"button-submit-platform",children:k.isPending?"Registering...":"Register Platform"})]})]})]})]})]}),se?e.jsx("div",{className:"text-center py-8",children:"Loading platforms..."}):F.length===0?e.jsx(m,{children:e.jsxs(p,{className:"py-8 text-center text-muted-foreground",children:[e.jsx(U,{className:"h-12 w-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"No LMS platforms registered yet."}),e.jsx("p",{className:"text-sm",children:'Click "Register Platform" to add your first LMS connection.'})]})}):e.jsx("div",{className:"grid gap-4",children:F.map(s=>
1e.jsxs(m,{className:`cursor-pointer transition-colors ${t?.id===s.id?"border-primary":""}`,onClick:()=>ee(s),"data-testid":`card-platform-${s.id}`,children:[e.jsxs(z,{className:"pb-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(H,{className:"text-lg flex items-center gap-2",children:[e.jsx(U,{className:"h-5 w-5"}),s.name]}),e.jsx(Y,{variant:s.isActive?"default":"secondary",children:s.isActive?e.jsxs(e.Fragment,{children:[e.jsx(me,{className:"h-3 w-3 mr-1"}),"Active"]}):e.jsxs(e.Fragment,{children:[e.jsx(pe,{className:"h-3 w-3 mr-1"}),"Inactive"]})})]}),e.jsx(W,{children:s.issuer})]}),e.jsx(p,{children:e.jsxs("div",{className:"grid gap-2 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"Client ID:"}),e.jsx("span",{className:"font-mono",children:s.clientId})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"JWKS URL:"}),e.jsx("span",{className:"font-mono text-xs truncate max-w-[300px]",children:`${n}/api/lti/jwks/${s.id}`})]})]})})]},s.id))})]}),e.jsxs(D,{value:"deployments",className:"space-y-4",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("h2",{className:"text-xl font-semibold",children:["Deployments ",t&&`for ${t.name}`]}),t&&e.jsxs(q,{open:_,onOpenChange:L,children:[e.jsx(M,{asChild:!0,children:e.jsxs(l,{"data-testid":"button-add-deployment",children:[e.jsx(X,{className:"h-4 w-4 mr-2"}),"Add Deployment"]})}),e.jsxs(O,{children:[e.jsx(E,{children:e.jsx(B,{children:"Add Deployment"})}),e.jsxs("form",{onSubmit:s=>{s.preventDefault(),C.mutate({...j,platformId:t.id})},className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"deploymentId",children:"Deployment ID"}),e.jsx(r,{id:"deploymentId",placeholder:"Provided by LMS during tool registration",value:j.deploymentId,onChange:s=>w({...j,deploymentId:s.target.value}),required:!0,"data-testid":"input-deployment-id"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(i,{htmlFor:"contextLabel",children:"Context Label (optional)"}),e.jsx(r,{id:"contextLabel",placeholder:"e.g., HR Training Course",value:j.contextLabel,onChange:s=>w({...j,contextLabel:s.target.value}),"data-testid":"input-context-label"})]}),e.jsxs(J,{children:[e.jsx(l,{type:"button",variant:"outline",onClick:()=>L(!1),children:"Cancel"}),e.jsx(l,{type:"submit",disabled:C.isPending,"data-testid":"button-submit-deployment",children:C.isPending?"Adding...":"Add Deployment"})]})]})]})]})]}),t?A.length===0?e.jsx(m,{children:e.jsxs(p,{className:"py-8 text-center text-muted-foreground",children:[e.jsx(P,{className:"h-12 w-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"No deployments for this platform yet."}),e.jsx("p",{className:"text-sm",children:"Add a deployment when you register this tool in your LMS."})]})}):e.jsxs(Q,{children:[e.jsx(G,{children:e.jsxs(v,{children:[e.jsx(h,{children:"Deployment ID"}),e.jsx(h,{children:"Context"}),e.jsx(h,{children:"Status"}),e.jsx(h,{children:"Created"})]})}),e.jsx(V,{children:A.map(s=>e.jsxs(v,{"data-testid":`row-deployment-${s.id}`,children:[e.jsx(x,{className:"font-mono",children:s.deploymentId}),e.jsx(x,{children:s.contextLabel||"-"}),e.jsx(x,{children:e.jsx(Y,{variant:s.isActive?"default":"secondary",children:s.isActive?"Active":"Inactive"})}),e.jsx(x,{children:new Date(s.createdAt).toLocaleDateString()})]},s.id))})]}):e.jsx(m,{children:e.jsxs(p,{className:"py-8 text-center text-muted-foreground",children:[e.jsx(P,{className:"h-12 w-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"Select a platform to view its deployments."})]})})]}),e.jsxs(D,{value:"resource-links",className:"space-y-4",children:[e.jsx("div",{className:"flex justify-between items-center",children:e.jsxs("h2",{className:"text-xl font-semibold",children:["Resource Links ",t&&`for ${t.name}`]})}),t?K.length===0?e.jsx(m,{children:e.jsxs(p,{className:"py-8 text-center text-muted-foreground",children:[e.jsx(g,{className:"h-12 w-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"No learning modules have been linked from this LMS yet."}),e.jsx("p",{className:"text-sm",children:"Resource links are created when instructors add content via Deep Linking."})]})}):e.jsxs(Q,{children:[e.jsx(G,{children:e.jsxs(v,{children:[e.jsx(h,{children:"Resource Link ID"}),e.jsx(h,{children:"Module"}),e.jsx(h,{children:"Created"})]})}),e.jsx(V,{children:K.map(s=>e.jsxs(v,{"data-testid":`row-resource-${s.id}`,children:[e.jsx(x,{className:"font-mono text-xs",children:s.resourceLinkId}),e.jsx(x,{children:s.moduleTitle||s.moduleId||"-"}),e.jsx(x,{children:new Date(s.createdAt).toLocaleDateString()})]},s.id))})]}):e.jsx(m,{children:e.jsxs(p,{className:"py-8 text-center text-muted-foreground",children:[e.jsx(g,{className:"h-12 w-12 mx-auto mb-4 opacity-50"}),e.jsx("p",{children:"Select a platform to view its resource links."})]})})]})]})]}),e.jsx(re,{})]})}
1export{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.