Changeset 3290868
- Timestamp:
- 05/10/2025 10:36:42 AM (11 months ago)
- Location:
- cloudapps-course-manager/trunk
- Files:
-
- 13 edited
-
admin/ui/build/index.asset.php (modified) (1 diff)
-
admin/ui/build/index.js (modified) (1 diff)
-
admin/ui/package.json (modified) (1 diff)
-
admin/ui/src/components/courses.js (modified) (1 diff)
-
admin/ui/src/components/login-form.js (modified) (2 diffs)
-
admin/ui/src/components/registration-form.js (modified) (1 diff)
-
block/course-list/build/index.asset.php (modified) (1 diff)
-
block/course-list/build/index.js (modified) (1 diff)
-
block/course-list/package.json (modified) (1 diff)
-
block/course-list/src/components/account-checker.js (modified) (1 diff)
-
block/course-list/src/edit.js (modified) (1 diff)
-
cloudapps-course-manager.php (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
cloudapps-course-manager/trunk/admin/ui/build/index.asset.php
r3260238 r3290868 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-date', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => ' 71115a99bcd78157fe98');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-date', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => '0d37e8c90d586cdcdf02'); -
cloudapps-course-manager/trunk/admin/ui/build/index.js
r3260238 r3290868 1 (()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.data,r=window.wp.i18n,o=window.wp.notices,l=window.wp.apiFetch;var s=e.n(l);const c=window.wp.components,u=({apiKey:e,appUrl:n,onLogout:o,tenant:l,onTenantChanged:s})=>{const[u,i]=(0,a.useState)(),[p,m]=(0,a.useState)(!0),[d,_]=(0,a.useState)(null);return(0,a.useEffect)((()=>{e&&(async()=>{const t=new URLSearchParams({api_key:e});await fetch(`${n}/api/users/me?${t.toString()}`).then((async e=>{if(!e.ok)return void _((0,r.__)("Failed to fetch account information.","cloudapps_course_manager"));const t=await e.json();i({userId:t.user_id,username:t.username,tenants:t.tenants,verified:t.verified})})).catch((e=>{console.error(e),_((0,r.__)("Failed to fetch account information.","cloudapps_course_manager"))}))})().finally((()=>{m(!1)}))}),[e,n,l]),(0,a.useEffect)((()=>{!l&&u&&u.tenants.length>0&&s(u.tenants[0].id)}),[u]),(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Account","cloudapps_course_manager"))),(0,t.createElement)(c.CardBody,null,p&&(0,t.createElement)(c.Spinner,null),u&&(0,t.createElement)("div",null,(0,t.createElement)(c.Flex,{justify:"space-between"},(0,t.createElement)(c.Button,{icon:"exit",variant:"secondary",label:(0,r.__)("Logout","cloudapps_course_manager"),onClick:o},(0,r.__)("Logout","cloudapps_course_manager")),(0,t.createElement)("span",null,(0,t.createElement)(c.Icon,{icon:"yes",className:"text-positive"}),(0,t.createElement)("span",null,(0,r.__)("Connected","cloudapps_course_manager")))),(0,t.createElement)("div",null,(0,t.createElement)("h3",null,(0,r.__)("Information","cloudapps_course_manager"),":"),(0,r.__)("User","cloudapps_course_manager"),":"," ",(0,t.createElement)("b",null,u?.username)," ",u?.tenants?.length>1&&(0,t.createElement)(c.SelectControl,{label:(0,r.__)("Tenant","cloudapps_course_manager"),value:l,options:u.tenants.map((e=>({label:e.alias,value:e.id}))),onChange:e=>{s(e)}}))),d&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)("span",{className:"text-negative"},d),(0,t.createElement)(c.Button,{label:(0,r.__)("Logout","cloudapps_course_manager"),onClick:o},(0,r.__)("Logout","cloudapps_course_manager")))))},i=window.wp.date,p=e=>{const n=e.appUrl,o=e.apiKey,l=e.tenant,[s,u]=(0,a.useState)([]),[p,m]=(0,a.useState)(!0),[d,_]=(0,a.useState)(null),[g,E]=(0,a.useState)("date");return(0,a.useEffect)((()=>{(async()=>{const e=await fetch(`${n}/api/auth/token/refresh?`+new URLSearchParams({tenant:l,api_key:o}).toString()).finally((()=>{m(!1)}));if(!e.ok)throw new Error("Failed to refresh token");const t=await e.json();_(t.access_token)})()}),[]),(0,a.useEffect)((()=>{(async()=>{const e=await fetch(`${n}/api/${encodeURIComponent(l)}/portal/courses/upcoming?`+new URLSearchParams({api_key:o}).toString());if(!e.ok)throw new Error("Failed to fetch courses");const t=await e.json();u(t)})()}),[d,l]),(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Courses","cloudapps_course_manager"),(0,t.createElement)("br",null),(0,t.createElement)("span",{className:"text-caption"},(0,r.__)("Stay Organized and Ready: Manage Your Upcoming Courses.","cloudapps-course-manager")))),(0,t.createElement)(c.CardBody,null,(0,t.createElement)("div",{className:"course-header-controls",style:{display:"flex",justifyContent:"space-between",marginBottom:"16px"}},(0,t.createElement)(c.SelectControl,{label:(0,r.__)("Sort by","cloudapps_course_manager"),labelPosition:"side",value:g,options:[{label:(0,r.__)("Date","cloudapps_course_manager"),value:"date"},{label:(0,r.__)("Name","cloudapps_course_manager"),value:"name"}],onChange:e=>{E(e),(e=>{const t=[...s].sort(((t,a)=>t.begin&&a.begin?"date"===e?new Date(t.begin)-new Date(a.begin):t.title.localeCompare(a.title):0));u(t)})(e)}}),(0,t.createElement)(c.Button,{isSecondary:!0,icon:"list-view",target:"_blank",href:`${n}/courses?${new URLSearchParams({authToken:d}).toString()}`,rel:"noreferrer",label:(0,r.__)("Course overview","cloudapps_course_manager")},(0,r.__)("Course overview","cloudapps_course_manager"))),p&&(0,t.createElement)(c.Spinner,null),!p&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)("ul",{style:{listStyleType:"none",padding:0}},s.map((e=>(0,t.createElement)("li",{key:e.reference,style:{padding:"12px",border:"1px solid #ddd",borderRadius:"8px",marginBottom:"12px"}},(0,t.createElement)(c.Flex,null,(0,t.createElement)("h4",{style:{margin:"0 0 8px"}},e.title," - ",e.reference),(0,t.createElement)("span",{className:"badge "+(e.bookable?"badge-positive":"badge-negative")},e.bookable&&(0,r.__)("Bookable","cloudapps_course_manager"),!e.bookable&&(0,r.__)("Fully booked","cloudapps_course_manager"))),(0,t.createElement)("p",{style:{color:"#555",fontSize:"14px"}},(0,i.dateI18n)("D, Y-M-d",e.begin)," ",(0,i.dateI18n)("H:i",e.begin)),e.location&&(0,t.createElement)("div",null,(0,t.createElement)(c.Icon,{icon:"location"})," ",e.location),e.instructor&&(0,t.createElement)("div",null,(0,t.createElement)(c.Icon,{icon:"businessperson"})," ",e.instructor.fullname),(0,t.createElement)("div",null,(0,t.createElement)(c.Icon,{icon:"money"})," ",e.fee),(0,t.createElement)(c.Button,{variant:"tertiary",className:"wp-icon",href:`${n}/courses/${encodeURIComponent(e.courseId)}?${new URLSearchParams({authToken:d}).toString()}`,target:"_blank",rel:"noreferrer"},(0,r.__)("Show","cloudapps_course_manager")))))),0===s.length&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(c.Flex,null,(0,t.createElement)(c.Notice,{status:"info",isDismissible:!1},(0,r.__)("No courses found. Create a new course to get started.","plugin-domain")),(0,t.createElement)(c.Button,{href:`${n}/courses?${new URLSearchParams({action:"create-course",authToken:d}).toString()}`,target:"_blank",rel:"noreferrer",icon:"plus",variant:"secondary"},(0,r.__)("Create course","cloudapps_course_manager")))))))},m=e=>{const[n,o]=(0,a.useState)(null),[l,s]=(0,a.useState)(!1),[u,i]=(0,a.useState)(""),[p,m]=(0,a.useState)("");return(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Log in","cloudapps-course-manager"),(0,t.createElement)("br",null),(0,t.createElement)("span",{className:"text-caption"},(0,r.__)("Connect your Cloudapps account.","cloudapps-course-manager")))),(0,t.createElement)(c.CardBody,null,(0,t.createElement)("form",{onSubmit:async t=>{t.preventDefault(),o(null),s(!0),d({email:u,password:p,appUrl:e.appUrl}).then((t=>{e.onLoginCompleted({apiKey:t})})).catch((e=>{o(e)})).finally((()=>{s(!1)}))}},(0,t.createElement)(c.TextControl,{label:(0,r.__)("Email","cloudapps-course-manager"),type:"email",value:u,onChange:e=>i(e),required:!0,autoComplete:"username"}),(0,t.createElement)(c.TextControl,{type:"password",value:p,onChange:e=>m(e),required:!0,label:(0,r.__)("Password","cloudapps-course-manager"),autoComplete:"current-password"}),(0,t.createElement)(c.Button,{type:"submit",variant:"primary",disabled:l},(0,r.__)("Login","cloudapps-course-manager"),l&&(0,t.createElement)(c.Spinner,null)),(0,t.createElement)(c.Button,{onClick:e.onSignUp},(0,r.__)("Create new account","cloudapps-course-manager")),n&&(0,t.createElement)("p",{className:"text-negative"},n))))},d=async({email:e,password:t,appUrl:a})=>{const n=new URLSearchParams;n.append("username",e),n.append("password",t);const r=await fetch(`${a}/api/auth/token`,{method:"POST",body:n,headers:{"Content-Type":"application/x-www-form-urlencoded"}}).catch((()=>{throw"Failed to connect to the server"}));if(401===r.status)throw"Incorrect username or password";if(!r.ok)throw"Failed to register";const o=(await r.json()).access_token,l=await fetch(`${a}/api/users/generate-api-key`,{method:"POST",headers:{Authorization:`Bearer ${o}`}});if(!l.ok)throw"Failed to generate API key";return(await l.json()).apiKey},_=()=>{const{removeNotice:e}=(0,n.useDispatch)(o.store),a=(0,n.useSelect)((e=>e(o.store).getNotices()));return 0===a.length?null:(0,t.createElement)(c.NoticeList,{notices:a,onRemove:e})},g=e=>{const[n,o]=(0,a.useState)(null),[l,s]=(0,a.useState)(!1),[u,i]=(0,a.useState)(""),[p,m]=(0,a.useState)("");return(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Create a new account","cloudapps-course-manager"),(0,t.createElement)("br",null),(0,t.createElement)("span",{className:"text-caption"},(0,r.__)("It's quick and easy.","cloudapps-course-manager")))),(0,t.createElement)(c.CardBody,null,(0,t.createElement)("form",{onSubmit:async t=>{t.preventDefault(),o(null),s(!0),E({email:u,password:p,siteUrl:e.siteUrl,appUrl:e.appUrl}).then((t=>{e.onRegistrationCompleted({apiKey:t.apiKey,tenant:t.tenant})})).catch((e=>{o(e)})).finally((()=>{s(!1)}))}},(0,t.createElement)(c.TextControl,{label:(0,r.__)("Email","cloudapps-course-manager"),type:"email",value:u,onChange:e=>i(e),required:!0,autoComplete:"username"}),(0,t.createElement)(c.TextControl,{type:"password",value:p,onChange:e=>m(e),required:!0,label:(0,r.__)("Password","cloudapps-course-manager"),autoComplete:"new-password"}),(0,t.createElement)(c.Button,{type:"submit",variant:"primary"},(0,r.__)("Register","cloudapps-course-manager"),l&&(0,t.createElement)(c.Spinner,null)),(0,t.createElement)(c.Button,{onClick:e.onSignIn},(0,r.__)("You have alreadyan account?","cloudapps-course-manager")),n&&(0,t.createElement)("p",{className:"text-negative"},n))))},E=async({email:e,password:t,siteUrl:a,appUrl:n})=>{const r=await fetch(`${n}/api/users/register-wordpress`,{method:"POST",body:JSON.stringify({email:e,password:t,siteUrl:a}),headers:{"Content-Type":"application/json"}}).catch((()=>{throw"Failed to connect to the server"}));if(!r.ok)throw"Failed to register";return await r.json()},w=()=>{const{saveSettings:e,settings:l,siteUrl:c}=(()=>{const[e,t]=(0,a.useState)(),[n,r]=(0,a.useState)();return(0,a.useEffect)((()=>{s()({path:"/wp/v2/settings"}).then((e=>{t(e.cloudapps_course_manager_options),r(e.url)}))}),[]),{siteUrl:n,settings:e,saveSettings:async a=>{const n={...e,...a};t(n),await s()({path:"/wp/v2/settings",method:"POST",data:{cloudapps_course_manager_options:n}})}}})(),[i,d]=(0,a.useState)(!1),{createSuccessNotice:E}=(0,n.useDispatch)(o.store);return(0,t.createElement)("div",{className:"wrap"},(0,t.createElement)("h1",{className:"wp-heading-inline"},"Cloudapps Course Manager"),(0,t.createElement)(_,null),l&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)("div",{className:"cloudapps-course-manager-settings"},(0,t.createElement)("div",{className:"account-card "},!l.apiKey&&(0,t.createElement)(t.Fragment,null,i&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(g,{appUrl:l.appUrl,siteUrl:c,onRegistrationCompleted:t=>{e({...l,tenant:t.tenant,apiKey:t.apiKey}).then((()=>{E((0,r.__)("Successfully registered.","cloudapps_course_manager"))}))},onSignIn:()=>{d(!1)}})),!i&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(m,{appUrl:l.appUrl,siteUrl:c,onLoginCompleted:t=>{e({...l,tenant:"",apiKey:t.apiKey}).then((()=>{E((0,r.__)("Successfully logged in.","cloudapps_course_manager"))}))},onSignUp:()=>{d(!0)}}))),l.apiKey&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(u,{apiKey:l.apiKey,appUrl:l.appUrl,tenant:l.tenant,onLogout:()=>{e({...l,apiKey:""})},onTenantChanged:t=>{e({...l,tenant:t})}}))),l.tenant&&l.apiKey&&l.appUrl&&(0,t.createElement)("div",{className:"courses"},(0,t.createElement)(p,{apiKey:l.apiKey,appUrl:l.appUrl,tenant:l.tenant})))))},h=document.getElementById("cloudapps-course-manager-holder");a.createRoot?(0,a.createRoot)(h).render((0,t.createElement)(w,null)):(0,a.render)((0,t.createElement)(w,null),h)})();1 (()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.React,a=window.wp.element,n=window.wp.data,r=window.wp.i18n,o=window.wp.notices,l=window.wp.apiFetch;var s=e.n(l);const c=window.wp.components,u=({apiKey:e,appUrl:n,onLogout:o,tenant:l,onTenantChanged:s})=>{const[u,i]=(0,a.useState)(),[p,m]=(0,a.useState)(!0),[d,_]=(0,a.useState)(null);return(0,a.useEffect)((()=>{e&&(async()=>{const t=new URLSearchParams({api_key:e});await fetch(`${n}/api/users/me?${t.toString()}`).then((async e=>{if(!e.ok)return void _((0,r.__)("Failed to fetch account information.","cloudapps_course_manager"));const t=await e.json();i({userId:t.user_id,username:t.username,tenants:t.tenants,verified:t.verified})})).catch((e=>{console.error(e),_((0,r.__)("Failed to fetch account information.","cloudapps_course_manager"))}))})().finally((()=>{m(!1)}))}),[e,n,l]),(0,a.useEffect)((()=>{!l&&u&&u.tenants.length>0&&s(u.tenants[0].id)}),[u]),(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Account","cloudapps_course_manager"))),(0,t.createElement)(c.CardBody,null,p&&(0,t.createElement)(c.Spinner,null),u&&(0,t.createElement)("div",null,(0,t.createElement)(c.Flex,{justify:"space-between"},(0,t.createElement)(c.Button,{icon:"exit",variant:"secondary",label:(0,r.__)("Logout","cloudapps_course_manager"),onClick:o},(0,r.__)("Logout","cloudapps_course_manager")),(0,t.createElement)("span",null,(0,t.createElement)(c.Icon,{icon:"yes",className:"text-positive"}),(0,t.createElement)("span",null,(0,r.__)("Connected","cloudapps_course_manager")))),(0,t.createElement)("div",null,(0,t.createElement)("h3",null,(0,r.__)("Information","cloudapps_course_manager"),":"),(0,r.__)("User","cloudapps_course_manager"),":"," ",(0,t.createElement)("b",null,u?.username)," ",u?.tenants?.length>1&&(0,t.createElement)(c.SelectControl,{label:(0,r.__)("Tenant","cloudapps_course_manager"),value:l,options:u.tenants.map((e=>({label:e.alias,value:e.id}))),onChange:e=>{s(e)}}))),d&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)("span",{className:"text-negative"},d),(0,t.createElement)(c.Button,{label:(0,r.__)("Logout","cloudapps_course_manager"),onClick:o},(0,r.__)("Logout","cloudapps_course_manager")))))},i=window.wp.date,p=e=>{const n=e.appUrl,o=e.apiKey,l=e.tenant,[s,u]=(0,a.useState)([]),[p,m]=(0,a.useState)(!0),[d,_]=(0,a.useState)(null),[g,E]=(0,a.useState)("date");return(0,a.useEffect)((()=>{(async()=>{const e=await fetch(`${n}/api/auth/token/refresh?`+new URLSearchParams({tenant:l,api_key:o}).toString()).finally((()=>{m(!1)}));if(!e.ok)throw new Error("Failed to refresh token");const t=await e.json();_(t.access_token)})()}),[]),(0,a.useEffect)((()=>{(async()=>{const e=await fetch(`${n}/api/${encodeURIComponent(l)}/portal/courses/upcoming?`+new URLSearchParams({api_key:o}).toString());if(!e.ok)throw new Error("Failed to fetch courses");const t=await e.json();u(t)})()}),[d,l]),(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Courses","cloudapps_course_manager"),(0,t.createElement)("br",null),(0,t.createElement)("span",{className:"text-caption"},(0,r.__)("Stay organized and ready: Manage your upcoming courses.","cloudapps-course-manager")))),(0,t.createElement)(c.CardBody,null,(0,t.createElement)("div",{className:"course-header-controls",style:{display:"flex",justifyContent:"space-between",marginBottom:"16px"}},(0,t.createElement)(c.SelectControl,{label:(0,r.__)("Sort by","cloudapps_course_manager"),labelPosition:"side",value:g,options:[{label:(0,r.__)("Date","cloudapps_course_manager"),value:"date"},{label:(0,r.__)("Name","cloudapps_course_manager"),value:"name"}],onChange:e=>{E(e),(e=>{const t=[...s].sort(((t,a)=>t.begin&&a.begin?"date"===e?new Date(t.begin)-new Date(a.begin):t.title.localeCompare(a.title):0));u(t)})(e)}}),(0,t.createElement)(c.Button,{isSecondary:!0,icon:"list-view",target:"_blank",href:`${n}/courses?${new URLSearchParams({authToken:d}).toString()}`,rel:"noreferrer",label:(0,r.__)("Course overview","cloudapps_course_manager")},(0,r.__)("Course overview","cloudapps_course_manager"))),p&&(0,t.createElement)(c.Spinner,null),!p&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)("ul",{style:{listStyleType:"none",padding:0}},s.map((e=>(0,t.createElement)("li",{key:e.reference,style:{padding:"12px",border:"1px solid #ddd",borderRadius:"8px",marginBottom:"12px"}},(0,t.createElement)(c.Flex,null,(0,t.createElement)("h4",{style:{margin:"0 0 8px"}},e.title," - ",e.reference),(0,t.createElement)("span",{className:"badge "+(e.bookable?"badge-positive":"badge-negative")},e.bookable&&(0,r.__)("Bookable","cloudapps_course_manager"),!e.bookable&&(0,r.__)("Fully booked","cloudapps_course_manager"))),(0,t.createElement)("p",{style:{color:"#555",fontSize:"14px"}},(0,i.dateI18n)("D, Y-M-d",e.begin)," ",(0,i.dateI18n)("H:i",e.begin)),e.location&&(0,t.createElement)("div",null,(0,t.createElement)(c.Icon,{icon:"location"})," ",e.location),e.instructor&&(0,t.createElement)("div",null,(0,t.createElement)(c.Icon,{icon:"businessperson"})," ",e.instructor.fullname),(0,t.createElement)("div",null,(0,t.createElement)(c.Icon,{icon:"money"})," ",e.fee),(0,t.createElement)(c.Button,{variant:"tertiary",className:"wp-icon",href:`${n}/courses/${encodeURIComponent(e.courseId)}?${new URLSearchParams({authToken:d}).toString()}`,target:"_blank",rel:"noreferrer"},(0,r.__)("Show","cloudapps_course_manager")))))),0===s.length&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(c.Flex,null,(0,t.createElement)(c.Notice,{status:"info",isDismissible:!1},(0,r.__)("No courses found. Create a new course to get started.","plugin-domain")),(0,t.createElement)(c.Button,{href:`${n}/courses?${new URLSearchParams({action:"create-course",authToken:d}).toString()}`,target:"_blank",rel:"noreferrer",icon:"plus",variant:"secondary"},(0,r.__)("Create course","cloudapps_course_manager")))))))},m=e=>{const[n,o]=(0,a.useState)(null),[l,s]=(0,a.useState)(!1),[u,i]=(0,a.useState)(""),[p,m]=(0,a.useState)("");return(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Login","cloudapps-course-manager"),(0,t.createElement)("br",null),(0,t.createElement)("span",{className:"text-caption"},(0,r.__)("Connect your Cloudapps account.","cloudapps-course-manager")))),(0,t.createElement)(c.CardBody,null,(0,t.createElement)("form",{onSubmit:async t=>{t.preventDefault(),o(null),s(!0),d({email:u,password:p,appUrl:e.appUrl}).then((t=>{e.onLoginCompleted({apiKey:t})})).catch((e=>{o(e)})).finally((()=>{s(!1)}))}},(0,t.createElement)(c.TextControl,{label:(0,r.__)("Email","cloudapps-course-manager"),type:"email",value:u,onChange:e=>i(e),required:!0,autoComplete:"username"}),(0,t.createElement)(c.TextControl,{type:"password",value:p,onChange:e=>m(e),required:!0,label:(0,r.__)("Password","cloudapps-course-manager"),autoComplete:"current-password"}),(0,t.createElement)(c.Button,{type:"submit",variant:"primary",disabled:l},(0,r.__)("Login","cloudapps-course-manager"),l&&(0,t.createElement)(c.Spinner,null)),(0,t.createElement)(c.Button,{onClick:e.onSignUp},(0,r.__)("Create a new account","cloudapps-course-manager")),n&&(0,t.createElement)("p",{className:"text-negative"},n))))},d=async({email:e,password:t,appUrl:a})=>{const n=new URLSearchParams;n.append("username",e),n.append("password",t);const r=await fetch(`${a}/api/auth/token`,{method:"POST",body:n,headers:{"Content-Type":"application/x-www-form-urlencoded"}}).catch((()=>{throw"Failed to connect to the server"}));if(401===r.status)throw"Incorrect username or password";if(!r.ok)throw"Failed to register";const o=(await r.json()).access_token,l=await fetch(`${a}/api/users/generate-api-key`,{method:"POST",headers:{Authorization:`Bearer ${o}`}});if(!l.ok)throw"Failed to generate API key";return(await l.json()).apiKey},_=()=>{const{removeNotice:e}=(0,n.useDispatch)(o.store),a=(0,n.useSelect)((e=>e(o.store).getNotices()));return 0===a.length?null:(0,t.createElement)(c.NoticeList,{notices:a,onRemove:e})},g=e=>{const[n,o]=(0,a.useState)(null),[l,s]=(0,a.useState)(!1),[u,i]=(0,a.useState)(""),[p,m]=(0,a.useState)("");return(0,t.createElement)(c.Card,{elevation:2},(0,t.createElement)(c.CardHeader,{isBorderless:!0},(0,t.createElement)("h2",null,(0,r.__)("Create a new account","cloudapps-course-manager"),(0,t.createElement)("br",null),(0,t.createElement)("span",{className:"text-caption"},(0,r.__)("It's quick and easy.","cloudapps-course-manager")))),(0,t.createElement)(c.CardBody,null,(0,t.createElement)("form",{onSubmit:async t=>{t.preventDefault(),o(null),s(!0),E({email:u,password:p,siteUrl:e.siteUrl,appUrl:e.appUrl}).then((t=>{e.onRegistrationCompleted({apiKey:t.apiKey,tenant:t.tenant})})).catch((e=>{o(e)})).finally((()=>{s(!1)}))}},(0,t.createElement)(c.TextControl,{label:(0,r.__)("Email","cloudapps-course-manager"),type:"email",value:u,onChange:e=>i(e),required:!0,autoComplete:"username"}),(0,t.createElement)(c.TextControl,{type:"password",value:p,onChange:e=>m(e),required:!0,label:(0,r.__)("Password","cloudapps-course-manager"),autoComplete:"new-password"}),(0,t.createElement)(c.Button,{type:"submit",variant:"primary"},(0,r.__)("Register","cloudapps-course-manager"),l&&(0,t.createElement)(c.Spinner,null)),(0,t.createElement)(c.Button,{onClick:e.onSignIn},(0,r.__)("You already have an account?","cloudapps-course-manager")),n&&(0,t.createElement)("p",{className:"text-negative"},n))))},E=async({email:e,password:t,siteUrl:a,appUrl:n})=>{const r=await fetch(`${n}/api/users/register-wordpress`,{method:"POST",body:JSON.stringify({email:e,password:t,siteUrl:a}),headers:{"Content-Type":"application/json"}}).catch((()=>{throw"Failed to connect to the server"}));if(!r.ok)throw"Failed to register";return await r.json()},w=()=>{const{saveSettings:e,settings:l,siteUrl:c}=(()=>{const[e,t]=(0,a.useState)(),[n,r]=(0,a.useState)();return(0,a.useEffect)((()=>{s()({path:"/wp/v2/settings"}).then((e=>{t(e.cloudapps_course_manager_options),r(e.url)}))}),[]),{siteUrl:n,settings:e,saveSettings:async a=>{const n={...e,...a};t(n),await s()({path:"/wp/v2/settings",method:"POST",data:{cloudapps_course_manager_options:n}})}}})(),[i,d]=(0,a.useState)(!1),{createSuccessNotice:E}=(0,n.useDispatch)(o.store);return(0,t.createElement)("div",{className:"wrap"},(0,t.createElement)("h1",{className:"wp-heading-inline"},"Cloudapps Course Manager"),(0,t.createElement)(_,null),l&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)("div",{className:"cloudapps-course-manager-settings"},(0,t.createElement)("div",{className:"account-card "},!l.apiKey&&(0,t.createElement)(t.Fragment,null,i&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(g,{appUrl:l.appUrl,siteUrl:c,onRegistrationCompleted:t=>{e({...l,tenant:t.tenant,apiKey:t.apiKey}).then((()=>{E((0,r.__)("Successfully registered.","cloudapps_course_manager"))}))},onSignIn:()=>{d(!1)}})),!i&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(m,{appUrl:l.appUrl,siteUrl:c,onLoginCompleted:t=>{e({...l,tenant:"",apiKey:t.apiKey}).then((()=>{E((0,r.__)("Successfully logged in.","cloudapps_course_manager"))}))},onSignUp:()=>{d(!0)}}))),l.apiKey&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(u,{apiKey:l.apiKey,appUrl:l.appUrl,tenant:l.tenant,onLogout:()=>{e({...l,apiKey:""})},onTenantChanged:t=>{e({...l,tenant:t})}}))),l.tenant&&l.apiKey&&l.appUrl&&(0,t.createElement)("div",{className:"courses"},(0,t.createElement)(p,{apiKey:l.apiKey,appUrl:l.appUrl,tenant:l.tenant})))))},h=document.getElementById("cloudapps-course-manager-holder");a.createRoot?(0,a.createRoot)(h).render((0,t.createElement)(w,null)):(0,a.render)((0,t.createElement)(w,null),h)})(); -
cloudapps-course-manager/trunk/admin/ui/package.json
r3260238 r3290868 1 1 { 2 2 "name": "cloudapps-course-manager-admin-ui", 3 "version": "1.0. 0",3 "version": "1.0.1", 4 4 "main": "build/index.js", 5 5 "license": "GPL-2.0-or-later", -
cloudapps-course-manager/trunk/admin/ui/src/components/courses.js
r3260238 r3290868 80 80 <span className={'text-caption'}> 81 81 {__( 82 'Stay Organized and Ready: Manage Your Upcoming Courses.',82 'Stay organized and ready: Manage your upcoming courses.', 83 83 'cloudapps-course-manager' 84 84 )} -
cloudapps-course-manager/trunk/admin/ui/src/components/login-form.js
r3260238 r3290868 39 39 <CardHeader isBorderless> 40 40 <h2> 41 {__('Log in', 'cloudapps-course-manager')}41 {__('Login', 'cloudapps-course-manager')} 42 42 <br /> 43 43 <span className={'text-caption'}> … … 72 72 </Button> 73 73 <Button onClick={props.onSignUp}> 74 {__('Create new account', 'cloudapps-course-manager')}74 {__('Create a new account', 'cloudapps-course-manager')} 75 75 </Button> 76 76 {error && <p className={'text-negative'}>{error}</p>} -
cloudapps-course-manager/trunk/admin/ui/src/components/registration-form.js
r3260238 r3290868 75 75 <Button onClick={props.onSignIn}> 76 76 {__( 77 'You have alreadyan account?',77 'You already have an account?', 78 78 'cloudapps-course-manager' 79 79 )} -
cloudapps-course-manager/trunk/block/course-list/build/index.asset.php
r3260238 r3290868 1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => ' c58e8c81418995a709d2');1 <?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '15023dd79f5f9d079e42'); -
cloudapps-course-manager/trunk/block/course-list/build/index.js
r3260238 r3290868 1 (()=>{"use strict";var e,t={131:(e,t,a)=>{const n=window.wp.blocks,r=window.React,o=window.wp.i18n,l=window.wp.blockEditor,s=window.wp.components,i=window.wp.apiFetch;var c=a.n(i);const u=window.wp.element,p=({appUrl:e,apiKey:t,children:a})=>{const[n,l]=(0,u.useState)(!0);return(0,u.useEffect)((()=>{(async()=>{const a=new URLSearchParams({api_key:t});await fetch(`${e}/api/users/me?${a.toString()}`).then((async e=>{e.ok||l(!1)}))})()}),[t,e]),(0,r.createElement)(r.Fragment,null,!n&&(0,r.createElement)("span",{className:"text-negative"},(0,o.__)(" It seems there is a problem with your account. Please check the plugin settings.","cloudapps_course_manager")),a)},d=({widgetUrl:e,titleFilter:t,bordered:a,denseLayout:n,onlyBookable:o,excludeWaitlist:l,openExternally:s,autoWidth:i,width:c,minRemainingSeats:p,maxRemainingSeats:d,minDaysUntilStart:m,maxDaysUntilStart:g})=>{const h=new URLSearchParams;t&&h.append("text-filter",t),a&&h.append("bordered",a),n&&h.append("dense-layout",n),o&&h.append("only-bookable",o),l&&h.append("exclude-waitlist",l),s&&h.append("open-externally",s),p&&h.append("min-remaining-seats",p),d&&h.append("max-remaining-seats",d),m&&h.append("min-days-until-start",m),g&&h.append("max-days-until-start",g);const b={};b.width=i?"100%":c||1024,b.scrolling="no",a||(b.style={border:"none"});const y=(0,u.useRef)();return(0,u.useEffect)((()=>{const e=y.current;window.addEventListener("message",(t=>{e.getAttribute("src").includes(t.origin)&&"contentHeight"in t.data&&!isNaN(t.data.contentHeight)&&(e.height=t.data.contentHeight)}))}),[e]),(0,r.createElement)(r.Fragment,null,(0,r.createElement)("iframe",{ref:y,title:"Cloudapps Course List",src:e+"?"+h.toString(),...b}))},m=JSON.parse('{"UU":"cloudapps-course-manager/course-list-block"}');(0,n.registerBlockType)(m.UU,{edit:function({attributes:e,setAttributes:t,clientId:a}){t({widgetId:a.substring(0,8)});const[n,i]=(0,u.useState)(),[m,g]=(0,u.useState)();(0,u.useEffect)((()=>{c()({path:"/wp/v2/settings"}).then((e=>{i(e.cloudapps_course_manager_options)}))}),[]),(0,u.useEffect)((()=>{n&&g({...e,widgetUrl:`${n.appUrl}/embed/${encodeURIComponent(n.tenant)}/course-list`})}),[e,n]);const{titleFilter:h}=e;return(0,r.createElement)(r.Fragment,null,(0,r.createElement)(l.InspectorControls,null,(0,r.createElement)(s.PanelBody,{title:(0,o.__)("Settings","cloudapps-course-manager")},(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Border","cloudapps-course-manager"),checked:e.bordered,onChange:e=>t({bordered:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Dense","cloudapps-course-manager"),checked:e.denseLayout,onChange:e=>t({denseLayout:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Only bookable","cloudapps-course-manager"),checked:e.onlyBookable,onChange:e=>t({onlyBookable:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Exclude waitlist","cloudapps-course-manager"),checked:e.excludeWaitlist,onChange:e=>t({excludeWaitlist:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Open in new Tab","cloudapps-course-manager"),checked:e.openExternally,onChange:e=>t({openExternally:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Auto width","cloudapps-course-manager"),checked:e.autoWidth,onChange:e=>t({autoWidth:e})}),!e.autoWidth&&(0,r.createElement)(s.RangeControl,{RangeControl:!0,label:(0,o.__)("Width","cloudapps-course-manager"),value:e.width,onChange:e=>t({width:e}),min:100,max:1024}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Title contains","cloudapps-course-manager"),value:h||"",onChange:e=>t({titleFilter:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Minimum remaining seats","cloudapps-course-manager"),value:e.minRemainingSeats,type:"number",onChange:e=>t({minRemainingSeats:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Maximum remaining seats","cloudapps-course-manager"),value:e.maxRemainingSeats,type:"number",onChange:e=>t({maxRemainingSeats:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Minimum days until start","cloudapps-course-manager"),value:e.minDaysUntilStart,type:"number",onChange:e=>t({minDaysUntilStart:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Maximum days until start","cloudapps-course-manager"),value:e.maxDaysUntilStart,type:"number",onChange:e=>t({maxDaysUntilStart:e})}))),(0,r.createElement)("p",{...(0,l.useBlockProps)()},n&&(0,r.createElement)(p,{...n},(0,r.createElement)(d,{key:JSON.stringify(e),...m}))))}})}},a={};function n(e){var r=a[e];if(void 0!==r)return r.exports;var o=a[e]={exports:{}};return t[e](o,o.exports,n),o.exports}n.m=t,e=[],n.O=(t,a,r,o)=>{if(!a){var l=1/0;for(u=0;u<e.length;u++){a=e[u][0],r=e[u][1],o=e[u][2];for(var s=!0,i=0;i<a.length;i++)(!1&o||l>=o)&&Object.keys(n.O).every((e=>n.O[e](a[i])))?a.splice(i--,1):(s=!1,o<l&&(l=o));if(s){e.splice(u--,1);var c=r();void 0!==c&&(t=c)}}return t}o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[a,r,o]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var a in t)n.o(t,a)&&!n.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};n.O.j=t=>0===e[t];var t=(t,a)=>{var r,o,l=a[0],s=a[1],i=a[2],c=0;if(l.some((t=>0!==e[t]))){for(r in s)n.o(s,r)&&(n.m[r]=s[r]);if(i)var u=i(n)}for(t&&t(a);c<l.length;c++)o=l[c],n.o(e,o)&&e[o]&&e[o][0](),e[o]=0;return n.O(u)},a=self.webpackChunkcloudapps_course_list=self.webpackChunkcloudapps_course_list||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var r=n.O(void 0,[350],(()=>n(131)));r=n.O(r)})();1 (()=>{"use strict";var e,t={131:(e,t,a)=>{const n=window.wp.blocks,r=window.React,o=window.wp.i18n,l=window.wp.blockEditor,s=window.wp.components,i=window.wp.apiFetch;var c=a.n(i);const u=window.wp.element,p=({appUrl:e,apiKey:t,children:a})=>{const[n,l]=(0,u.useState)(!0);return(0,u.useEffect)((()=>{(async()=>{const a=new URLSearchParams({api_key:t});await fetch(`${e}/api/users/me?${a.toString()}`).then((async e=>{e.ok||l(!1)}))})()}),[t,e]),(0,r.createElement)(r.Fragment,null,!n&&(0,r.createElement)("span",{className:"text-negative"},(0,o.__)("There seems to be a problem with your account. Please check the plugin settings.","cloudapps_course_manager")),a)},d=({widgetUrl:e,titleFilter:t,bordered:a,denseLayout:n,onlyBookable:o,excludeWaitlist:l,openExternally:s,autoWidth:i,width:c,minRemainingSeats:p,maxRemainingSeats:d,minDaysUntilStart:m,maxDaysUntilStart:g})=>{const h=new URLSearchParams;t&&h.append("text-filter",t),a&&h.append("bordered",a),n&&h.append("dense-layout",n),o&&h.append("only-bookable",o),l&&h.append("exclude-waitlist",l),s&&h.append("open-externally",s),p&&h.append("min-remaining-seats",p),d&&h.append("max-remaining-seats",d),m&&h.append("min-days-until-start",m),g&&h.append("max-days-until-start",g);const b={};b.width=i?"100%":c||1024,b.scrolling="no",a||(b.style={border:"none"});const y=(0,u.useRef)();return(0,u.useEffect)((()=>{const e=y.current;window.addEventListener("message",(t=>{e.getAttribute("src").includes(t.origin)&&"contentHeight"in t.data&&!isNaN(t.data.contentHeight)&&(e.height=t.data.contentHeight)}))}),[e]),(0,r.createElement)(r.Fragment,null,(0,r.createElement)("iframe",{ref:y,title:"Cloudapps Course List",src:e+"?"+h.toString(),...b}))},m=JSON.parse('{"UU":"cloudapps-course-manager/course-list-block"}');(0,n.registerBlockType)(m.UU,{edit:function({attributes:e,setAttributes:t,clientId:a}){t({widgetId:a.substring(0,8)});const[n,i]=(0,u.useState)(),[m,g]=(0,u.useState)();(0,u.useEffect)((()=>{c()({path:"/wp/v2/settings"}).then((e=>{i(e.cloudapps_course_manager_options)}))}),[]),(0,u.useEffect)((()=>{n&&g({...e,widgetUrl:`${n.appUrl}/embed/${encodeURIComponent(n.tenant)}/course-list`})}),[e,n]);const{titleFilter:h}=e;return(0,r.createElement)(r.Fragment,null,(0,r.createElement)(l.InspectorControls,null,(0,r.createElement)(s.PanelBody,{title:(0,o.__)("Settings","cloudapps-course-manager")},(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Border","cloudapps-course-manager"),checked:e.bordered,onChange:e=>t({bordered:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Dense","cloudapps-course-manager"),checked:e.denseLayout,onChange:e=>t({denseLayout:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Only bookable","cloudapps-course-manager"),checked:e.onlyBookable,onChange:e=>t({onlyBookable:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Exclude waitlist","cloudapps-course-manager"),checked:e.excludeWaitlist,onChange:e=>t({excludeWaitlist:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Open in new tab","cloudapps-course-manager"),checked:e.openExternally,onChange:e=>t({openExternally:e})}),(0,r.createElement)(s.ToggleControl,{label:(0,o.__)("Auto width","cloudapps-course-manager"),checked:e.autoWidth,onChange:e=>t({autoWidth:e})}),!e.autoWidth&&(0,r.createElement)(s.RangeControl,{RangeControl:!0,label:(0,o.__)("Width","cloudapps-course-manager"),value:e.width,onChange:e=>t({width:e}),min:100,max:1024}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Title contains","cloudapps-course-manager"),value:h||"",onChange:e=>t({titleFilter:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Minimum remaining seats","cloudapps-course-manager"),value:e.minRemainingSeats,type:"number",onChange:e=>t({minRemainingSeats:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Maximum remaining seats","cloudapps-course-manager"),value:e.maxRemainingSeats,type:"number",onChange:e=>t({maxRemainingSeats:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Minimum days until start","cloudapps-course-manager"),value:e.minDaysUntilStart,type:"number",onChange:e=>t({minDaysUntilStart:e})}),(0,r.createElement)(s.TextControl,{label:(0,o.__)("Maximum days until start","cloudapps-course-manager"),value:e.maxDaysUntilStart,type:"number",onChange:e=>t({maxDaysUntilStart:e})}))),(0,r.createElement)("p",{...(0,l.useBlockProps)()},n&&(0,r.createElement)(p,{...n},(0,r.createElement)(d,{key:JSON.stringify(e),...m}))))}})}},a={};function n(e){var r=a[e];if(void 0!==r)return r.exports;var o=a[e]={exports:{}};return t[e](o,o.exports,n),o.exports}n.m=t,e=[],n.O=(t,a,r,o)=>{if(!a){var l=1/0;for(u=0;u<e.length;u++){a=e[u][0],r=e[u][1],o=e[u][2];for(var s=!0,i=0;i<a.length;i++)(!1&o||l>=o)&&Object.keys(n.O).every((e=>n.O[e](a[i])))?a.splice(i--,1):(s=!1,o<l&&(l=o));if(s){e.splice(u--,1);var c=r();void 0!==c&&(t=c)}}return t}o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[a,r,o]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var a in t)n.o(t,a)&&!n.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={57:0,350:0};n.O.j=t=>0===e[t];var t=(t,a)=>{var r,o,l=a[0],s=a[1],i=a[2],c=0;if(l.some((t=>0!==e[t]))){for(r in s)n.o(s,r)&&(n.m[r]=s[r]);if(i)var u=i(n)}for(t&&t(a);c<l.length;c++)o=l[c],n.o(e,o)&&e[o]&&e[o][0](),e[o]=0;return n.O(u)},a=self.webpackChunkcloudapps_course_list=self.webpackChunkcloudapps_course_list||[];a.forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a))})();var r=n.O(void 0,[350],(()=>n(131)));r=n.O(r)})(); -
cloudapps-course-manager/trunk/block/course-list/package.json
r3260238 r3290868 1 1 { 2 2 "name": "cloudapps-course-list", 3 "version": "1.0. 0",3 "version": "1.0.1", 4 4 "description": "List upcoming courses.", 5 5 "author": "Manuel Holzrichter", -
cloudapps-course-manager/trunk/block/course-list/src/components/account-checker.js
r3260238 r3290868 23 23 <span className="text-negative"> 24 24 {__( 25 ' It seems there isa problem with your account. Please check the plugin settings.',25 'There seems to be a problem with your account. Please check the plugin settings.', 26 26 'cloudapps_course_manager' 27 27 )} -
cloudapps-course-manager/trunk/block/course-list/src/edit.js
r3260238 r3290868 98 98 <ToggleControl 99 99 label={__( 100 'Open in new Tab',100 'Open in new tab', 101 101 'cloudapps-course-manager' 102 102 )} -
cloudapps-course-manager/trunk/cloudapps-course-manager.php
r3260238 r3290868 6 6 * Requires at least: 5.6 7 7 * Requires PHP: 7.0 8 * Version: 1.0. 08 * Version: 1.0.1 9 9 * Author: Manuel Holzrichter 10 10 * Author URI: https://www.manuel-holzrichter.de/ -
cloudapps-course-manager/trunk/readme.txt
r3286487 r3290868 1 1 === Cloudapps Course Manager === 2 Contributors: mholzrichter, texperience 2 Contributors: mholzrichter, texperience, trieber 3 3 Tags: Course, Event, Efficiency, Office, Booking 4 4 Tested up to: 6.8 5 Stable tag: 1.0. 05 Stable tag: 1.0.1 6 6 Requires PHP: 7.0 7 7 Requires at least: 5.6 … … 12 12 13 13 == Description == 14 Cloudapps Course Manager is a comprehensive WordPress plugin that integrates the powerful course management features of [Cloudapps](https://www.texperience.de/#cloudapps) directly into your WordPress site. Designed for trainers, educators, and business owners, this plugin simplifies the process of organizing, delivering, and managing both online and on-site courses from a single centralized platform.14 Cloudapps Course Manager is a comprehensive WordPress plugin that integrates the powerful course management features of [Cloudapps](https://www.texperience.de/#cloudapps) directly into your WordPress site. Designed for freelancers, sports clubs, companies and their staff, this plugin simplifies the process of organizing, delivering, and managing both online and on-site courses from a single centralized platform. 15 15 16 16 Key features include: 17 * **Seamless Cloudapps Integration:** Easily connect your active Cloudapps account to manage courses through your WordPress admin.18 * **Online Registration & Payment:** Enable customers to register and pay for courses directly on your website.19 * **Automated Course Listings:** Dynamically display upcoming courses, ensuring your site always features the latest information.20 * **Efficient Administration:** Reduce time spent on administrative tasks, allowing you to focus on adding value for your customers.21 17 22 Inspired by the need of a self-employed midwife to save approximately 10 hours per week on course management, Cloudapps Course Manager was built to empower professionals by streamlining the registration process and course display, letting you spend more time on what truly matters. 18 * **Seamless Cloudapps integration:** Easily connect your active Cloudapps account to manage courses through your WordPress admin. 19 * **Online registration & payment:** Enable customers to register and pay for courses directly on your website. 20 * **Automated course listings:** Dynamically display upcoming courses, ensuring your site always features the latest information. 21 * **Efficient administration:** Reduce time spent on administrative tasks, allowing you to focus on adding value for your customers. 22 23 Inspired by the need of a self-employed midwife to save countless hours per week on course management, Cloudapps was built to empower professionals by streamlining the registration process and the publication of courses, letting you spend more time on what truly matters. 23 24 24 25 == Installation == 26 **Note:** An active Cloudapps account is required. Visit [Cloudapps](https://cloudapps.texperience.de) for account setup or register directly through the plugin admin interface. 27 25 28 1. Upload the plugin files to the `/wp-content/plugins/cloudapps-course-manager` directory, or install the plugin through the WordPress plugin installer. 26 29 2. Activate the plugin via the 'Plugins' screen in your WordPress dashboard. 27 30 3. Go to **Settings > Cloudapps Course Manager** and follow the on-screen instructions to configure the plugin and connect it to your Cloudapps account. 28 * **Note:** An active Cloudapps account is required. Visit [Cloudapps](https://cloudapps.texperience.de) for account setup and further details.29 31 30 32 == Frequently Asked Questions == 31 33 = Why do I need a Cloudapps account? = 32 An active Cloudapps account allows you to manage courses, track registrations, and process payments seamlessly—reducing the time spent on manual administrative tasks. 34 An active Cloudapps account allows you to manage courses, track registrations, communicate with your attendees, and process payments seamlessly—reducing the time spent on manual administrative tasks. 35 33 36 = How do I update my Cloudapps account credentials? = 34 Simply navigate to the Cloudapps Course Manager settings page and update your API credentials using the provided interface. 37 Navigate to the Cloudapps Course Manager plugin admin interface and update your credentials. 38 35 39 = What payment methods are supported? = 36 40 Payments are handled through Cloudapps. For detailed information on supported payment options, please refer to the Cloudapps documentation. 41 37 42 = I’m experiencing connectivity issues. What should I do? = 38 Verify that your APIcredentials are correct and ensure that your hosting environment meets the required PHP version. If issues persist, please contact our support team.43 Verify that your credentials are correct and ensure that your hosting environment meets the required PHP version. If issues persist, please contact our support team. 39 44 40 45 == Screenshots == 41 1. **Initial Settings Page:** The Cloudapps Course Manager settings page before connecting to Cloudapps.42 2. **Connected Settings Page:** The settings page displaying active courses retrieved from Cloudapps after a successful connection.43 3. ** Courselist Block in Editor:** The interface for adding and configuring the courselist block within the WordPress editor.44 4. ** Live Course Display:** How the courselist block appears on the published page.46 1. **Initial settings page:** The Cloudapps Course Manager plugin admin interface before connecting to Cloudapps. 47 2. **Connected settings page:** The admin interface displaying active courses retrieved from Cloudapps after a successful connection. 48 3. **"Courselist" block in editor:** The interface for adding and configuring the courselist block within the WordPress editor. 49 4. **Published widget:** How the courselist block appears on the published page. 45 50 46 51 == Changelog == 52 = 1.0.1 = 53 * Improve UI wording 54 47 55 = 1.0.0 = 48 * Initial release of Cloudapps Course Manager. 49 * Added a settings page for Cloudapps connection and course management. 50 * Implemented the Courselist Block for displaying courses on your website. 56 * Add the plugin admin interface for Cloudapps connection and course management 57 * Provide the Courselist block to integrate courses in your website 51 58 52 59 == Upgrade Notice == 53 = 1.0.0 = 54 Initial release of Cloudapps Course Manager. Please follow the installation and configuration instructions carefully for optimal performance. 60 Please follow the installation and configuration instructions carefully. 55 61 56 62 == Support and Documentation == 57 63 For support, troubleshooting, or feature requests, please: 58 * Email us at [office@texperience.de](mailto:office@texperience.de) 64 65 * Email us at [cloudapps@texperience.de](mailto:cloudapps@texperience.de) 59 66 * Visit our website at [texperience.de](https://www.texperience.de) for detailed documentation and updates. 60 * Check oursupport forum for community assistance and developer contributions.67 * Check the WordPress support forum for community assistance and developer contributions. 61 68 62 69 == Requirements == 63 70 * WordPress 5.6 or later 64 71 * PHP 7.0 or later 65 * An active Cloudapps account (required for full functionality)72 * An active Cloudapps account 66 73 67 74 == External services == 75 This plugin allows you to embed any number of configurable widgets (blocks in the WordPress editor) to display course information on your website pages. Visitors can browse the displayed courses and register for them directly on your website. Technically, the widgets are implemented as iframes that show the embeddable Cloudapps user interfaces. Visitors provide their required personal data for registration explicitly over the Cloudapps user interface. The plugin doesn't receive or store any personal data of the visitors. 68 76 69 This plugin allows you to embed any number of configurable widgets (blocks in the WordPress editor) to display course information on your website pages. End users can browse the displayed courses and register for them directly on your website. Technically, the widgets are implemented as iframes that show the embeddable Cloudapps user interfaces. End users provide their required personal data for registration explicitly over the Cloudapps user interface. The plugin doesn't receive or store any personal data of the end users. 70 71 The admin interface connects to the service using an API key. This API key is retrieved over a secure connection after the user provides their Cloudapps credentials. The user can then select the tenant and preview the currently available courses of this tenant. API key and tenant selection are stored in the WordPress database. The plugin doesn't retrieve or store any personal data of the connected user. The tenant selection serves as global setting for all widgets. 77 The plugin admin interface connects to the service using an API key. This API key is retrieved over a secure connection after the user provides their Cloudapps account credentials. The user can then select the tenant and preview the currently available courses of this tenant. API key and tenant selection are stored in the WordPress database. The plugin doesn't retrieve or store any personal data of the connected user. The tenant selection serves as global setting for all widgets. 72 78 73 79 This service is provided by texperience (https://www.texperience.de) and is subject to their terms of service (https://www.texperience.de/nutzungsbedingungen) and privacy policy (https://www.texperience.de/datenschutz).
Note: See TracChangeset
for help on using the changeset viewer.