diff --git a/packages/acquisition-manager/index.js b/packages/acquisition-manager/index.js index 2eb5d80..533d6a0 100644 --- a/packages/acquisition-manager/index.js +++ b/packages/acquisition-manager/index.js @@ -1 +1 @@ -import{defineModule as e}from"@directus/extensions-sdk";import{defineComponent as t,resolveComponent as n,openBlock as a,createBlock as i,withCtx as r,createElementVNode as o}from"vue";var s=t({__name:"module",setup:e=>(e,t)=>{const s=n("private-view");return a(),i(s,{title:"Acquisition Manager"},{default:r(()=>[...t[0]||(t[0]=[o("div",{class:"acquisition-manager"},[o("h1",null,"Acquisition Manager"),o("p",null,"Modern Industrial Acquisition Management Interface")],-1)])]),_:1})}}),u=[],c=[];!function(e,t){if(e&&"undefined"!=typeof document){var n,a=!0===t.prepend?"prepend":"append",i=!0===t.singleTag,r="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(i){var o=u.indexOf(r);-1===o&&(o=u.push(r)-1,c[o]={}),n=c[o]&&c[o][a]?c[o][a]:c[o][a]=s()}else n=s();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function s(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var n=Object.keys(t.attributes),i=0;i{const n=e.__vccOpts||e;for(const[e,a]of t)n[e]=a;return n})(s,[["__scopeId","data-v-19f4e937"],["__file","module.vue"]])}]});export{d as default}; +import{useApi as e,defineModule as a}from"@directus/extensions-sdk";import{defineComponent as t,ref as l,computed as n,onMounted as i,resolveComponent as s,resolveDirective as o,openBlock as d,createBlock as r,withCtx as u,createVNode as c,createElementBlock as v,Fragment as p,renderList as m,createTextVNode as f,toDisplayString as g,createCommentVNode as y,createElementVNode as b,withDirectives as h}from"vue";var _=Object.defineProperty,x=Object.getOwnPropertySymbols,w=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable,V=(e,a,t)=>a in e?_(e,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[a]=t;const A={class:"content-wrapper"},C={key:0,class:"empty-state"},$={class:"header"},U={class:"header-left"},F={class:"title"},O={class:"subtitle"},P=["href"],E={class:"header-right"},S={class:"sections"},j={class:"main-info"},L={class:"form-grid"},z={class:"field"},q={key:1,class:"value text-subdued"},B={class:"field"},N={class:"value"},D={class:"field full"},M={class:"value text-block"},I={key:0,class:"ai-observations"},T={class:"metrics"},K={class:"page-title"},G={class:"page-url"},R={class:"drawer-content"},W={class:"form-section"},H={class:"field"},J={class:"field"},Q={class:"field"},X={class:"field"},Y={class:"field"},Z={class:"field"},ee={class:"drawer-actions"};var ae=t({__name:"module",setup(a){const t=e(),_=l([]),ae=l(null),te=l(!1),le=l(!1),ne=l(!1),ie=l(!1),se=l(!1),oe=l(null),de=l({company_name:"",website_url:"",contact_name:"",contact_email:"",contact_person:null,briefing:"",status:"new"}),re=l([]),ue=n(()=>re.value.map(e=>({text:`${e.first_name} ${e.last_name}`,value:e.id})));function ce(e){const a=re.value.find(a=>a.id===e);return a?`${a.first_name} ${a.last_name}`:e}const ve=n(()=>_.value.find(e=>e.id===ae.value));async function pe(){const[e,a]=await Promise.all([t.get("/items/leads",{params:{sort:"-date_created"}}),t.get("/items/people",{params:{sort:"last_name"}})]);_.value=e.data.data,re.value=a.data.data,!ae.value&&_.value.length>0&&(ae.value=_.value[0].id)}async function me(){if(ae.value){te.value=!0;try{await t.post(`/acquisition/audit/${ae.value}`),oe.value={type:"success",message:"Audit erfolgreich gestartet!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler beim Audit: ${e.message}`}}finally{te.value=!1}}}async function fe(){if(ae.value){ne.value=!0;try{await t.post(`/acquisition/audit-email/${ae.value}`),oe.value={type:"success",message:"Audit E-Mail versendet!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler beim Versenden: ${e.message}`}}finally{ne.value=!1}}}async function ge(){if(ae.value){le.value=!0;try{await t.post(`/acquisition/estimate/${ae.value}`),oe.value={type:"success",message:"Angebot (PDF) wurde generiert!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler bei PDF Generierung: ${e.message}`}}finally{le.value=!1}}}async function ye(){if(ae.value){ne.value=!0;try{await t.post(`/acquisition/estimate-email/${ae.value}`),oe.value={type:"success",message:"Angebot erfolgreich versendet!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler beim Versenden: ${e.message}`}}finally{ne.value=!1}}}function be(){var e;(null==(e=ve.value)?void 0:e.audit_pdf_path)&&window.open(`${window.location.origin}/assets/${ve.value.audit_pdf_path}`,"_blank")}async function he(){if(de.value.company_name){se.value=!0;try{const e=((e,a)=>{for(var t in a||(a={}))w.call(a,t)&&V(e,t,a[t]);if(x)for(var t of x(a))k.call(a,t)&&V(e,t,a[t]);return e})({id:crypto.randomUUID()},de.value);await t.post("/items/leads",e),oe.value={type:"success",message:"Lead erfolgreich registriert!"},ie.value=!1,await pe(),ae.value=e.id,de.value={company_name:"",website_url:"",contact_name:"",contact_email:"",contact_person:null,briefing:"",status:"new"}}catch(e){oe.value={type:"danger",message:`Fehler beim Speichern: ${e.message}`}}finally{se.value=!1}}}function _e(e){switch(e){case"new":return"fiber_new";case"auditing":return"hourglass_empty";case"audit_ready":return"check_circle";case"contacted":return"mail_outline";default:return"help_outline"}}function xe(e){switch(e){case"new":return"var(--theme--primary)";case"auditing":return"var(--theme--warning)";case"audit_ready":return"var(--theme--success)";case"contacted":return"var(--theme--secondary)";default:return"var(--theme--foreground-subdued)"}}return i(pe),(e,a)=>{const t=s("v-icon"),l=s("v-list-item-icon"),n=s("v-text-overflow"),i=s("v-list-item-content"),x=s("v-list-item"),w=s("v-divider"),k=s("v-list"),V=s("v-notice"),re=s("v-button"),pe=s("v-info"),we=s("v-table"),ke=s("v-input"),Ve=s("v-textarea"),Ae=s("v-select"),Ce=s("v-drawer"),$e=s("private-view"),Ue=o("tooltip");return d(),r($e,{title:"Acquisition Manager"},{navigation:u(()=>[c(k,{nav:""},{default:u(()=>[c(x,{onClick:a[0]||(a[0]=e=>ie.value=!0),clickable:""},{default:u(()=>[c(l,null,{default:u(()=>[c(t,{name:"add",color:"var(--theme--primary)"})]),_:1}),c(i,null,{default:u(()=>[c(n,{text:"Neuen Lead anlegen"})]),_:1})]),_:1}),c(w),(d(!0),v(p,null,m(_.value,e=>(d(),r(x,{key:e.id,active:ae.value===e.id,class:"lead-item",clickable:"",onClick:a=>{return t=e.id,void(ae.value=t);var t}},{default:u(()=>[c(l,null,{default:u(()=>[c(t,{name:_e(e.status),color:xe(e.status)},null,8,["name","color"])]),_:2},1024),c(i,null,{default:u(()=>[c(n,{text:e.company_name},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","onClick"]))),128))]),_:1})]),"title-outer:after":u(()=>[oe.value?(d(),r(V,{key:0,type:oe.value.type,onClose:a[1]||(a[1]=e=>oe.value=null),dismissible:""},{default:u(()=>[f(g(oe.value.message),1)]),_:1},8,["type"])):y("v-if",!0)]),default:u(()=>{var e;return[b("div",A,[c(V,{type:"success",style:{"margin-bottom":"16px"}},{default:u(()=>[f(" DEBUG: Module Version 1.1.0 - Native Build - "+g((new Date).toISOString()),1)]),_:1}),ve.value?(d(),v(p,{key:1},[b("header",$,[b("div",U,[b("h1",F,g(ve.value.company_name),1),b("p",O,[c(t,{name:"language","x-small":""}),b("a",{href:ve.value.website_url,target:"_blank",class:"url-link"},g(ve.value.website_url.replace(/^https?:\/\//,"")),9,P),f(" · Status: "+g(ve.value.status.toUpperCase()),1)])]),b("div",E,["new"===ve.value.status?(d(),r(re,{key:0,secondary:"",loading:te.value,onClick:me},{default:u(()=>[c(t,{name:"settings_suggest",left:""}),a[15]||(a[15]=f(" Audit starten ",-1))]),_:1},8,["loading"])):y("v-if",!0),"audit_ready"===ve.value.status?(d(),v(p,{key:1},[c(re,{secondary:"",loading:ne.value,onClick:fe},{default:u(()=>[c(t,{name:"mail",left:""}),a[16]||(a[16]=f(" Audit E-Mail ",-1))]),_:1},8,["loading"]),c(re,{loading:le.value,onClick:ge},{default:u(()=>[c(t,{name:"picture_as_pdf",left:""}),a[17]||(a[17]=f(" PDF Erstellen ",-1))]),_:1},8,["loading"])],64)):y("v-if",!0),ve.value.audit_pdf_path?h((d(),r(re,{key:2,secondary:"",icon:"",onClick:be},{default:u(()=>[c(t,{name:"open_in_new"})]),_:1})),[[Ue,"PDF öffnen",void 0,{bottom:!0}]]):y("v-if",!0),ve.value.audit_pdf_path?(d(),r(re,{key:3,primary:"",loading:ne.value,onClick:ye},{default:u(()=>[c(t,{name:"send",left:""}),a[18]||(a[18]=f(" Angebot senden ",-1))]),_:1},8,["loading"])):y("v-if",!0)])]),b("div",S,[b("div",j,[b("div",L,[b("div",z,[a[19]||(a[19]=b("span",{class:"label"},"Kontaktperson",-1)),ve.value.contact_person?(d(),v("div",{key:0,class:"value person-link",onClick:a[3]||(a[3]=e=>{return a=ve.value.contact_person,void(oe.value={type:"info",message:`Navigiere zu Person: ${a}`});var a})},g(ce(ve.value.contact_person)),1)):(d(),v("div",q,"Keine Person verknüpft"))]),b("div",B,[a[20]||(a[20]=b("span",{class:"label"},"E-Mail (Legacy)",-1)),b("div",N,g(ve.value.contact_email||"—"),1)]),b("div",D,[a[21]||(a[21]=b("span",{class:"label"},"Briefing / Fokus",-1)),b("div",M,g(ve.value.briefing||"Kein Briefing hinterlegt."),1)])])]),c(w),ve.value.ai_state?(d(),v("div",I,[a[22]||(a[22]=b("h3",{class:"section-title"},"AI Observations & Estimation",-1)),b("div",T,[c(pe,{label:"Projekt-Modus",value:ve.value.ai_state.projectType||"Unbekannt"},null,8,["value"]),c(pe,{label:"Seitenanzahl",value:(null==(e=ve.value.ai_state.sitemap)?void 0:e.length)||"0"},null,8,["value"])]),ve.value.ai_state.sitemap?(d(),r(we,{key:0,headers:[{text:"Seite",value:"title"},{text:"URL",value:"url"}],items:ve.value.ai_state.sitemap,class:"observation-table"},{"item.title":u(({item:e})=>[b("span",K,g(e.title),1)]),"item.url":u(({item:e})=>[b("span",G,g(e.url),1)]),_:2},1032,["items"])):y("v-if",!0)])):y("v-if",!0)])],64)):(d(),v("div",C,[c(pe,{title:"Lead auswählen",icon:"auto_awesome",center:""},{default:u(()=>[a[13]||(a[13]=f(" Wähle einen Lead in der Navigation aus oder ",-1)),c(re,{"x-small":"",onClick:a[2]||(a[2]=e=>ie.value=!0)},{default:u(()=>[...a[12]||(a[12]=[f("registriere einen neuen Lead",-1)])]),_:1}),a[14]||(a[14]=f(". ",-1))]),_:1})]))]),c(Ce,{modelValue:ie.value,"onUpdate:modelValue":a[10]||(a[10]=e=>ie.value=e),title:"Neuen Lead registrieren",icon:"person_add",onCancel:a[11]||(a[11]=e=>ie.value=!1)},{default:u(()=>[b("div",R,[b("div",W,[b("div",H,[a[23]||(a[23]=b("span",{class:"label"},"Firma",-1)),c(ke,{modelValue:de.value.company_name,"onUpdate:modelValue":a[4]||(a[4]=e=>de.value.company_name=e),placeholder:"z.B. Schmidt GmbH",autofocus:""},null,8,["modelValue"])]),b("div",J,[a[24]||(a[24]=b("span",{class:"label"},"Website URL",-1)),c(ke,{modelValue:de.value.website_url,"onUpdate:modelValue":a[5]||(a[5]=e=>de.value.website_url=e),placeholder:"https://..."},null,8,["modelValue"])]),b("div",Q,[a[25]||(a[25]=b("span",{class:"label"},"Ansprechpartner",-1)),c(ke,{modelValue:de.value.contact_name,"onUpdate:modelValue":a[6]||(a[6]=e=>de.value.contact_name=e),placeholder:"Vorname Nachname"},null,8,["modelValue"])]),b("div",X,[a[26]||(a[26]=b("span",{class:"label"},"E-Mail Adresse",-1)),c(ke,{modelValue:de.value.contact_email,"onUpdate:modelValue":a[7]||(a[7]=e=>de.value.contact_email=e),placeholder:"email@beispiel.de",type:"email"},null,8,["modelValue"])]),b("div",Y,[a[27]||(a[27]=b("span",{class:"label"},"Briefing / Fokus",-1)),c(Ve,{modelValue:de.value.briefing,"onUpdate:modelValue":a[8]||(a[8]=e=>de.value.briefing=e),placeholder:"Besonderheiten für das Audit..."},null,8,["modelValue"])]),b("div",Z,[a[28]||(a[28]=b("span",{class:"label"},"Kontaktperson (Optional)",-1)),c(Ae,{modelValue:de.value.contact_person,"onUpdate:modelValue":a[9]||(a[9]=e=>de.value.contact_person=e),items:ue.value,placeholder:"Person auswählen..."},null,8,["modelValue","items"])])]),b("div",ee,[c(re,{primary:"",block:"",loading:se.value,onClick:he},{default:u(()=>[...a[29]||(a[29]=[f("Lead speichern",-1)])]),_:1},8,["loading"])])])]),_:1},8,["modelValue"])]}),_:1})}}}),te=[],le=[];!function(e,a){if(e&&"undefined"!=typeof document){var t,l=!0===a.prepend?"prepend":"append",n=!0===a.singleTag,i="string"==typeof a.container?document.querySelector(a.container):document.getElementsByTagName("head")[0];if(n){var s=te.indexOf(i);-1===s&&(s=te.push(i)-1,le[s]={}),t=le[s]&&le[s][l]?le[s][l]:le[s][l]=o()}else t=o();65279===e.charCodeAt(0)&&(e=e.substring(1)),t.styleSheet?t.styleSheet.cssText+=e:t.appendChild(document.createTextNode(e))}function o(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),a.attributes)for(var t=Object.keys(a.attributes),n=0;n{const t=e.__vccOpts||e;for(const[e,l]of a)t[e]=l;return t})(ae,[["__scopeId","data-v-6a55edd7"],["__file","module.vue"]]),ie=a({id:"acquisition-manager",name:"Acquisition",icon:"auto_awesome",routes:[{path:"",component:ne},{path:":id",component:ne,props:!0}]});export{ie as default}; diff --git a/packages/acquisition-manager/src/index.ts b/packages/acquisition-manager/src/index.ts index 52e17e6..cfd5aee 100644 --- a/packages/acquisition-manager/src/index.ts +++ b/packages/acquisition-manager/src/index.ts @@ -1,14 +1,19 @@ -import { defineModule } from '@directus/extensions-sdk'; -import ModuleComponent from './module.vue'; +import { defineModule } from "@directus/extensions-sdk"; +import ModuleComponent from "./module.vue"; export default defineModule({ - id: 'acquisition-manager', - name: 'Acquisition Manager', - icon: 'account_balance_wallet', + id: "acquisition-manager", + name: "Acquisition", + icon: "auto_awesome", routes: [ { - path: '', + path: "", component: ModuleComponent, }, + { + path: ":id", + component: ModuleComponent, + props: true + } ], }); diff --git a/packages/acquisition-manager/src/module.vue b/packages/acquisition-manager/src/module.vue index 951b0d5..8e3b483 100644 --- a/packages/acquisition-manager/src/module.vue +++ b/packages/acquisition-manager/src/module.vue @@ -1,18 +1,403 @@ diff --git a/packages/acquisition/src/index.ts b/packages/acquisition/src/index.ts index 432b71b..22dcf6a 100644 --- a/packages/acquisition/src/index.ts +++ b/packages/acquisition/src/index.ts @@ -1,5 +1,172 @@ -import { defineEndpoint } from '@directus/extensions-sdk'; +import "./shim"; +import { defineEndpoint } from "@directus/extensions-sdk"; +import { AcquisitionService, PdfEngine } from "@mintel/acquisition"; +import { render, SiteAuditTemplate, ProjectEstimateTemplate } from "@mintel/mail"; +import { createElement } from "react"; +import * as path from "path"; +import * as fs from "fs"; -export default defineEndpoint((router) => { - router.get('/ping', (req, res) => res.send('pong')); +export default defineEndpoint((router, { services, env }) => { + const { ItemsService, MailService } = services; + + router.get("/ping", (req, res) => res.send("pong")); + + router.post("/audit/:id", async (req: any, res: any) => { + const { id } = req.params; + const leadsService = new ItemsService("leads", { schema: req.schema, accountability: req.accountability }); + + try { + const lead = await leadsService.readOne(id); + if (!lead) return res.status(404).send({ error: "Lead not found" }); + + await leadsService.updateOne(id, { status: "auditing" }); + + const acqService = new AcquisitionService(env.OPENROUTER_API_KEY); + const result = await acqService.runFullSequence(lead.website_url, lead.briefing, lead.comments); + + await leadsService.updateOne(id, { + status: "audit_ready", + ai_state: result.state, + audit_context: JSON.stringify(result.usage), + }); + + res.send({ success: true, result }); + } catch (error: any) { + console.error("Audit failed:", error); + await leadsService.updateOne(id, { status: "new", comments: `Audit failed: ${error.message}` }); + res.status(500).send({ error: error.message }); + } + }); + + router.post("/audit-email/:id", async (req: any, res: any) => { + const { id } = req.params; + const leadsService = new ItemsService("leads", { schema: req.schema, accountability: req.accountability }); + const peopleService = new ItemsService("people", { schema: req.schema, accountability: req.accountability }); + const mailService = new MailService({ schema: req.schema, accountability: req.accountability }); + + try { + const lead = await leadsService.readOne(id); + if (!lead || !lead.ai_state) return res.status(400).send({ error: "Lead or Audit not ready" }); + + let recipientEmail = lead.contact_email; + let companyName = lead.company_name; + + if (lead.contact_person) { + const person = await peopleService.readOne(lead.contact_person); + if (person && person.email) { + recipientEmail = person.email; + companyName = person.company || lead.company_name; + } + } + + if (!recipientEmail) return res.status(400).send({ error: "No recipient email found" }); + + const auditHighlights = [ + `Projekt-Typ: ${lead.ai_state.projectType === "website" ? "Website" : "Web App"}`, + ...(lead.ai_state.sitemap || []).slice(0, 3).map((item: any) => `Potenzial in: ${item.category}`), + ]; + + const html = await render(createElement(SiteAuditTemplate, { + companyName: companyName, + websiteUrl: lead.website_url, + auditHighlights + })); + + await mailService.send({ + to: recipientEmail, + subject: `Analyse Ihrer Webpräsenz: ${companyName}`, + html + }); + + await leadsService.updateOne(id, { + status: "contacted", + last_contacted_at: new Date().toISOString(), + }); + + res.send({ success: true }); + } catch (error: any) { + console.error("Audit Email failed:", error); + res.status(500).send({ error: error.message }); + } + }); + + router.post("/estimate/:id", async (req: any, res: any) => { + const { id } = req.params; + const leadsService = new ItemsService("leads", { schema: req.schema, accountability: req.accountability }); + + try { + const lead = await leadsService.readOne(id); + if (!lead || !lead.ai_state) return res.status(400).send({ error: "Lead or AI state not found" }); + + const pdfEngine = new PdfEngine(); + const filename = `estimate_${id}_${Date.now()}.pdf`; + const storageRoot = env.STORAGE_LOCAL_ROOT || "./storage"; + const outputPath = path.join(storageRoot, filename); + + await pdfEngine.generateEstimatePdf(lead.ai_state, outputPath); + + await leadsService.updateOne(id, { + audit_pdf_path: filename, + }); + + res.send({ success: true, filename }); + } catch (error: any) { + console.error("PDF Generation failed:", error); + res.status(500).send({ error: error.message }); + } + }); + + router.post("/estimate-email/:id", async (req: any, res: any) => { + const { id } = req.params; + const leadsService = new ItemsService("leads", { schema: req.schema, accountability: req.accountability }); + const peopleService = new ItemsService("people", { schema: req.schema, accountability: req.accountability }); + const mailService = new MailService({ schema: req.schema, accountability: req.accountability }); + + try { + const lead = await leadsService.readOne(id); + if (!lead || !lead.audit_pdf_path) return res.status(400).send({ error: "PDF not generated" }); + + let recipientEmail = lead.contact_email; + let companyName = lead.company_name; + + if (lead.contact_person) { + const person = await peopleService.readOne(lead.contact_person); + if (person && person.email) { + recipientEmail = person.email; + companyName = person.company || lead.company_name; + } + } + + if (!recipientEmail) return res.status(400).send({ error: "No recipient email found" }); + + const html = await render(createElement(ProjectEstimateTemplate, { + companyName: companyName, + })); + + const storageRoot = env.STORAGE_LOCAL_ROOT || "./storage"; + const attachmentPath = path.join(storageRoot, lead.audit_pdf_path); + + await mailService.send({ + to: recipientEmail, + subject: `Ihre Projekt-Schätzung: ${companyName}`, + html, + attachments: [ + { + filename: `Angebot_${companyName}.pdf`, + content: fs.readFileSync(attachmentPath) + } + ] + }); + + await leadsService.updateOne(id, { + status: "contacted", + last_contacted_at: new Date().toISOString(), + }); + + res.send({ success: true }); + } catch (error: any) { + console.error("Estimate Email failed:", error); + res.status(500).send({ error: error.message }); + } + }); }); diff --git a/packages/acquisition/src/shim.ts b/packages/acquisition/src/shim.ts new file mode 100644 index 0000000..66079f7 --- /dev/null +++ b/packages/acquisition/src/shim.ts @@ -0,0 +1,22 @@ +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; +import { createRequire } from 'module'; + +try { + const url = import.meta?.url; + // Hardcode fallback path for Directus Docker environment + const fallbackPath = '/directus/extensions/acquisition/dist/index.js'; + const filename = url ? fileURLToPath(url) : fallbackPath; + const dir = dirname(filename); + + // @ts-ignore + globalThis.__filename = filename; + // @ts-ignore + globalThis.__dirname = dir; + // @ts-ignore + globalThis.require = createRequire(url || `file://${fallbackPath}`); + + console.log(`[Shim] Loaded. __dirname: ${dir}`); +} catch (e) { + console.warn("[Shim] Failed to shim __dirname/require", e); +} diff --git a/packages/cms-infra/database/data.db b/packages/cms-infra/database/data.db old mode 100644 new mode 100755 index 4c050a3..e536eaf Binary files a/packages/cms-infra/database/data.db and b/packages/cms-infra/database/data.db differ diff --git a/packages/cms-infra/extensions/acquisition-manager/index.js b/packages/cms-infra/extensions/acquisition-manager/index.js index 2eb5d80..533d6a0 100644 --- a/packages/cms-infra/extensions/acquisition-manager/index.js +++ b/packages/cms-infra/extensions/acquisition-manager/index.js @@ -1 +1 @@ -import{defineModule as e}from"@directus/extensions-sdk";import{defineComponent as t,resolveComponent as n,openBlock as a,createBlock as i,withCtx as r,createElementVNode as o}from"vue";var s=t({__name:"module",setup:e=>(e,t)=>{const s=n("private-view");return a(),i(s,{title:"Acquisition Manager"},{default:r(()=>[...t[0]||(t[0]=[o("div",{class:"acquisition-manager"},[o("h1",null,"Acquisition Manager"),o("p",null,"Modern Industrial Acquisition Management Interface")],-1)])]),_:1})}}),u=[],c=[];!function(e,t){if(e&&"undefined"!=typeof document){var n,a=!0===t.prepend?"prepend":"append",i=!0===t.singleTag,r="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(i){var o=u.indexOf(r);-1===o&&(o=u.push(r)-1,c[o]={}),n=c[o]&&c[o][a]?c[o][a]:c[o][a]=s()}else n=s();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function s(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var n=Object.keys(t.attributes),i=0;i{const n=e.__vccOpts||e;for(const[e,a]of t)n[e]=a;return n})(s,[["__scopeId","data-v-19f4e937"],["__file","module.vue"]])}]});export{d as default}; +import{useApi as e,defineModule as a}from"@directus/extensions-sdk";import{defineComponent as t,ref as l,computed as n,onMounted as i,resolveComponent as s,resolveDirective as o,openBlock as d,createBlock as r,withCtx as u,createVNode as c,createElementBlock as v,Fragment as p,renderList as m,createTextVNode as f,toDisplayString as g,createCommentVNode as y,createElementVNode as b,withDirectives as h}from"vue";var _=Object.defineProperty,x=Object.getOwnPropertySymbols,w=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable,V=(e,a,t)=>a in e?_(e,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[a]=t;const A={class:"content-wrapper"},C={key:0,class:"empty-state"},$={class:"header"},U={class:"header-left"},F={class:"title"},O={class:"subtitle"},P=["href"],E={class:"header-right"},S={class:"sections"},j={class:"main-info"},L={class:"form-grid"},z={class:"field"},q={key:1,class:"value text-subdued"},B={class:"field"},N={class:"value"},D={class:"field full"},M={class:"value text-block"},I={key:0,class:"ai-observations"},T={class:"metrics"},K={class:"page-title"},G={class:"page-url"},R={class:"drawer-content"},W={class:"form-section"},H={class:"field"},J={class:"field"},Q={class:"field"},X={class:"field"},Y={class:"field"},Z={class:"field"},ee={class:"drawer-actions"};var ae=t({__name:"module",setup(a){const t=e(),_=l([]),ae=l(null),te=l(!1),le=l(!1),ne=l(!1),ie=l(!1),se=l(!1),oe=l(null),de=l({company_name:"",website_url:"",contact_name:"",contact_email:"",contact_person:null,briefing:"",status:"new"}),re=l([]),ue=n(()=>re.value.map(e=>({text:`${e.first_name} ${e.last_name}`,value:e.id})));function ce(e){const a=re.value.find(a=>a.id===e);return a?`${a.first_name} ${a.last_name}`:e}const ve=n(()=>_.value.find(e=>e.id===ae.value));async function pe(){const[e,a]=await Promise.all([t.get("/items/leads",{params:{sort:"-date_created"}}),t.get("/items/people",{params:{sort:"last_name"}})]);_.value=e.data.data,re.value=a.data.data,!ae.value&&_.value.length>0&&(ae.value=_.value[0].id)}async function me(){if(ae.value){te.value=!0;try{await t.post(`/acquisition/audit/${ae.value}`),oe.value={type:"success",message:"Audit erfolgreich gestartet!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler beim Audit: ${e.message}`}}finally{te.value=!1}}}async function fe(){if(ae.value){ne.value=!0;try{await t.post(`/acquisition/audit-email/${ae.value}`),oe.value={type:"success",message:"Audit E-Mail versendet!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler beim Versenden: ${e.message}`}}finally{ne.value=!1}}}async function ge(){if(ae.value){le.value=!0;try{await t.post(`/acquisition/estimate/${ae.value}`),oe.value={type:"success",message:"Angebot (PDF) wurde generiert!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler bei PDF Generierung: ${e.message}`}}finally{le.value=!1}}}async function ye(){if(ae.value){ne.value=!0;try{await t.post(`/acquisition/estimate-email/${ae.value}`),oe.value={type:"success",message:"Angebot erfolgreich versendet!"},await pe()}catch(e){oe.value={type:"danger",message:`Fehler beim Versenden: ${e.message}`}}finally{ne.value=!1}}}function be(){var e;(null==(e=ve.value)?void 0:e.audit_pdf_path)&&window.open(`${window.location.origin}/assets/${ve.value.audit_pdf_path}`,"_blank")}async function he(){if(de.value.company_name){se.value=!0;try{const e=((e,a)=>{for(var t in a||(a={}))w.call(a,t)&&V(e,t,a[t]);if(x)for(var t of x(a))k.call(a,t)&&V(e,t,a[t]);return e})({id:crypto.randomUUID()},de.value);await t.post("/items/leads",e),oe.value={type:"success",message:"Lead erfolgreich registriert!"},ie.value=!1,await pe(),ae.value=e.id,de.value={company_name:"",website_url:"",contact_name:"",contact_email:"",contact_person:null,briefing:"",status:"new"}}catch(e){oe.value={type:"danger",message:`Fehler beim Speichern: ${e.message}`}}finally{se.value=!1}}}function _e(e){switch(e){case"new":return"fiber_new";case"auditing":return"hourglass_empty";case"audit_ready":return"check_circle";case"contacted":return"mail_outline";default:return"help_outline"}}function xe(e){switch(e){case"new":return"var(--theme--primary)";case"auditing":return"var(--theme--warning)";case"audit_ready":return"var(--theme--success)";case"contacted":return"var(--theme--secondary)";default:return"var(--theme--foreground-subdued)"}}return i(pe),(e,a)=>{const t=s("v-icon"),l=s("v-list-item-icon"),n=s("v-text-overflow"),i=s("v-list-item-content"),x=s("v-list-item"),w=s("v-divider"),k=s("v-list"),V=s("v-notice"),re=s("v-button"),pe=s("v-info"),we=s("v-table"),ke=s("v-input"),Ve=s("v-textarea"),Ae=s("v-select"),Ce=s("v-drawer"),$e=s("private-view"),Ue=o("tooltip");return d(),r($e,{title:"Acquisition Manager"},{navigation:u(()=>[c(k,{nav:""},{default:u(()=>[c(x,{onClick:a[0]||(a[0]=e=>ie.value=!0),clickable:""},{default:u(()=>[c(l,null,{default:u(()=>[c(t,{name:"add",color:"var(--theme--primary)"})]),_:1}),c(i,null,{default:u(()=>[c(n,{text:"Neuen Lead anlegen"})]),_:1})]),_:1}),c(w),(d(!0),v(p,null,m(_.value,e=>(d(),r(x,{key:e.id,active:ae.value===e.id,class:"lead-item",clickable:"",onClick:a=>{return t=e.id,void(ae.value=t);var t}},{default:u(()=>[c(l,null,{default:u(()=>[c(t,{name:_e(e.status),color:xe(e.status)},null,8,["name","color"])]),_:2},1024),c(i,null,{default:u(()=>[c(n,{text:e.company_name},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","onClick"]))),128))]),_:1})]),"title-outer:after":u(()=>[oe.value?(d(),r(V,{key:0,type:oe.value.type,onClose:a[1]||(a[1]=e=>oe.value=null),dismissible:""},{default:u(()=>[f(g(oe.value.message),1)]),_:1},8,["type"])):y("v-if",!0)]),default:u(()=>{var e;return[b("div",A,[c(V,{type:"success",style:{"margin-bottom":"16px"}},{default:u(()=>[f(" DEBUG: Module Version 1.1.0 - Native Build - "+g((new Date).toISOString()),1)]),_:1}),ve.value?(d(),v(p,{key:1},[b("header",$,[b("div",U,[b("h1",F,g(ve.value.company_name),1),b("p",O,[c(t,{name:"language","x-small":""}),b("a",{href:ve.value.website_url,target:"_blank",class:"url-link"},g(ve.value.website_url.replace(/^https?:\/\//,"")),9,P),f(" · Status: "+g(ve.value.status.toUpperCase()),1)])]),b("div",E,["new"===ve.value.status?(d(),r(re,{key:0,secondary:"",loading:te.value,onClick:me},{default:u(()=>[c(t,{name:"settings_suggest",left:""}),a[15]||(a[15]=f(" Audit starten ",-1))]),_:1},8,["loading"])):y("v-if",!0),"audit_ready"===ve.value.status?(d(),v(p,{key:1},[c(re,{secondary:"",loading:ne.value,onClick:fe},{default:u(()=>[c(t,{name:"mail",left:""}),a[16]||(a[16]=f(" Audit E-Mail ",-1))]),_:1},8,["loading"]),c(re,{loading:le.value,onClick:ge},{default:u(()=>[c(t,{name:"picture_as_pdf",left:""}),a[17]||(a[17]=f(" PDF Erstellen ",-1))]),_:1},8,["loading"])],64)):y("v-if",!0),ve.value.audit_pdf_path?h((d(),r(re,{key:2,secondary:"",icon:"",onClick:be},{default:u(()=>[c(t,{name:"open_in_new"})]),_:1})),[[Ue,"PDF öffnen",void 0,{bottom:!0}]]):y("v-if",!0),ve.value.audit_pdf_path?(d(),r(re,{key:3,primary:"",loading:ne.value,onClick:ye},{default:u(()=>[c(t,{name:"send",left:""}),a[18]||(a[18]=f(" Angebot senden ",-1))]),_:1},8,["loading"])):y("v-if",!0)])]),b("div",S,[b("div",j,[b("div",L,[b("div",z,[a[19]||(a[19]=b("span",{class:"label"},"Kontaktperson",-1)),ve.value.contact_person?(d(),v("div",{key:0,class:"value person-link",onClick:a[3]||(a[3]=e=>{return a=ve.value.contact_person,void(oe.value={type:"info",message:`Navigiere zu Person: ${a}`});var a})},g(ce(ve.value.contact_person)),1)):(d(),v("div",q,"Keine Person verknüpft"))]),b("div",B,[a[20]||(a[20]=b("span",{class:"label"},"E-Mail (Legacy)",-1)),b("div",N,g(ve.value.contact_email||"—"),1)]),b("div",D,[a[21]||(a[21]=b("span",{class:"label"},"Briefing / Fokus",-1)),b("div",M,g(ve.value.briefing||"Kein Briefing hinterlegt."),1)])])]),c(w),ve.value.ai_state?(d(),v("div",I,[a[22]||(a[22]=b("h3",{class:"section-title"},"AI Observations & Estimation",-1)),b("div",T,[c(pe,{label:"Projekt-Modus",value:ve.value.ai_state.projectType||"Unbekannt"},null,8,["value"]),c(pe,{label:"Seitenanzahl",value:(null==(e=ve.value.ai_state.sitemap)?void 0:e.length)||"0"},null,8,["value"])]),ve.value.ai_state.sitemap?(d(),r(we,{key:0,headers:[{text:"Seite",value:"title"},{text:"URL",value:"url"}],items:ve.value.ai_state.sitemap,class:"observation-table"},{"item.title":u(({item:e})=>[b("span",K,g(e.title),1)]),"item.url":u(({item:e})=>[b("span",G,g(e.url),1)]),_:2},1032,["items"])):y("v-if",!0)])):y("v-if",!0)])],64)):(d(),v("div",C,[c(pe,{title:"Lead auswählen",icon:"auto_awesome",center:""},{default:u(()=>[a[13]||(a[13]=f(" Wähle einen Lead in der Navigation aus oder ",-1)),c(re,{"x-small":"",onClick:a[2]||(a[2]=e=>ie.value=!0)},{default:u(()=>[...a[12]||(a[12]=[f("registriere einen neuen Lead",-1)])]),_:1}),a[14]||(a[14]=f(". ",-1))]),_:1})]))]),c(Ce,{modelValue:ie.value,"onUpdate:modelValue":a[10]||(a[10]=e=>ie.value=e),title:"Neuen Lead registrieren",icon:"person_add",onCancel:a[11]||(a[11]=e=>ie.value=!1)},{default:u(()=>[b("div",R,[b("div",W,[b("div",H,[a[23]||(a[23]=b("span",{class:"label"},"Firma",-1)),c(ke,{modelValue:de.value.company_name,"onUpdate:modelValue":a[4]||(a[4]=e=>de.value.company_name=e),placeholder:"z.B. Schmidt GmbH",autofocus:""},null,8,["modelValue"])]),b("div",J,[a[24]||(a[24]=b("span",{class:"label"},"Website URL",-1)),c(ke,{modelValue:de.value.website_url,"onUpdate:modelValue":a[5]||(a[5]=e=>de.value.website_url=e),placeholder:"https://..."},null,8,["modelValue"])]),b("div",Q,[a[25]||(a[25]=b("span",{class:"label"},"Ansprechpartner",-1)),c(ke,{modelValue:de.value.contact_name,"onUpdate:modelValue":a[6]||(a[6]=e=>de.value.contact_name=e),placeholder:"Vorname Nachname"},null,8,["modelValue"])]),b("div",X,[a[26]||(a[26]=b("span",{class:"label"},"E-Mail Adresse",-1)),c(ke,{modelValue:de.value.contact_email,"onUpdate:modelValue":a[7]||(a[7]=e=>de.value.contact_email=e),placeholder:"email@beispiel.de",type:"email"},null,8,["modelValue"])]),b("div",Y,[a[27]||(a[27]=b("span",{class:"label"},"Briefing / Fokus",-1)),c(Ve,{modelValue:de.value.briefing,"onUpdate:modelValue":a[8]||(a[8]=e=>de.value.briefing=e),placeholder:"Besonderheiten für das Audit..."},null,8,["modelValue"])]),b("div",Z,[a[28]||(a[28]=b("span",{class:"label"},"Kontaktperson (Optional)",-1)),c(Ae,{modelValue:de.value.contact_person,"onUpdate:modelValue":a[9]||(a[9]=e=>de.value.contact_person=e),items:ue.value,placeholder:"Person auswählen..."},null,8,["modelValue","items"])])]),b("div",ee,[c(re,{primary:"",block:"",loading:se.value,onClick:he},{default:u(()=>[...a[29]||(a[29]=[f("Lead speichern",-1)])]),_:1},8,["loading"])])])]),_:1},8,["modelValue"])]}),_:1})}}}),te=[],le=[];!function(e,a){if(e&&"undefined"!=typeof document){var t,l=!0===a.prepend?"prepend":"append",n=!0===a.singleTag,i="string"==typeof a.container?document.querySelector(a.container):document.getElementsByTagName("head")[0];if(n){var s=te.indexOf(i);-1===s&&(s=te.push(i)-1,le[s]={}),t=le[s]&&le[s][l]?le[s][l]:le[s][l]=o()}else t=o();65279===e.charCodeAt(0)&&(e=e.substring(1)),t.styleSheet?t.styleSheet.cssText+=e:t.appendChild(document.createTextNode(e))}function o(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),a.attributes)for(var t=Object.keys(a.attributes),n=0;n{const t=e.__vccOpts||e;for(const[e,l]of a)t[e]=l;return t})(ae,[["__scopeId","data-v-6a55edd7"],["__file","module.vue"]]),ie=a({id:"acquisition-manager",name:"Acquisition",icon:"auto_awesome",routes:[{path:"",component:ne},{path:":id",component:ne,props:!0}]});export{ie as default}; diff --git a/packages/cms-infra/extensions/acquisition-manager/package.json b/packages/cms-infra/extensions/acquisition-manager/package.json index eeed01b..14990bd 100644 --- a/packages/cms-infra/extensions/acquisition-manager/package.json +++ b/packages/cms-infra/extensions/acquisition-manager/package.json @@ -2,7 +2,7 @@ "name": "acquisition-manager", "description": "Custom High-Fidelity Acquisition Management for Directus", "icon": "account_balance_wallet", - "version": "1.0.0", + "version": "1.7.12", "type": "module", "keywords": [ "directus", diff --git a/packages/cms-infra/extensions/acquisition/package.json b/packages/cms-infra/extensions/acquisition/package.json index 5c9bcc1..92330d0 100644 --- a/packages/cms-infra/extensions/acquisition/package.json +++ b/packages/cms-infra/extensions/acquisition/package.json @@ -1,25 +1,25 @@ { - "name": "acquisition", - "version": "1.0.0", - "type": "module", - "directus:extension": { - "type": "endpoint", - "path": "index.js", - "source": "src/index.ts", - "host": "^11.0.0" - }, - "scripts": { - "build": "node build.js", - "dev": "node build.js --watch" - }, - "devDependencies": { - "@directus/extensions-sdk": "11.0.2", - "esbuild": "^0.25.0", - "typescript": "^5.6.3" - }, - "dependencies": { - "jquery": "^3.7.1", - "react": "^19.2.4", - "react-dom": "^19.2.4" - } -} \ No newline at end of file + "name": "acquisition", + "version": "1.7.12", + "type": "module", + "directus:extension": { + "type": "endpoint", + "path": "index.js", + "source": "src/index.ts", + "host": "^11.0.0" + }, + "scripts": { + "build": "node build.js", + "dev": "node build.js --watch" + }, + "devDependencies": { + "@directus/extensions-sdk": "11.0.2", + "esbuild": "^0.25.0", + "typescript": "^5.6.3" + }, + "dependencies": { + "jquery": "^3.7.1", + "react": "^19.2.4", + "react-dom": "^19.2.4" + } +} diff --git a/packages/cms-infra/extensions/customer-manager/package.json b/packages/cms-infra/extensions/customer-manager/package.json index ef1404f..426752b 100644 --- a/packages/cms-infra/extensions/customer-manager/package.json +++ b/packages/cms-infra/extensions/customer-manager/package.json @@ -2,7 +2,7 @@ "name": "customer-manager", "description": "Custom High-Fidelity Customer & Company Management for Directus", "icon": "supervisor_account", - "version": "1.7.3", + "version": "1.7.12", "type": "module", "keywords": [ "directus", @@ -27,4 +27,4 @@ "@directus/extensions-sdk": "11.0.2", "vue": "^3.4.0" } -} \ No newline at end of file +} diff --git a/packages/cms-infra/extensions/feedback-commander/package.json b/packages/cms-infra/extensions/feedback-commander/package.json index 1d99342..a0e6798 100644 --- a/packages/cms-infra/extensions/feedback-commander/package.json +++ b/packages/cms-infra/extensions/feedback-commander/package.json @@ -2,7 +2,7 @@ "name": "feedback-commander", "description": "Custom High-Fidelity Feedback Management Extension for Directus", "icon": "view_kanban", - "version": "1.7.3", + "version": "1.7.12", "type": "module", "keywords": [ "directus", diff --git a/packages/cms-infra/extensions/people-manager/index.js b/packages/cms-infra/extensions/people-manager/index.js index ebb3194..7b71123 100644 --- a/packages/cms-infra/extensions/people-manager/index.js +++ b/packages/cms-infra/extensions/people-manager/index.js @@ -1 +1 @@ -import{defineModule as e}from"@directus/extensions-sdk";import{defineComponent as t,resolveComponent as n,openBlock as a,createBlock as r,withCtx as o,createElementVNode as p}from"vue";var s=t({__name:"module",setup:e=>(e,t)=>{const s=n("private-view");return a(),r(s,{title:"People Manager"},{default:o(()=>[...t[0]||(t[0]=[p("div",{class:"people-manager"},[p("h1",null,"People Manager"),p("p",null,"Modern Industrial People Management Interface")],-1)])]),_:1})}}),d=[],i=[];!function(e,t){if(e&&"undefined"!=typeof document){var n,a=!0===t.prepend?"prepend":"append",r=!0===t.singleTag,o="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(r){var p=d.indexOf(o);-1===p&&(p=d.push(o)-1,i[p]={}),n=i[p]&&i[p][a]?i[p][a]:i[p][a]=s()}else n=s();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function s(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var n=Object.keys(t.attributes),r=0;r{const n=e.__vccOpts||e;for(const[e,a]of t)n[e]=a;return n})(s,[["__scopeId","data-v-da2952f8"],["__file","module.vue"]])}]});export{u as default}; +import{useApi as e,defineModule as a}from"@directus/extensions-sdk";import{defineComponent as t,ref as l,onMounted as n,resolveComponent as i,resolveDirective as s,openBlock as d,createBlock as o,withCtx as r,createVNode as u,createElementBlock as c,Fragment as p,renderList as v,createElementVNode as m,createTextVNode as f,toDisplayString as b,createCommentVNode as g,withDirectives as y}from"vue";var h=Object.defineProperty,x=Object.getOwnPropertySymbols,_=Object.prototype.hasOwnProperty,w=Object.prototype.propertyIsEnumerable,V=(e,a,t)=>a in e?h(e,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[a]=t;const k={class:"content-wrapper"},P={key:1,class:"empty-state"},C={key:2},O={class:"header"},j={class:"header-left"},N={class:"title"},E={class:"subtitle"},T={class:"header-right"},U={class:"details-grid"},z={class:"detail-item"},M={class:"value"},S={class:"detail-item"},A={class:"value"},$={class:"drawer-content"},B={class:"form-section"},F={class:"field"},I={class:"field"},q={class:"field"},K={class:"field"},W={class:"field"},D={class:"drawer-actions"};var G=t({__name:"module",setup(a){const t=e(),h=l([]),G=l(null),H=l(null),J=l(!1),L=l(!1),Q=l(!1),R=l({id:null,first_name:"",last_name:"",email:"",company:"",phone:""});async function X(){try{const e=await t.get("/items/people",{params:{sort:"last_name"}});h.ref=e.data.data}catch(e){console.error("Failed to fetch people:",e)}}function Y(){Q.value=!1,R.value={id:null,first_name:"",last_name:"",email:"",company:"",phone:""},L.value=!0}function Z(){Q.value=!0,R.value=((e,a)=>{for(var t in a||(a={}))_.call(a,t)&&V(e,t,a[t]);if(x)for(var t of x(a))w.call(a,t)&&V(e,t,a[t]);return e})({},G.value),L.value=!0}async function ee(){if(R.value.first_name&&R.value.last_name){J.value=!0;try{Q.value?(await t.patch(`/items/people/${R.value.id}`,R.value),H.value={type:"success",message:"Person aktualisiert!"}):(await t.post("/items/people",R.value),H.value={type:"success",message:"Person angelegt!"}),L.value=!1,await X(),Q.value&&(G.value=R.value)}catch(e){H.value={type:"danger",message:e.message}}finally{J.value=!1}}else H.value={type:"danger",message:"Vor- und Nachname sind erforderlich."}}async function ae(){if(confirm("Soll diese Person wirklich gelöscht werden?"))try{await t.delete(`/items/people/${G.value.id}`),H.value={type:"success",message:"Person gelöscht."},G.value=null,await X()}catch(e){H.value={type:"danger",message:e.message}}}return n(X),(e,a)=>{const t=i("v-icon"),l=i("v-list-item-icon"),n=i("v-text-overflow"),x=i("v-list-item-content"),_=i("v-list-item"),w=i("v-divider"),V=i("v-list"),X=i("v-notice"),te=i("v-button"),le=i("v-info"),ne=i("v-input"),ie=i("v-drawer"),se=i("private-view"),de=s("tooltip");return d(),o(se,{title:"People Manager"},{navigation:r(()=>[u(V,{nav:""},{default:r(()=>[u(_,{onClick:Y,clickable:""},{default:r(()=>[u(l,null,{default:r(()=>[u(t,{name:"add",color:"var(--theme--primary)"})]),_:1}),u(x,null,{default:r(()=>[u(n,{text:"Neue Person anlegen"})]),_:1})]),_:1}),u(w),(d(!0),c(p,null,v(h.value,e=>{var a;return d(),o(_,{key:e.id,active:(null==(a=G.value)?void 0:a.id)===e.id,class:"person-item",clickable:"",onClick:a=>function(e){G.value=e}(e)},{default:r(()=>[u(l,null,{default:r(()=>[u(t,{name:"person"})]),_:1}),u(x,null,{default:r(()=>[u(n,{text:`${e.first_name} ${e.last_name}`},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","onClick"])}),128))]),_:1})]),default:r(()=>[m("div",k,[H.value?(d(),o(X,{key:0,type:H.value.type,onClose:a[0]||(a[0]=e=>H.value=null),dismissible:""},{default:r(()=>[f(b(H.value.message),1)]),_:1},8,["type"])):g("v-if",!0),G.value?(d(),c("div",C,[m("header",O,[m("div",j,[m("h1",N,b(G.value.first_name)+" "+b(G.value.last_name),1),m("p",E,b(G.value.email||"Keine E-Mail angegeben"),1)]),m("div",T,[y((d(),o(te,{secondary:"",rounded:"",icon:"",onClick:Z},{default:r(()=>[u(t,{name:"edit"})]),_:1})),[[de,"Person bearbeiten"]]),y((d(),o(te,{danger:"",rounded:"",icon:"",onClick:ae},{default:r(()=>[u(t,{name:"delete"})]),_:1})),[[de,"Person löschen"]])])]),u(w),m("div",U,[m("div",z,[a[11]||(a[11]=m("span",{class:"label"},"Organisation",-1)),m("p",M,b(G.value.company||"---"),1)]),m("div",S,[a[12]||(a[12]=m("span",{class:"label"},"Telefon",-1)),m("p",A,b(G.value.phone||"---"),1)])])])):(d(),c("div",P,[u(le,{title:"Person auswählen",icon:"person",center:""},{default:r(()=>[a[9]||(a[9]=f(" Wähle eine Person in der Navigation aus oder ",-1)),u(te,{"x-small":"",onClick:Y},{default:r(()=>[...a[8]||(a[8]=[f("erstelle eine neue Person",-1)])]),_:1}),a[10]||(a[10]=f(". ",-1))]),_:1})]))]),u(ie,{modelValue:L.value,"onUpdate:modelValue":a[6]||(a[6]=e=>L.value=e),title:Q.value?"Person bearbeiten":"Neue Person anlegen",icon:"person",onCancel:a[7]||(a[7]=e=>L.value=!1)},{default:r(()=>[m("div",$,[m("div",B,[m("div",F,[a[13]||(a[13]=m("span",{class:"label"},"Vorname",-1)),u(ne,{modelValue:R.value.first_name,"onUpdate:modelValue":a[1]||(a[1]=e=>R.value.first_name=e),placeholder:"Vorname",autofocus:""},null,8,["modelValue"])]),m("div",I,[a[14]||(a[14]=m("span",{class:"label"},"Nachname",-1)),u(ne,{modelValue:R.value.last_name,"onUpdate:modelValue":a[2]||(a[2]=e=>R.value.last_name=e),placeholder:"Nachname"},null,8,["modelValue"])]),m("div",q,[a[15]||(a[15]=m("span",{class:"label"},"E-Mail",-1)),u(ne,{modelValue:R.value.email,"onUpdate:modelValue":a[3]||(a[3]=e=>R.value.email=e),placeholder:"email@beispiel.de",type:"email"},null,8,["modelValue"])]),m("div",K,[a[16]||(a[16]=m("span",{class:"label"},"Organisation / Firma",-1)),u(ne,{modelValue:R.value.company,"onUpdate:modelValue":a[4]||(a[4]=e=>R.value.company=e),placeholder:"z.B. Mintel"},null,8,["modelValue"])]),m("div",W,[a[17]||(a[17]=m("span",{class:"label"},"Telefon",-1)),u(ne,{modelValue:R.value.phone,"onUpdate:modelValue":a[5]||(a[5]=e=>R.value.phone=e),placeholder:"+49 ..."},null,8,["modelValue"])])]),m("div",D,[u(te,{primary:"",block:"",loading:J.value,onClick:ee},{default:r(()=>[...a[18]||(a[18]=[f(" Person speichern ",-1)])]),_:1},8,["loading"])])])]),_:1},8,["modelValue","title"])]),_:1})}}}),H=[],J=[];!function(e,a){if(e&&"undefined"!=typeof document){var t,l=!0===a.prepend?"prepend":"append",n=!0===a.singleTag,i="string"==typeof a.container?document.querySelector(a.container):document.getElementsByTagName("head")[0];if(n){var s=H.indexOf(i);-1===s&&(s=H.push(i)-1,J[s]={}),t=J[s]&&J[s][l]?J[s][l]:J[s][l]=d()}else t=d();65279===e.charCodeAt(0)&&(e=e.substring(1)),t.styleSheet?t.styleSheet.cssText+=e:t.appendChild(document.createTextNode(e))}function d(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),a.attributes)for(var t=Object.keys(a.attributes),n=0;n{const t=e.__vccOpts||e;for(const[e,l]of a)t[e]=l;return t})(G,[["__scopeId","data-v-bd30dab7"],["__file","module.vue"]])}]});export{L as default}; diff --git a/packages/cms-infra/extensions/people-manager/package.json b/packages/cms-infra/extensions/people-manager/package.json index 8c0ba73..8a02f79 100644 --- a/packages/cms-infra/extensions/people-manager/package.json +++ b/packages/cms-infra/extensions/people-manager/package.json @@ -1,30 +1,30 @@ { - "name": "people-manager", - "description": "Custom High-Fidelity People Management for Directus", - "icon": "person", - "version": "1.0.0", + "name": "people-manager", + "description": "Custom High-Fidelity People Management for Directus", + "icon": "person", + "version": "1.7.12", + "type": "module", + "keywords": [ + "directus", + "directus-extension", + "directus-extension-module" + ], + "files": [ + "dist" + ], + "directus:extension": { "type": "module", - "keywords": [ - "directus", - "directus-extension", - "directus-extension-module" - ], - "files": [ - "dist" - ], - "directus:extension": { - "type": "module", - "path": "index.js", - "source": "src/index.ts", - "host": "*", - "name": "People Manager" - }, - "scripts": { - "build": "directus-extension build && (cp -f dist/index.js index.js 2>/dev/null || true)", - "dev": "directus-extension build -w" - }, - "devDependencies": { - "@directus/extensions-sdk": "11.0.2", - "vue": "^3.4.0" - } -} \ No newline at end of file + "path": "index.js", + "source": "src/index.ts", + "host": "*", + "name": "People Manager" + }, + "scripts": { + "build": "directus-extension build && (cp -f dist/index.js index.js 2>/dev/null || true)", + "dev": "directus-extension build -w" + }, + "devDependencies": { + "@directus/extensions-sdk": "11.0.2", + "vue": "^3.4.0" + } +} diff --git a/packages/people-manager/index.js b/packages/people-manager/index.js index ebb3194..7b71123 100644 --- a/packages/people-manager/index.js +++ b/packages/people-manager/index.js @@ -1 +1 @@ -import{defineModule as e}from"@directus/extensions-sdk";import{defineComponent as t,resolveComponent as n,openBlock as a,createBlock as r,withCtx as o,createElementVNode as p}from"vue";var s=t({__name:"module",setup:e=>(e,t)=>{const s=n("private-view");return a(),r(s,{title:"People Manager"},{default:o(()=>[...t[0]||(t[0]=[p("div",{class:"people-manager"},[p("h1",null,"People Manager"),p("p",null,"Modern Industrial People Management Interface")],-1)])]),_:1})}}),d=[],i=[];!function(e,t){if(e&&"undefined"!=typeof document){var n,a=!0===t.prepend?"prepend":"append",r=!0===t.singleTag,o="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(r){var p=d.indexOf(o);-1===p&&(p=d.push(o)-1,i[p]={}),n=i[p]&&i[p][a]?i[p][a]:i[p][a]=s()}else n=s();65279===e.charCodeAt(0)&&(e=e.substring(1)),n.styleSheet?n.styleSheet.cssText+=e:n.appendChild(document.createTextNode(e))}function s(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var n=Object.keys(t.attributes),r=0;r{const n=e.__vccOpts||e;for(const[e,a]of t)n[e]=a;return n})(s,[["__scopeId","data-v-da2952f8"],["__file","module.vue"]])}]});export{u as default}; +import{useApi as e,defineModule as a}from"@directus/extensions-sdk";import{defineComponent as t,ref as l,onMounted as n,resolveComponent as i,resolveDirective as s,openBlock as d,createBlock as o,withCtx as r,createVNode as u,createElementBlock as c,Fragment as p,renderList as v,createElementVNode as m,createTextVNode as f,toDisplayString as b,createCommentVNode as g,withDirectives as y}from"vue";var h=Object.defineProperty,x=Object.getOwnPropertySymbols,_=Object.prototype.hasOwnProperty,w=Object.prototype.propertyIsEnumerable,V=(e,a,t)=>a in e?h(e,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[a]=t;const k={class:"content-wrapper"},P={key:1,class:"empty-state"},C={key:2},O={class:"header"},j={class:"header-left"},N={class:"title"},E={class:"subtitle"},T={class:"header-right"},U={class:"details-grid"},z={class:"detail-item"},M={class:"value"},S={class:"detail-item"},A={class:"value"},$={class:"drawer-content"},B={class:"form-section"},F={class:"field"},I={class:"field"},q={class:"field"},K={class:"field"},W={class:"field"},D={class:"drawer-actions"};var G=t({__name:"module",setup(a){const t=e(),h=l([]),G=l(null),H=l(null),J=l(!1),L=l(!1),Q=l(!1),R=l({id:null,first_name:"",last_name:"",email:"",company:"",phone:""});async function X(){try{const e=await t.get("/items/people",{params:{sort:"last_name"}});h.ref=e.data.data}catch(e){console.error("Failed to fetch people:",e)}}function Y(){Q.value=!1,R.value={id:null,first_name:"",last_name:"",email:"",company:"",phone:""},L.value=!0}function Z(){Q.value=!0,R.value=((e,a)=>{for(var t in a||(a={}))_.call(a,t)&&V(e,t,a[t]);if(x)for(var t of x(a))w.call(a,t)&&V(e,t,a[t]);return e})({},G.value),L.value=!0}async function ee(){if(R.value.first_name&&R.value.last_name){J.value=!0;try{Q.value?(await t.patch(`/items/people/${R.value.id}`,R.value),H.value={type:"success",message:"Person aktualisiert!"}):(await t.post("/items/people",R.value),H.value={type:"success",message:"Person angelegt!"}),L.value=!1,await X(),Q.value&&(G.value=R.value)}catch(e){H.value={type:"danger",message:e.message}}finally{J.value=!1}}else H.value={type:"danger",message:"Vor- und Nachname sind erforderlich."}}async function ae(){if(confirm("Soll diese Person wirklich gelöscht werden?"))try{await t.delete(`/items/people/${G.value.id}`),H.value={type:"success",message:"Person gelöscht."},G.value=null,await X()}catch(e){H.value={type:"danger",message:e.message}}}return n(X),(e,a)=>{const t=i("v-icon"),l=i("v-list-item-icon"),n=i("v-text-overflow"),x=i("v-list-item-content"),_=i("v-list-item"),w=i("v-divider"),V=i("v-list"),X=i("v-notice"),te=i("v-button"),le=i("v-info"),ne=i("v-input"),ie=i("v-drawer"),se=i("private-view"),de=s("tooltip");return d(),o(se,{title:"People Manager"},{navigation:r(()=>[u(V,{nav:""},{default:r(()=>[u(_,{onClick:Y,clickable:""},{default:r(()=>[u(l,null,{default:r(()=>[u(t,{name:"add",color:"var(--theme--primary)"})]),_:1}),u(x,null,{default:r(()=>[u(n,{text:"Neue Person anlegen"})]),_:1})]),_:1}),u(w),(d(!0),c(p,null,v(h.value,e=>{var a;return d(),o(_,{key:e.id,active:(null==(a=G.value)?void 0:a.id)===e.id,class:"person-item",clickable:"",onClick:a=>function(e){G.value=e}(e)},{default:r(()=>[u(l,null,{default:r(()=>[u(t,{name:"person"})]),_:1}),u(x,null,{default:r(()=>[u(n,{text:`${e.first_name} ${e.last_name}`},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","onClick"])}),128))]),_:1})]),default:r(()=>[m("div",k,[H.value?(d(),o(X,{key:0,type:H.value.type,onClose:a[0]||(a[0]=e=>H.value=null),dismissible:""},{default:r(()=>[f(b(H.value.message),1)]),_:1},8,["type"])):g("v-if",!0),G.value?(d(),c("div",C,[m("header",O,[m("div",j,[m("h1",N,b(G.value.first_name)+" "+b(G.value.last_name),1),m("p",E,b(G.value.email||"Keine E-Mail angegeben"),1)]),m("div",T,[y((d(),o(te,{secondary:"",rounded:"",icon:"",onClick:Z},{default:r(()=>[u(t,{name:"edit"})]),_:1})),[[de,"Person bearbeiten"]]),y((d(),o(te,{danger:"",rounded:"",icon:"",onClick:ae},{default:r(()=>[u(t,{name:"delete"})]),_:1})),[[de,"Person löschen"]])])]),u(w),m("div",U,[m("div",z,[a[11]||(a[11]=m("span",{class:"label"},"Organisation",-1)),m("p",M,b(G.value.company||"---"),1)]),m("div",S,[a[12]||(a[12]=m("span",{class:"label"},"Telefon",-1)),m("p",A,b(G.value.phone||"---"),1)])])])):(d(),c("div",P,[u(le,{title:"Person auswählen",icon:"person",center:""},{default:r(()=>[a[9]||(a[9]=f(" Wähle eine Person in der Navigation aus oder ",-1)),u(te,{"x-small":"",onClick:Y},{default:r(()=>[...a[8]||(a[8]=[f("erstelle eine neue Person",-1)])]),_:1}),a[10]||(a[10]=f(". ",-1))]),_:1})]))]),u(ie,{modelValue:L.value,"onUpdate:modelValue":a[6]||(a[6]=e=>L.value=e),title:Q.value?"Person bearbeiten":"Neue Person anlegen",icon:"person",onCancel:a[7]||(a[7]=e=>L.value=!1)},{default:r(()=>[m("div",$,[m("div",B,[m("div",F,[a[13]||(a[13]=m("span",{class:"label"},"Vorname",-1)),u(ne,{modelValue:R.value.first_name,"onUpdate:modelValue":a[1]||(a[1]=e=>R.value.first_name=e),placeholder:"Vorname",autofocus:""},null,8,["modelValue"])]),m("div",I,[a[14]||(a[14]=m("span",{class:"label"},"Nachname",-1)),u(ne,{modelValue:R.value.last_name,"onUpdate:modelValue":a[2]||(a[2]=e=>R.value.last_name=e),placeholder:"Nachname"},null,8,["modelValue"])]),m("div",q,[a[15]||(a[15]=m("span",{class:"label"},"E-Mail",-1)),u(ne,{modelValue:R.value.email,"onUpdate:modelValue":a[3]||(a[3]=e=>R.value.email=e),placeholder:"email@beispiel.de",type:"email"},null,8,["modelValue"])]),m("div",K,[a[16]||(a[16]=m("span",{class:"label"},"Organisation / Firma",-1)),u(ne,{modelValue:R.value.company,"onUpdate:modelValue":a[4]||(a[4]=e=>R.value.company=e),placeholder:"z.B. Mintel"},null,8,["modelValue"])]),m("div",W,[a[17]||(a[17]=m("span",{class:"label"},"Telefon",-1)),u(ne,{modelValue:R.value.phone,"onUpdate:modelValue":a[5]||(a[5]=e=>R.value.phone=e),placeholder:"+49 ..."},null,8,["modelValue"])])]),m("div",D,[u(te,{primary:"",block:"",loading:J.value,onClick:ee},{default:r(()=>[...a[18]||(a[18]=[f(" Person speichern ",-1)])]),_:1},8,["loading"])])])]),_:1},8,["modelValue","title"])]),_:1})}}}),H=[],J=[];!function(e,a){if(e&&"undefined"!=typeof document){var t,l=!0===a.prepend?"prepend":"append",n=!0===a.singleTag,i="string"==typeof a.container?document.querySelector(a.container):document.getElementsByTagName("head")[0];if(n){var s=H.indexOf(i);-1===s&&(s=H.push(i)-1,J[s]={}),t=J[s]&&J[s][l]?J[s][l]:J[s][l]=d()}else t=d();65279===e.charCodeAt(0)&&(e=e.substring(1)),t.styleSheet?t.styleSheet.cssText+=e:t.appendChild(document.createTextNode(e))}function d(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),a.attributes)for(var t=Object.keys(a.attributes),n=0;n{const t=e.__vccOpts||e;for(const[e,l]of a)t[e]=l;return t})(G,[["__scopeId","data-v-bd30dab7"],["__file","module.vue"]])}]});export{L as default}; diff --git a/packages/people-manager/src/module.vue b/packages/people-manager/src/module.vue index 8275bc0..0aff9ce 100644 --- a/packages/people-manager/src/module.vue +++ b/packages/people-manager/src/module.vue @@ -1,18 +1,296 @@