1import{z as xt,H as it,j as e,aZ as It,ap as Ft,l as qs,X as Mt,a_ as ss,a9 as Xe,a7 as q,b as Wt,m as St,S as Yt,aM as Us,a0 as Tt,M as Gs,al as Ks,a$ as Xt,k as Ct,U as _t,aa as ht,as as Ws,x as Ys,aD as Xs,T as Dt,ae as Qs,f as Qt,b0 as Jt,aI as Js,b1 as Zs,ai as er,b2 as tr,aC as sr,b3 as rr,b4 as ar,b5 as ir,K as nr,aB as ut,ay as $t,L as or,b6 as lr,E as cr}from"./vendor-ui-_RPPooYb.js";import{r as u}from"./vendor-react-BUIyrYwY.js";import{C as ie,a as fe,b as ge,d as Bt,c as ne}from"./card-DrC6oauU.js";import{B as z}from"./button-D3uTTW09.js";import{L as oe}from"./label-D2cpe-a6.js";import{I as Me}from"./input-BbFphxaW.js";import{T as Vt}from"./textarea-BeMDWrVF.js";import{S as tt,a as st,b as rt,c as at,d as ze}from"./select-2208Ip43.js";import{B as ue}from"./badge-C_BuYg_L.js";import{s as me}from"./index-DFKG0mMo.js";import{D as rs,a as as,b as is,c as ns,l as os,m as ls}from"./dialog-CH7MrbNA.js";import{C as Zt}from"./checkbox-CGjHtbbA.js";import{S as cs}from"./scroll-area-BCySFcKh.js";import{f as x,e as de}from"./format-DITPfS5Z.js";import{s as Ue}from"./startOfMonth-DegRm3H9.js";import{s as ft}from"./subMonths-CO-pswDS.js";import{R as es,B as dr,X as pr,Y as mr,T as ts,e as ur,P as hr,c as xr,d as fr}from"./vendor-charts-CcURYOqB.js";import{e as ds}from"./endOfMonth-BJyjn0rX.js";import{p as P}from"./parseISO-Cb1Q6uF3.js";import{f as pe}from"./fr-D83lTE9O.js";import{b as gr,c as br,d as vr,g as jr,a as zt,e as yr}from"./stakeholderUtils-B72soJJv.js";import{d as Ye}from"./differenceInDays-DDL5AqV6.js";import"./index-BdQq_4o_.js";import"./index-qXun1-EW.js";import"./vendor-3d-B-oxlep_.js";import"./vendor-supabase-DWXT_K62.js";import"./vendor-query-DlwbE54t.js";function wr({open:j,onOpenChange:J,projects:d,language:h,onGenerate:R,generating:E}){const[n,B]=u.useState([]),[K,Z]=u.useState(!1),[M,O]=u.useState(""),[he,le]=u.useState(""),[c,A]=u.useState(""),[y,G]=u.useState(""),[we,ce]=u.useState(null),[v,k]=u.useState(h);u.useEffect(()=>{j&&G("")},[j]);const se=u.useMemo(()=>[{id:"last-2-months",label:h==="fr"?"Derniers 2 mois":"Last 2 months",start:x(Ue(ft(new Date,1)),"yyyy-MM-dd"),end:x(new Date,"yyyy-MM-dd"),icon:xt},{id:"last-3-months",label:h==="fr"?"Derniers 3 mois":"Last 3 months",start:x(Ue(ft(new Date,2)),"yyyy-MM-dd"),end:x(new Date,"yyyy-MM-dd"),icon:xt},{id:"q4-2024",label:"Q4 2024",start:"2024-10-01",end:"2024-12-31",icon:it},{id:"year-2024",label:h==="fr"?"Année 2024":"Year 2024",start:"2024-01-01",end:"2024-12-31",icon:it}],[h]),W=u.useMemo(()=>{if(!y.trim())return d;const m=y.toLowerCase();return d.filter(T=>{var ve,Ne;return T.nom_projet.toLowerCase().includes(m)||((Ne=(ve=T.client)==null?void 0:ve.nom_client)==null?void 0:Ne.toLowerCase().includes(m))})},[d,y]),D=m=>{B(T=>T.includes(m)?T.filter(ve=>ve!==m):[...T,m])},ee=()=>{n.length===W.length?B([]):B(W.map(m=>m.projet_id))},Qe=(m,T,ve)=>{ce(m),Z(!0),O(T),le(ve)},Le=(m,T)=>{ce(null),m==="start"?O(T):le(T)},be=()=>{if(n.length===0)return;const m={selectedProjects:n,customDateRange:K&&M&&he?{start:M,end:he}:null,reportTitle:c.trim()||U(),language:v};R(m)},U=()=>{const m=n.map(ve=>{var Ne;return(Ne=d.find(Oe=>Oe.projet_id===ve))==null?void 0:Ne.nom_projet}).filter(Boolean).slice(0,2).join(" & "),T=n.length>2?` +${n.length-2}`:"";return`${m}${T}`},Pe=n.map(m=>d.find(T=>T.projet_id===m)).filter(Boolean),Re=n.length>0&&(!K||M&&he);return e.jsx(rs,{open:j,onOpenChange:J,children:e.jsxs(as,{className:"max-w-2xl max-h-[90vh] flex flex-col",children:[e.jsxs(is,{children:[e.jsxs(ns,{className:"flex items-center gap-2",children:[e.jsx(It,{className:"h-5 w-5 text-blue-500"}),h==="fr"?"Rapport personnalisé":"Custom Report"]}),e.jsx(os,{children:h==="fr"?"Combinez plusieurs projets et/ou périodes dans un seul rapport consolidé.":"Combine multiple projects and/or periods into a single consolidated report."})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto space-y-6 py-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(oe,{className:"flex items-center gap-2 text-base font-semibold",children:[e.jsx(Ft,{className:"h-4 w-4"}),h==="fr"?"Projets":"Projects",n.length>0&&e.jsx(ue,{variant:"secondary",className:"ml-2",children:n.length})]}),e.jsx(z,{variant:"ghost",size:"sm",onClick:ee,className:"text-xs",children:n.length===W.length?h==="fr"?"Désélectionner tout":"Deselect all":h==="fr"?"Tout sélectionner":"Select all"})]}),e.jsxs("div",{className:"relative",children:[e.jsx(qs,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400"}),e.jsx(Me,{placeholder:h==="fr"?"Rechercher un projet...":"Search projects...",value:y,onChange:m=>G(m.target.value),className:"pl-9"})]}),e.jsx(cs,{className:"h-48 rounded-lg border bg-slate-50 p-2",children:e.jsxs("div",{className:"space-y-1.5",children:[W.map(m=>{var T;return e.jsxs("div",{className:`flex items-center gap-3 p-3 rounded-lg border cursor-pointer transition-all ${n.includes(m.projet_id)?"bg-blue-50 border-blue-300 shadow-sm":"bg-white border-slate-200 hover:border-slate-300 hover:bg-slate-50"}`,onClick:()=>D(m.projet_id),children:[e.jsx(Zt,{checked:n.includes(m.projet_id),onCheckedChange:()=>D(m.projet_id)}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-medium text-sm truncate",children:m.nom_projet}),((T=m.client)==null?void 0:T.nom_client)&&e.jsx("p",{className:"text-xs text-slate-500 truncate",children:m.client.nom_client})]})]},m.projet_id)}),W.length===0&&e.jsx("p",{className:"text-sm text-slate-500 text-center py-4",children:h==="fr"?"Aucun projet trouvé":"No projects found"})]})}),n.length>0&&e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[Pe.slice(0,5).map(m=>m&&e.jsxs(ue,{variant:"secondary",className:"flex items-center gap-1 text-xs",children:[m.nom_projet,e.jsx(Mt,{className:"h-3 w-3 cursor-pointer hover:text-red-500",onClick:T=>{T.stopPropagation(),D(m.projet_id)}})]},m.projet_id)),n.length>5&&e.jsxs(ue,{variant:"outline",className:"text-xs",children:["+",n.length-5]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs(oe,{className:"flex items-center gap-2 text-base font-semibold",children:[e.jsx(it,{className:"h-4 w-4"}),h==="fr"?"Période":"Period"]}
1),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:se.map(m=>e.jsxs(z,{variant:"outline",size:"sm",onClick:()=>Qe(m.id,m.start,m.end),className:`justify-start ${we===m.id?"border-blue-500 bg-blue-50 text-blue-700":""}`,children:[e.jsx(m.icon,{className:"h-3.5 w-3.5 mr-2"}),m.label]},m.id))}),e.jsxs("div",{className:"flex items-center gap-2 pt-2",children:[e.jsx(Zt,{id:"custom-dates",checked:K,onCheckedChange:m=>{Z(!!m),m||ce(null)}}),e.jsx("label",{htmlFor:"custom-dates",className:"text-sm text-slate-600 cursor-pointer",children:h==="fr"?"Utiliser des dates personnalisées":"Use custom dates"})]}),K&&e.jsxs("div",{className:"grid grid-cols-2 gap-4 pt-1",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(oe,{className:"text-xs text-slate-500",children:h==="fr"?"Du":"From"}),e.jsx(Me,{type:"date",value:M,onChange:m=>Le("start",m.target.value),className:"text-sm"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(oe,{className:"text-xs text-slate-500",children:h==="fr"?"Au":"To"}),e.jsx(Me,{type:"date",value:he,onChange:m=>Le("end",m.target.value),className:"text-sm"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(oe,{className:"flex items-center gap-2 text-base font-semibold",children:[e.jsx(ss,{className:"h-4 w-4"}),h==="fr"?"Langue du rapport":"Report language"]}),e.jsxs(tt,{value:v,onValueChange:m=>k(m),children:[e.jsx(st,{className:"w-full",children:e.jsx(rt,{})}),e.jsxs(at,{children:[e.jsx(ze,{value:"fr",children:"ð«ð· Français"}),e.jsx(ze,{value:"en",children:"ð¬ð§ English"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(oe,{className:"text-base font-semibold",children:[h==="fr"?"Titre du rapport":"Report title",e.jsxs("span",{className:"text-slate-400 font-normal text-sm ml-2",children:["(",h==="fr"?"optionnel":"optional",")"]})]}),e.jsx(Me,{value:c,onChange:m=>A(m.target.value),placeholder:U()||(h==="fr"?"Titre automatique...":"Auto-generated title...")})]})]}),e.jsxs(ls,{className:"border-t pt-4",children:[e.jsx(z,{variant:"outline",onClick:()=>J(!1),disabled:E,children:h==="fr"?"Annuler":"Cancel"}),e.jsx(z,{onClick:be,disabled:!Re||E,children:E?e.jsxs(e.Fragment,{children:[e.jsx(Xe,{className:"h-4 w-4 mr-2 animate-spin"}),h==="fr"?"Génération...":"Generating..."]}):e.jsxs(e.Fragment,{children:[e.jsx(It,{className:"h-4 w-4 mr-2"}),h==="fr"?"Générer le rapport":"Generate Report"]})})]})]})})}function Nr({reportData:j,reportId:J,language:d,onReportUpdated:h}){const[R,E]=u.useState(!1),[n,B]=u.useState(""),[K,Z]=u.useState(!1),[M,O]=u.useState([]),[he,le]=u.useState(null),c=u.useRef(null),A=d==="fr"?[{label:"Texte",icon:Xt,suggestions:["Rends les accomplissements plus impactants","Simplifie les recommandations","Reformule les next steps de manière plus actionnable","Ajoute plus de détails sur les risques"]},{label:"Visualisations",icon:Tt,suggestions:["Ajoute un graphique de répartition du temps par activité","Crée un diagramme d'évolution des heures par semaine","Génère une visualisation des risques par sévérité","Ajoute un graphique budget vs réalisé"]}]:[{label:"Text",icon:Xt,suggestions:["Make accomplishments more impactful","Simplify the recommendations","Rephrase next steps to be more actionable","Add more details about risks"]},{label:"Visualizations",icon:Tt,suggestions:["Add a time breakdown chart by activity","Create a weekly hours trend chart","Generate a risk severity visualization","Add a budget vs actual chart"]}];u.useEffect(()=>{R&&c.current&&c.current.focus()},[R]);const y=u.useCallback(async()=>{if(!(!n.trim()||!j||!J)){Z(!0),le(null);try{const{data:v,error:k}=await me.functions.invoke("ai-update-report",{body:{reportId:J,currentReport:j,userRequest:n,language:d}});if(k)throw new Error(k.message||"Function invocation failed");if(v!=null&&v.error){if(v.error==="Rate limit exceeded"){le(d==="fr"?"Limite de requêtes atteinte. Réessayez dans quelques instants.":"Rate limit reached. Please try again in a moment.");return}throw new Error(v.error)}if(v!=null&&v.updatedReport){h(v.updatedReport);const W=n.toLowerCase().includes("graph")||n.toLowerCase().includes("chart")||n.toLowerCase().includes("visualis")||n.toLowerCase().includes("diagram")?"chart":"text";O(D=>[{summary:v.changesSummary||n,type:W,timestamp:new Date},...D].slice(0,5)),q.success(d==="fr"?"Rapport mis à jour!":"Report updated!"),B("")}else throw new Error("No updated report received")}catch(v){console.error("AI update error:",v);const k=v instanceof Error?v.message:"Unknown error";le(d==="fr"?`Erreur: ${k}`:`Error: ${k}`),q.error(d==="fr"?"Erreur lors de la mise à jour":"Error updating report")}finally{Z(!1)}}},[n,j,J,d,h]),G=v=>{B(v),le(null),c.current&&c.current.focus()},we=v=>{v.key==="Enter"&&!v.shiftKey&&(v.preventDefault(),y())},ce=()=>{O([])};return!j||!J?null:e.jsxs(e.Fragment,{children:[e.jsx(Wt,{children:!R&&e.jsx(St.div,{initial:{scale:0,opacity:0}
1,animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:{type:"spring",damping:20,stiffness:300},className:"fixed bottom-6 right-6 z-50",children:e.jsxs(z,{onClick:()=>E(!0),className:"h-14 px-5 rounded-full bg-gradient-to-r from-violet-600 to-indigo-600 hover:from-violet-700 hover:to-indigo-700 shadow-xl shadow-violet-500/25 text-white group transition-all duration-300 hover:scale-105",children:[e.jsx(Yt,{className:"h-5 w-5 mr-2 group-hover:animate-pulse"}),e.jsx("span",{className:"font-medium",children:d==="fr"?"Modifier avec l'IA":"Ask AI to update"}),M.length>0&&e.jsx(ue,{className:"ml-2 bg-white/20 text-white text-xs",children:M.length})]})})}),e.jsx(Wt,{children:R&&e.jsx(St.div,{initial:{opacity:0,y:100,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:100,scale:.95},transition:{type:"spring",damping:25,stiffness:300},className:"fixed bottom-6 right-6 z-50 w-[420px] max-w-[calc(100vw-48px)]",children:e.jsxs("div",{className:"bg-white rounded-2xl shadow-2xl border border-slate-200 overflow-hidden",children:[e.jsxs("div",{className:"bg-gradient-to-r from-violet-600 to-indigo-600 px-4 py-3 flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2 text-white",children:[e.jsx(Yt,{className:"h-5 w-5"}),e.jsx("span",{className:"font-semibold",children:d==="fr"?"Assistant IA":"AI Assistant"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[M.length>0&&e.jsx(z,{variant:"ghost",size:"sm",className:"text-white/70 hover:text-white hover:bg-white/20 h-8 text-xs",onClick:ce,children:d==="fr"?"Effacer":"Clear"}),e.jsx(z,{variant:"ghost",size:"icon",className:"text-white/80 hover:text-white hover:bg-white/20 h-8 w-8",onClick:()=>E(!1),children:e.jsx(Mt,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"p-4 space-y-4 max-h-[60vh] overflow-y-auto",children:[he&&e.jsxs(St.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"flex items-start gap-2 p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm",children:[e.jsx(Us,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsx("span",{children:he}),e.jsx(z,{variant:"ghost",size:"icon",className:"h-5 w-5 ml-auto -mt-0.5",onClick:()=>le(null),children:e.jsx(Mt,{className:"h-3 w-3"})})]}),M.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs text-slate-500 font-medium uppercase tracking-wide",children:d==="fr"?"Modifications récentes":"Recent changes"}),e.jsx("div",{className:"space-y-1.5",children:M.map((v,k)=>e.jsxs(St.div,{initial:{opacity:0,x:-10},animate:{opacity:1,x:0},transition:{delay:k*.1},className:`text-xs px-3 py-2 rounded-lg flex items-start gap-2 ${v.type==="chart"?"bg-blue-50 text-blue-700":"bg-green-50 text-green-700"}`,children:[v.type==="chart"?e.jsx(Tt,{className:"h-3 w-3 mt-0.5 flex-shrink-0"}):e.jsx(Gs,{className:"h-3 w-3 mt-0.5 flex-shrink-0"}),e.jsx("span",{className:"line-clamp-2",children:v.summary})]},`${v.timestamp.getTime()}-${k}`))})]}),A.map((v,k)=>e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"text-xs text-slate-500 font-medium uppercase tracking-wide flex items-center gap-1.5",children:[e.jsx(v.icon,{className:"h-3 w-3"}),v.label]}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:v.suggestions.map((se,W)=>e.jsx("button",{onClick:()=>G(se),disabled:K,className:"text-xs px-2.5 py-1.5 bg-slate-100 hover:bg-slate-200 disabled:opacity-50 rounded-full text-slate-600 transition-colors",children:se},W))})]},k)),e.jsxs("div",{className:"space-y-2 pt-2 border-t border-slate-100",children:[e.jsx(Vt,{ref:c,value:n,onChange:v=>{B(v.target.value),le(null)},onKeyDown:we,placeholder:d==="fr"?"Décrivez les modifications souhaitées ou demandez un graphique...":"Describe changes or request a chart...",className:"min-h-[80px] resize-none text-sm border-slate-200 focus:border-violet-300 focus:ring-violet-200",disabled:K}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-xs text-slate-400",children:d==="fr"?"Entrée pour envoyer ⢠Shift+Entrée nouvelle ligne":"Enter to send ⢠Shift+Enter for new line"}),e.jsx(z,{onClick:y,disabled:!n.trim()||K,size:"sm",className:"bg-gradient-to-r from-violet-600 to-indigo-600 hover:from-violet-700 hover:to-indigo-700 disabled:from-slate-400 disabled:to-slate-500",children:K?e.jsxs(e.Fragment,{children:[e.jsx(Xe,{className:"h-4 w-4 animate-spin mr-1"}),d==="fr"?"Traitement...":"Processing..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Ks,{className:"h-4 w-4 mr-1"}),d==="fr"?"Appliquer":"Apply"]})})]})]})]})]})})})]})}function kr({open:j,onOpenChange:J,language:d,teamMembers:h,inconsistencies:R,projectNames:E,totalHours:n,onConfirm:B,onCancel:K}){const[Z,M]=u.useState(""),O={title:d==="fr"?"Vérification des données":"Data Verification",subtitle:d==="fr"?"Veuillez vérifier que toutes les informations sont correctes avant de continuer.":"Please verify that all information is correct before proceeding.",teamSection:d==="fr"?"Ãquipe détectée":"Detected Team",issuesSection:d==="fr"?"Points à vérifier":"Items to Review",noIssues:d==="fr"?"Aucun problème détecté":"No issues detected",notesLabel:d==="fr"?"Notes ou corrections (optionnel)":"Notes or corrections (optional)",notesPlaceholder:d==="fr"?"Ajoutez des précisions si certaines informations semblent incorrectes...":"Add details if any information seems incorrect...",confirm:d==="fr"?"Confirmer et continuer":"Confirm and continue",cancel:d==="fr"?"Annuler":"Cancel",hours:d==="fr"?"heures":"hours",projects:d==="fr"?"projets":"projects",roles:d==="fr"?"Rôles":"Roles",summary:d==="fr"?"Résumé":"Summary"},he=c=>{switch(c){case"missing_member":return e.jsx(_t,{className:"h-4 w-4 text-amber-500"});case"missing_role":return e.jsx(Ys,{className:"h-4 w-4 text-blue-500"});case"hours_mismatch":return e.jsx(xt,{className:"h-4 w-4 text-red-500"});case"project_gap":return e.jsx(Ws,{className:"h-4 w-4 text-purple-500"});default:return e.jsx(ht,{className:"h-4 w-4 text-slate-500"})}},le=c=>{switch(c){case"missing_member":return"border-amber-200 bg-amber-50";case"missing_role":return"border-blue-200 bg-blue-50";case"hours_mismatch":return"border-red-200 bg-red-50";case"project_gap":return"border-purple-200 bg-purple-50";default:return"border-slate-200 bg-slate-50"}};return e.jsx(rs,{open:j,onOpenChange:J,children:e.jsxs(as,{className:"max-w-2xl max-h-[85vh] flex flex-col",children:[e.jsxs(is,{children:[e.jsxs(ns,{className:"flex items-center gap-2",children:[e.jsx(Ct,{className:"h-5 w-5 text-green-500"}),O.title]}),e.jsx(os,{children:O.subtitle})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto space-y-6 py-4",children:[e.jsxs("div",{className:"bg-slate-50 rounded-lg p-4 border",children:[e.jsx(oe,{className:"text-sm font-semibold text-slate-700",children:O.summary}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-3",children:[e.jsxs(ue,{variant:"secondary",className:"text-sm",children:[h.length," ",d==="fr"?"membres":"members"]}),e.jsxs(ue,{variant:"secondary",className:"text-sm",children:[n,"h ",O.hours]}),e.jsxs(ue,{variant:"secondary",className:"text-sm",children:[E.length," ",O.projects]})]}),e.jsx("div",{className:"mt-2 text-xs text-slate-500",children:E.join(", ")})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs(oe,{className:"flex items-center gap-2 text-base font-semibold",children:[e.jsx(_t,{className:"h-4 w-4"}),O.teamSection]}),e.jsx(cs,{className:"max-h-48",children:e.jsx("div",{className:"space-y-2",children:h.map((c,A)=>e.jsxs("div",{className:"flex items-center justify-between p-3 bg-white rounded-lg border",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"font-medium text-sm",children:c.name}),e.jsx("div",{className:"flex flex-wrap gap-1 mt-1",children:c.roles.map((y,G)=>e.jsx(ue,{variant:"outline",className:"text-xs",children:y},G))})]}),e.jsxs("div",{className:"text-right",children:[e.jsxs("p",{className:"text-sm font-medium",children:[c.hours,"h"]}),e.jsxs("p",{className:"text-xs text-slate-500",children:[c.projects.length," ",O.projects]})]})]},A))})})]}),R.length>0&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs(oe,{className:"flex items-center gap-2 text-base font-semibold text-amber-700",children:[e.jsx(ht,{className:"h-4 w-4"}),O.issuesSection]}),e.jsx("div",{className:"space-y-2",children:R.map((c,A)=>e.jsx("div",{className:`p-3 rounded-lg border ${le(c.type)}`,children:e.jsxs("div",{className:"flex items-start gap-2",children:[he(c.type),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"font-medium text-sm",children:c.title}),e.jsx("p",{className:"text-xs text-slate-600 mt-0.5",children:c.description}),c.suggestedAction&&e.jsxs("p",{className:"text-xs text-slate-500 mt-1 italic",children:["ð¡ ",c.suggestedAction]})]})]})},A))})]}),R.length===0&&e.jsxs("div",{className:"text-center py-4 text-green-600 flex items-center justify-center gap-2",children:[e.jsx(Ct,{className:"h-5 w-5"}),e.jsx("span",{className:"font-medium",children:O.noIssues})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(oe,{className:"text-sm font-medium",children:O.notesLabel}),e.jsx(Vt,{value:Z,onChange:c=>M(c.target.value),placeholder:O.notesPlaceholder,rows:3})]})]}),e.jsxs(ls,{className:"border-t pt-4",children:[e.jsx(z,{variant:"outline",onClick:K,children:O.cancel}),e.jsxs(z,{onClick:()=>B(Z),children:[e.jsx(Ct,{className:"h-4 w-4 mr-2"}),O.confirm]})]})]})})}const Ve=["#3B82F6","#10B981","#F59E0B","#EF4444","#8B5CF6","#EC4899","#06B6D4","#84CC16"];function Sr({language:j}){const[J,d]=u.useState(!0),[h,R]=u.useState([]),[E,n]=u.useState(null),[B,K]=u.useState("current"),Z=j==="fr"?pe:de,M={title:j==="fr"?"Contributeurs":"Contributors",subtitle:j==="fr"?"Vue des heures par membre de l'équipe":"Team member hours overview",period:j==="fr"?"Période":"Period",current:j==="fr"?"(en cours)":"(current)",totalHours:j==="fr"?"heures totales":"total hours",viewDetails:j==="fr"?"Voir détails":"View details",detailsFor:j==="fr"?"Détail pour":"Details for",close:j==="fr"?"Fermer":"Close",noData:j==="fr"?"Aucune donnée pour cette période":"No data for this period",byProject:j==="fr"?"Par projet":"By project",byActivity:j==="fr"?"Par activité":"By activity",recentEntries:j==="fr"?"Entrées récentes":"Recent entries",hours:j==="fr"?"heures":"hours"},O=(()=>{const c=[],A=new Date;c.push({value:"current",label:`${x(A,"MMMM yyyy",{locale:Z})} ${M.current}`,startDate:Ue(A),endDate:A});for(let y=1;y<=11;y++){const G=ft(A,y);
1c.push({value:x(G,"yyyy-MM"),label:x(G,"MMMM yyyy",{locale:Z}),startDate:Ue(G),endDate:ds(G)})}return c})();u.useEffect(()=>{he()},[B]);const he=async()=>{var c,A;d(!0);try{const y=O.find(k=>k.value===B);if(!y)return;const{data:G,error:we}=await me.from("sbc_time_entries").select(` 2 time_id, 3 date, 4 duree_minutes, 5 description_brute, 6 description_structuree, 7 user_id, 8 user:sbc_users(user_id, nom), 9 projet:sbc_projets(nom_projet), 10 task_type:sbc_task_types(nom) 11 `).gte("date",x(y.startDate,"yyyy-MM-dd")).lte("date",x(y.endDate,"yyyy-MM-dd")).order("date",{ascending:!1});if(we)throw we;const ce=new Map;for(const k of G||[]){const se=k.user;if(!se)continue;const W=se.user_id,D=se.nom||"Unknown",ee=((c=k.projet)==null?void 0:c.nom_projet)||"N/A",Qe=((A=k.task_type)==null?void 0:A.nom)||"Other",Le=(k.duree_minutes||0)/60;ce.has(W)||ce.set(W,{userId:W,name:D,totalHours:0,entries:[],byProject:[],byTaskType:[]});const be=ce.get(W);be.totalHours+=Le,be.entries.push({date:k.date,hours:Le,description:k.description_structuree||k.description_brute||"",project:ee,taskType:Qe})}for(const k of ce.values()){const se=new Map;for(const D of k.entries)se.set(D.project,(se.get(D.project)||0)+D.hours);k.byProject=Array.from(se.entries()).map(([D,ee])=>({name:D,hours:ee})).sort((D,ee)=>ee.hours-D.hours);const W=new Map;for(const D of k.entries)W.set(D.taskType,(W.get(D.taskType)||0)+D.hours);k.byTaskType=Array.from(W.entries()).map(([D,ee])=>({name:D,hours:ee})).sort((D,ee)=>ee.hours-D.hours)}const v=Array.from(ce.values()).sort((k,se)=>se.totalHours-k.totalHours);R(v)}catch(y){console.error("Error fetching contributor data:",y),q.error(j==="fr"?"Erreur de chargement":"Loading error")}finally{d(!1)}},le=Math.max(...h.map(c=>c.totalHours),1);return e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(ge,{className:"flex items-center gap-2",children:[e.jsx(_t,{className:"h-5 w-5 text-primary"}),M.title]}),e.jsx(Bt,{children:M.subtitle})]}),e.jsxs(tt,{value:B,onValueChange:K,children:[e.jsxs(st,{className:"w-[200px]",children:[e.jsx(it,{className:"h-4 w-4 mr-2"}),e.jsx(rt,{})]}),e.jsx(at,{children:O.map(c=>e.jsx(ze,{value:c.value,children:c.label},c.value))})]})]})}),e.jsx(ne,{children:J?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Xe,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):h.length===0?e.jsx("p",{className:"text-center text-muted-foreground py-8",children:M.noData}):E?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"h-12 w-12 rounded-full bg-primary/10 flex items-center justify-center",children:e.jsx("span",{className:"text-lg font-bold text-primary",children:E.name.charAt(0).toUpperCase()})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:E.name}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[E.totalHours.toFixed(1)," ",M.totalHours]})]})]}),e.jsxs(z,{variant:"ghost",size:"sm",onClick:()=>n(null),children:[e.jsx(Mt,{className:"h-4 w-4 mr-1"}),M.close]})]}),e.jsxs("div",{className:"grid md:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("h4",{className:"font-medium flex items-center gap-2",children:[e.jsx(Xs,{className:"h-4 w-4"}),M.byProject]}),e.jsx("div",{className:"h-[200px]",children:e.jsx(es,{width:"100%",height:"100%",children:e.jsxs(dr,{data:E.byProject.slice(0,5),layout:"vertical",children:[e.jsx(pr,{type:"number",tick:{fontSize:11}}),e.jsx(mr,{type:"category",dataKey:"name",width:100,tick:{fontSize:11},tickFormatter:c=>c.length>15?c.substring(0,15)+"...":c}),e.jsx(ts,{formatter:c=>[`${c.toFixed(1)}h`,M.hours],contentStyle:{fontSize:12}}),e.jsx(ur,{dataKey:"hours",fill:"hsl(var(--primary))",radius:[0,4,4,0]})]})})})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("h4",{className:"font-medium flex items-center gap-2",children:[e.jsx(Dt,{className:"h-4 w-4"}),M.byActivity]}),e.jsx("div",{className:"h-[200px]",children:e.jsx(es,{width:"100%",height:"100%",children:e.jsxs(hr,{children:[e.jsx(xr,{data:E.byTaskType,dataKey:"hours",nameKey:"name",cx:"50%",cy:"50%",innerRadius:40,outerRadius:70,paddingAngle:2,children:E.byTaskType.map((c,A)=>e.jsx(fr,{fill:Ve[A%Ve.length]},`cell-${A}`))}),e.jsx(ts,{formatter:c=>[`${c.toFixed(1)}h`,M.hours],contentStyle:{fontSize:12}})]})})}),e.jsx("div",{className:"flex flex-wrap gap-2",children:E.byTaskType.slice(0,4).map((c,A)=>e.jsxs(ue,{variant:"outline",className:"text-xs",children:[e.jsx("span",{className:"w-2 h-2 rounded-full mr-1.5",style:{backgroundColor:Ve[A%Ve.length]}}),c.name,": ",c.hours.toFixed(1),"h"]},c.name))})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("h4",{className:"font-medium flex items-center gap-2",children:[e.jsx(xt,{className:"h-4 w-4"}),M.recentEntries]}),e.jsx("div",{className:"space-y-2 max-h-[300px] overflow-y-auto",children:E.entries.slice(0,20).map((c,A)=>e.jsxs("div",{className:"flex items-start gap-3 p-3 bg-muted/50 rounded-lg border border-border/50",children:[e.jsx("div",{className:"text-xs text-muted-foreground whitespace-nowrap pt-0.5",children:x(P(c.date),"dd MMM",{locale:Z})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm truncate",children:c.description||"â"}),e.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[e.jsx(ue,{variant:"secondary",className:"text-xs",children:c.project}),e.jsx(ue,{variant:"outline",className:"text-xs",children:c.taskType})]})]}),e.jsxs("div",{className:"text-sm font-medium text-primary whitespace-nowrap",children:[c.hours.toFixed(1),"h"]})]},A))})]})]}):e.jsx("div",{className:"grid gap-3",children:h.map((c,A)=>e.jsxs("div",{className:"flex items-center gap-4 p-4 rounded-lg border border-border/50 bg-card hover:bg-muted/50 transition-colors cursor-pointer group",onClick:()=>n(c),children:[e.jsx("div",{className:"h-10 w-10 rounded-full flex items-center justify-center text-white font-semibold",style:{backgroundColor:Ve[A%Ve.length]},children:c.name.charAt(0).toUpperCase()}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-medium truncate",children:c.name}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[c.byProject.length," ",j==="fr"?"projets":"projects"]})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("div",{className:"hidden sm:block w-[120px]",children:e.jsx("div",{className:"h-2 bg-muted rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${c.totalHours/le*100}%`,backgroundColor:Ve[A%Ve.length]}})})}),e.jsx("div",{className:"text-right",children:e.jsxs("p",{className:"font-semibold text-primary",children:[c.totalHours.toFixed(1),"h"]})}),e.jsx(Qs,{className:"h-5 w-5 text-muted-foreground group-hover:text-primary transition-colors"})]})]},c.userId))})})]})}const qe=["#3B82F6","#10B981","#F59E0B","#EF4444","#8B5CF6","#EC4899","#06B6D4","#84CC16"],$r=(j,J,d)=>{const h=j.toLowerCase();return h.includes("site")||h.includes("website")||h.includes("web")?d==="fr"?"Création et développement d'un site web professionnel et moderne":"Create and develop a professional, modern website":h.includes("automation")||h.includes("automat")?d==="fr"?"Automatisation des processus business pour améliorer l'efficacité opérationnelle":"Automate business processes to improve operational efficiency":h.includes("marketing")||h.includes("content")||h.includes("contenu")?d==="fr"?"Développement de la stratég
11ie marketing et création de contenu engageant":"Develop marketing strategy and create engaging content":h.includes("consulting")||h.includes("audit")||h.includes("strategy")?d==="fr"?"Accompagnement stratégique et conseil pour optimiser les opérations":"Strategic consulting and advisory to optimize operations":h.includes("brand")||h.includes("marque")?d==="fr"?"Création et développement de l'identité de marque":"Create and develop brand identity":d==="fr"?`Projet de consulting pour ${J||"le client"}`:`Consulting project for ${J||"the client"}`},Cr=(j,J)=>{const d=j.toLowerCase(),R={fr:[{type:"Disponibilité",description:"Interruptions voyages & disponibilité vacances",severity:"Moyenne",impact:"Retards potentiels sur les livrables",mitigation:"Planning anticipé, communication proactive",owner:"Team SBC"},{type:"Données",description:"Manque de données historiques du projet",severity:"Faible",impact:"Estimations moins précises",mitigation:"Utilisation de benchmarks sectoriels",owner:"PM"},{type:"Client",description:"Disponibilité client pour les réunions de gouvernance",severity:"Moyenne",impact:"Décisions retardées",mitigation:"Planification hebdomadaire, async updates",owner:"PM"},{type:"Technique",description:"Intégration outils client existants",severity:"Moyenne",impact:"Complexité additionnelle",mitigation:"Audit technique préalable",owner:"Dev Lead"},{type:"Adoption",description:"Capacité client à utiliser les outils livrés",severity:"Faible",impact:"Sous-utilisation des livrables",mitigation:"Formation et documentation",owner:"Team SBC"}],en:[{type:"Availability",description:"Travel interruptions & holiday availability",severity:"Medium",impact:"Potential delays on deliverables",mitigation:"Advance planning, proactive communication",owner:"SBC Team"},{type:"Data",description:"Lack of historical project data",severity:"Low",impact:"Less accurate estimates",mitigation:"Use of industry benchmarks",owner:"PM"},{type:"Client",description:"Client availability for governance meetings",severity:"Medium",impact:"Delayed decisions",mitigation:"Weekly planning, async updates",owner:"PM"},{type:"Technical",description:"Integration with existing client tools",severity:"Medium",impact:"Additional complexity",mitigation:"Prior technical audit",owner:"Dev Lead"},{type:"Adoption",description:"Client ability to use delivered tools",severity:"Low",impact:"Underutilization of deliverables",mitigation:"Training and documentation",owner:"SBC Team"}]}[J];return d.includes("site")||d.includes("website")?[R[0],R[3],R[4]]:d.includes("automation")?[R[3],R[4],R[1]]:[R[0],R[2]]},Lt=(j,J,d)=>{const h=[],R=new Set,E=[...j].sort((B,K)=>B.date.localeCompare(K.date)),n=[{regex:/\b(v\s*1|version\s*1|v1)\b/i,type:"version",label:"V1"},{regex:/\b(v\s*2|version\s*2|v2)\b/i,type:"version",label:"V2"},{regex:/\b(launch|lancement|mise en ligne|go\s*live|live)\b/i,type:"launch",label:"Launch"},{regex:/\b(final|terminé|completed|livraison finale|finalized)\b/i,type:"completion",label:d==="fr"?"Livré":"Done"},{regex:/\b(branding|brand|identité|identity)\b/i,type:"delivery",label:"Branding"},{regex:/\b(stripe|payment|paiement|monetization)\b/i,type:"delivery",label:d==="fr"?"Paiement":"Payment"},{regex:/\b(automation|automatisation|workflow)\b/i,type:"delivery",label:"Auto"},{regex:/\b(seo|référencement)\b/i,type:"delivery",label:"SEO"}];E.length>0&&(h.push({date:E[0].date,label:"Kick-off",type:"kickoff"}),R.add("kickoff"));for(const B of E){const K=B.description||"";for(const Z of n)if(Z.regex.test(K)){const M=Z.label;R.has(M)||(h.push({date:B.date,label:Z.label,type:Z.type}),R.add(M))}}if(h.length<2&&E.length>5){const B=Math.floor(E.length/2);h.push({date:E[B].date,label:d==="fr"?"En cours":"Progress",type:"delivery"})}return h.sort((B,K)=>B.date.localeCompare(K.date)).slice(0,4)},Ot={fr:[{type:"Nouvelle fonctionnalité",description:"Ajout d'une fonctionnalité non prévue initialement",implications:"Heures additionnelles requises, facturation séparée"},{type:"Modification de design",description:"Révision majeure du design approuvé",implications:"Délai additionnel, révision du planning"},{type:"Changement de périmètre",description:"Extension ou réduction du scope initial",implications:"Ajustement du budget et du planning"},{type:"Révision technique",description:"Changement d'approche technique suite à nouvelles contraintes",implications:"Impact sur le livrable final"}],en:[{type:"New feature",description:"Addition of a feature not initially planned",implications:"Additional hours required, separate billing"},{type:"Design modification",description:"Major revision of approved design",implications:"Additional delay, schedule revision"},{type:"Scope change",description:"Extension or reduction of initial scope",implications:"Budget and timeline adjustment"},{type:"Technical revision",description:"Technical approach change due to new constraints",implications:"Impact on final deliverable"}]},Ht={fr:{title:"Reporting Client",subtitle:"Générez automatiquement vos présentations de suivi mensuel",configTitle:"Configuration du rapport",configDesc:"Sélectionnez le projet, la période et les options d'export",project:"Projet",period:"Période",language:"Langue du rapport",format:"Format d'export",generate:"Générer le rapport",generating:"Génération en cours...",exportSlides:"Ouvrir présentation",exportPdf:"Télécharger PDF",copyLink:"Copier le lien",monthlyReport:"Rapport Mensuel",hoursWorked:"heures travaillées",keyAccomplishments:"Accomplissements clés",timeBreakdown:"Répartition du temps",timeline:"Timeline des livrables",teamInvolved:"Ãquipe impl
11iquée",recommendations:"Recommandations",kpis:"Indicateurs clés",comparison:"vs période précédente",noEntries:"Aucune entrée de temps pour cette période",current:"(en cours)",inScopeHours:"Heures In Scope",outOfScopeHours:"Heures Out of Scope",teamSize:"Membres de l'équipe",scopeChanges:"Scope Change Log",risksAndDependencies:"Risques et Dépendances",meetingLogs:"Compte-rendus de réunions",nextSteps:"Prochaines étapes",nothingForNow:"Rien pour le moment",previousReports:"Rapports précédemment générés",viewReport:"Voir",deleteReport:"Supprimer",addNextStep:"Ajouter une étape",shareableLink:"Lien partageable",linkCopied:"Lien copié!",saveNextSteps:"Enregistrer les étapes",saved:"Enregistré",projectDates:"Dates du projet",projectStart:"Début",projectEnd:"Fin",ongoing:"En cours",phases:"Phases du projet",taskTracker:"Suivi des tâches",ganttChart:"Diagramme de Gantt",inScope:"In Scope (facturé)",outOfScope:"Out of Scope (non facturé)",scopeChangeFramework:"Cadre des changements de scope"},en:{title:"Client Reporting",subtitle:"Automatically generate your monthly progress presentations",configTitle:"Report Configuration",configDesc:"Select the project, period, and export options",project:"Project",period:"Period",language:"Report Language",format:"Export Format",generate:"Generate Report",generating:"Generating...",exportSlides:"Open Presentation",exportPdf:"Download PDF",copyLink:"Copy Link",monthlyReport:"Monthly Report",hoursWorked:"hours worked",keyAccomplishments:"Key Accomplishments",timeBreakdown:"Time Breakdown",timeline:"Deliverables Timeline",teamInvolved:"Team Involved",recommendations:"Recommendations",kpis:"Key Metrics",comparison:"vs previous period",noEntries:"No time entries for this period",current:"(current)",inScopeHours:"In Scope Hours",outOfScopeHours:"Out of Scope Hours",teamSize:"Team Members",scopeChanges:"Scope Change Log",risksAndDependencies:"Risks and Dependencies",meetingLogs:"Meeting Logs",nextSteps:"Next Steps",nothingForNow:"Nothing for now",previousReports:"Previously Generated Reports",viewReport:"View",deleteReport:"Delete",addNextStep:"Add step",shareableLink:"Shareable Link",linkCopied:"Link copied!",saveNextSteps:"Save steps",saved:"Saved",projectDates:"Project Dates",projectStart:"Start",projectEnd:"End",ongoing:"Ongoing",phases:"Project Phases",taskTracker:"Task Tracker",ganttChart:"Gantt Chart",inScope:"In Scope (billed)",outOfScope:"Out of Scope (not billed)",scopeChangeFramework:"Scope Change Framework"}};function ra(){const[j,J]=u.useState([]),[d,h]=u.useState(""),[R,E]=u.useState("current"),[n,B]=u.useState("fr"),[K,Z]=u.useState(!0),[M,O]=u.useState(!1),[he,le]=u.useState(!1),[c,A]=u.useState(!1),[y,G]=u.useState(null),[we,ce]=u.useState(null),[v,k]=u.useState(null),[se,W]=u.useState([]),[D,ee]=u.useState([]),[Qe,Le]=u.useState(!1),[be,U]=u.useState(!1),[Pe,Re]=u.useState([]),[m,T]=u.useState([]),[ve,Ne]=u.useState(""),[Oe,nt]=u.useState([]),[Ge,Ke]=u.useState([]),[ot,gt]=u.useState([]),[lt,bt]=u.useState([]),[re,vt]=u.useState({start:"",end:"",status:"ongoing"}),[ps,Pt]=u.useState(!1),[ms,ct]=u.useState(!1),[Dr,_]=u.useState(0),[Mr,te]=u.useState(""),[He,Je]=u.useState(null),[us,jt]=u.useState(!1),[Ze,yt]=u.useState(null),g=Ht[n],Ee=n==="fr"?pe:de,qt=u.useMemo(()=>{const t=[],r=new Date;t.push({value:"full_project",label:n==="fr"?"ð Projet entier":"ð Full Project",startDate:new Date("2020-01-01"),endDate:r}),t.push({value:"current",label:`${x(r,"MMMM yyyy",{locale:Ee})} ${g.current}`,startDate:Ue(r),endDate:r});for(let s=1;s<=11;s++){const p=ft(r,s);t.push({value:x(p,"yyyy-MM"),label:x(p,"MMMM yyyy",{locale:Ee}),startDate:Ue(p),endDate:ds(p)})}return t},[Ee,g.current,n]);u.useEffect(()=>{hs(),dt()},[]);const hs=async()=>{try{const{data:t,error:r}=await me.from("sbc_projets").select(` 12 projet_id, 13 nom_projet, 14 client_id, 15 budget_heures, 16 budget_euros, 17 risques, 18 date_debut, 19 date_fin_cible, 20 statut, 21 client:sbc_clients(nom_client) 22 `).eq("archive",!1).order("nom_projet");if(r)throw r;J(t||[])}catch{q.error("Erreur lors du chargement des projets")}finally{Z(!1)}},dt=async()=>{try{const{data:t,error:r}=await me.from("sbc_generated_reports").select(` 23 *, 24 projet:sbc_projets(nom_projet, client:sbc_clients(nom_
24client)) 25 `).order("created_at",{ascending:!1}).limit(20);if(r)throw r;W(t||[])}catch(t){console.error("Error fetching previous reports:",t)}},Ut=async(t,r,s)=>{const{data:p,error:w}=await me.from("sbc_time_entries").select(` 26 time_id, 27 date, 28 duree_minutes, 29 description_brute, 30 description_structuree, 31 est_facturable, 32 task_type:sbc_task_types(nom), 33 user:sbc_users(nom) 34 `).eq("projet_id",t).gte("date",x(r,"yyyy-MM-dd")).lte("date",x(s,"yyyy-MM-dd")).order("date",{ascending:!0});if(w)throw w;return p||[]},xs=async t=>{const{data:r,error:s}=await me.from("sbc_time_entries").select(` 35 time_id, 36 date, 37 duree_minutes, 38 description_brute, 39 description_structuree, 40 est_facturable, 41 task_type:sbc_task_types(nom), 42 user:sbc_users(nom) 43 `).eq("projet_id",t).order("date",{ascending:!0});if(s)throw s;return r||[]},fs=async t=>{const{data:r,error:s}=await me.from("sbc_scope_changes").select("*").eq("projet_id",t).order("date",{ascending:!1});if(s)throw s;return r||[]},gs=async(t,r,s)=>{const{data:p,error:w}=await me.from("sbc_meetings").select("*").eq("projet_id",t).gte("date",x(r,"yyyy-MM-dd")).lte("date",x(s,"yyyy-MM-dd")).order("date",{ascending:!1});if(w)throw w;return p||[]},bs=async(t,r)=>{const s=new Date(r);s.setDate(s.getDate()-1);const p=Ue(s),{data:w,error:S}=await me.from("sbc_time_entries").select("duree_minutes").eq("projet_id",t).gte("date",x(p,"yyyy-MM-dd")).lte("date",x(s,"yyyy-MM-dd"));return S?null:(w==null?void 0:w.reduce((o,b)=>o+b.duree_minutes,0))||0},Rt=(t,r)=>{const s=new Map;t.forEach($=>{var Y;const H=((Y=$.task_type)==null?void 0:Y.nom)||(r==="fr"?"Autre":"Other");s.has(H)||s.set(H,[]),s.get(H).push($)});const p=[],w={content:["Flyers","Content","Social Media","Marketing","Branding","Email"],website:["Website","Site web","Dev","Frontend","Backend"],consulting:["Audit","Consulting","Strategy","Process"],other:[]},S=new Map;s.forEach(($,H)=>{let Y="other";for(const[I,je]of Object.entries(w))if(je.some(xe=>H.toLowerCase().includes(xe.toLowerCase()))){Y=I;break}S.has(Y)||S.set(Y,{entries:[],hours:0});const L=S.get(Y);L.entries.push(...$),L.hours+=$.reduce((I,je)=>I+je.duree_minutes/60,0)});const o=Array.from(S.entries()).filter(([$,H])=>H.hours>0).sort(($,H)=>$[0]==="content"&&H[0]==="website"?-1:$[0]==="website"&&H[0]==="content"?1:H[1].hours-$[1].hours),b={content:{fr:"Création de contenu",en:"Content Creation"},website:{fr:"Développement web",en:"Web Development"},consulting:{fr:"Conseil & Audit",en:"Consulting & Audit"},other:{fr:"Autres activités",en:"Other Activities"}};let N=1;return o.forEach(([$,H])=>{var xe;const Y=H.entries.sort((F,X)=>F.date.localeCompare(X.date)).map(F=>{var X;return{date:F.date,description:F.description_structuree||F.description_brute||"",hours:Math.round(F.duree_minutes/60*10)/10,type:((X=F.task_type)==null?void 0:X.nom)||(r==="fr"?"Autre":"Other"),inScope:F.est_facturable!==!1}}),L=Y.map(F=>F.date).sort((F,X)=>F.localeCompare(X)),I=Y.filter(F=>F.inScope).reduce((F,X)=>F+X.hours,0),je=Y.filter(F=>!F.inScope).reduce((F,X)=>F+X.hours,0);p.push({name:`Phase ${N}: ${((xe=b[$])==null?void 0:xe[r])||$}`,tasks:Y,totalHours:Math.round(H.hours*10)/10,inScopeHours:Math.round(I*10)/10,outOfScopeHours:Math.round(je*10)/10,startDate:L[0]||"",endDate:L[L.length-1]||""}),N++}),p},vs=async()=>{var t,r,s,p,w,S;if(!d){q.error(n==="fr"?"Veuillez sélectionner un projet":"Please select a project");return}O(!0),_(0),te(n==="fr"?"Initialisation...":"Initializing..."),Je(null);try{const o=j.find(i=>i.projet_id===d);if(!o)throw new Error("Project not found");const b=qt.find(i=>i.value===R);if(!b)throw new Error("Period not found");_(5),te(n==="fr"?"Récupération des données...":"Fetching data...");const[N,$,H,Y]=await Promise.all([Ut(d,b.startDate,b.endDate),xs(d),fs(d),gs(d,b.startDate,b.endDate)]);if(_(20),N.length===0){q.warning(g.noEntries),G(null),O(!1),_(0),te("");return}_(25),te(n==="fr"?"Calcul des heures...":"Calculating hours...");const L=new Map;N.forEach(i=>
43{var kt;const f=((kt=i.task_type)==null?void 0:kt.nom)||(n==="fr"?"Autre":"Other"),V=i.duree_minutes/60,De=i.est_facturable!==!1;L.has(f)||L.set(f,{total:0,inScope:0,outOfScope:0});const We=L.get(f);We.total+=V,De?We.inScope+=V:We.outOfScope+=V});const I=Array.from(L.entries()).map(([i,f],V)=>({name:i,hours:Math.round(f.total*10)/10,inScopeHours:Math.round(f.inScope*10)/10,outOfScopeHours:Math.round(f.outOfScope*10)/10,color:qe[V%qe.length]})).sort((i,f)=>f.hours-i.hours);_(30);const je=N.map(i=>{var f;return{date:i.date,description:i.description_structuree||i.description_brute||(n==="fr"?"Travail effectué":"Work completed"),type:((f=i.task_type)==null?void 0:f.nom)||(n==="fr"?"Autre":"Other"),inScope:i.est_facturable!==!1}}),xe=Rt(N,n),F=Rt($,n).map(i=>{const f=b.startDate,V=b.endDate,De=new Date(i.startDate),kt=new Date(i.endDate)>=f&&De<=V;return{...i,isCurrentPeriod:kt}}),X=[...new Set(N.map(i=>{var f;return(f=i.user)==null?void 0:f.nom}).filter(Boolean))],et=N.reduce((i,f)=>i+f.duree_minutes,0),ke=Math.round(et/60*10)/10,Ae=N.filter(i=>i.est_facturable!==!1).reduce((i,f)=>i+f.duree_minutes,0),Te=Math.round(Ae/60*10)/10,Se=Math.round((ke-Te)*10)/10;_(35);const Ie=await bs(d,b.startDate);let ae=null;if(Ie!==null){const i=Math.round(Ie/60*10)/10,f=Math.round((ke-i)*10)/10,V=i>0?Math.round(f/i*100):0;ae={previousHours:i,hoursDiff:f,hoursPercent:V}}_(40),te(n==="fr"?"Génération du contenu IA...":"Generating AI content...");const Fe=N.map(i=>i.description_structuree||i.description_brute).filter(Boolean).join(` 44- `),a=await Gt(N,o.nom_projet,n,je);_(60),te(n==="fr"?"Vérification des données (double-check)...":"Verifying data (double-check)...");let C=a;try{const{data:i,error:f}=await me.functions.invoke("verify-report-data",{body:{accomplishments:a.accomplishments,recommendations:a.recommendations,professionalDescriptions:a.professionalDescriptions,originalData:{projectName:o.nom_projet,totalEntries:N.length,descriptions:Fe},language:n}});_(75),!f&&i&&(((t=i.verifiedAccomplishments)==null?void 0:t.length)>0&&(C.accomplishments=i.verifiedAccomplishments),((r=i.verifiedRecommendations)==null?void 0:r.length)>0&&(C.recommendations=i.verifiedRecommendations),((s=i.verifiedDescriptions)==null?void 0:s.length)>0&&(C.professionalDescriptions=i.verifiedDescriptions),Je({isValid:i.isValid,confidence:i.confidence,issues:i.issues||[]}),console.log("Verification result:",{isValid:i.isValid,confidence:i.confidence,issues:i.issues}),(!i.isValid||i.confidence<80)&&q.warning(n==="fr"?`â ï¸ Vérification: ${i.confidence}% de confiance. ${((p=i.issues)==null?void 0:p.length)||0} problème(s) détecté(s).`:`â ï¸ Verification: ${i.confidence}% confidence. ${((w=i.issues)==null?void 0:w.length)||0} issue(s) detected.`,{duration:5e3}))}catch(i){console.error("Verification error (non-blocking):",i),Je({isValid:!0,confidence:70,issues:[n==="fr"?"Vérification automatique non disponible":"Automatic verification unavailable"]})}_(85),te(n==="fr"?"Finalisation du rapport...":"Finalizing report...");const Q=i=>{if(!i)return i;const f=C.professionalDescriptions.find(V=>V.original.toLowerCase().includes(i.toLowerCase().substring(0,20))||i.toLowerCase().includes(V.original.toLowerCase().substring(0,20)));return(f==null?void 0:f.professional)||i};_(90);const $e=je.map(i=>({...i,professionalDescription:Q(i.description)})),Be=xe.map(i=>({...i,tasks:i.tasks.map(f=>({...f,description:Q(f.description)}))})),_e=F.map(i=>({...i,tasks:i.tasks.map(f=>({...f,description:Q(f.description)}))})),pt=[{label:g.inScopeHours,value:`${Te}h`,trend:"up",trendValue:`${Math.round(Te/ke*100)}% ${n==="fr"?"du total":"of total"}`},{label:g.outOfScopeHours,value:`${Se}h`,trend:Se>0?"neutral":"up",trendValue:n==="fr"?"Non facturé":"Not billed"},{label:n==="fr"?"Heures totales":"Total Hours",value:`${ke}h`,trend:ae&&ae.hoursDiff>0?"up":ae&&ae.hoursDiff<0?"down":"neutral",trendValue:ae?`${ae.hoursDiff>0?"+":""}${ae.hoursDiff}h ${g.comparison}`:""},{label:g.teamSize,value:`${X.length}`,trend:"neutral",trendValue:X.slice(0,2).join(", ")+(X.length>2?"...":"")}],wt=o.statut==="livré"||o.statut==="clôturé"?"completed":"ongoing",At=$e.map(i=>({date:i.date,description:i.description}
44)),Ce=Lt(At,o.nom_projet,n),ye={projectName:o.nom_projet,clientName:((S=o.client)==null?void 0:S.nom_client)||(n==="fr"?"Client non défini":"Client not defined"),period:b.label,periodKey:b.value,language:n,projectStartDate:o.date_debut,projectEndDate:o.date_fin_cible,projectStatus:wt,totalHours:ke,inScopeHours:Te,outOfScopeHours:Se,hoursBreakdown:I,accomplishments:C.accomplishments,phases:Be,fullProjectPhases:_e,reportPeriodStart:x(b.startDate,"yyyy-MM-dd"),reportPeriodEnd:x(b.endDate,"yyyy-MM-dd"),timeline:$e,teamMembers:X,recommendations:C.recommendations,kpis:pt,comparison:ae,scopeChanges:H,scopeChangeTemplate:Ot[n],risksAndDependencies:o.risques||"",meetings:Y,nextSteps:[],milestones:Ce,timeEntries:N.map(i=>({user:i.user,task_type:i.task_type,duree_minutes:i.duree_minutes}))};G(ye),ee([]),Re(ye.accomplishments),T(ye.recommendations),Ne(ye.risksAndDependencies),nt(ye.phases),Ke(ye.teamMembers),gt(ye.scopeChanges),bt(ye.meetings),vt({start:o.date_debut||"",end:o.date_fin_cible||"",status:wt}),U(!1),_(95);const{data:mt,error:Nt}=await me.from("sbc_generated_reports").insert({projet_id:d,period_start:x(b.startDate,"yyyy-MM-dd"),period_end:x(b.endDate,"yyyy-MM-dd"),language:n,report_data:ye,next_steps:[]}).select().single();Nt?console.error("Error saving report:",Nt):(ce(mt.report_id),k(mt.share_token),dt()),_(100),te(n==="fr"?"Terminé!":"Complete!");const l=He!=null&&He.confidence?` (${He.confidence}% ${n==="fr"?"vérifié":"verified"})`:"";q.success((n==="fr"?"Rapport généré avec succès":"Report generated successfully")+l)}catch(o){console.error("Error generating report:",o),q.error(n==="fr"?"Erreur lors de la génération du rapport":"Error generating report")}finally{O(!1),_(0),te("")}},js=async t=>{var s,p,w;const r=t.language;ct(!0),_(0),te(r==="fr"?"Initialisation du rapport personnalisé...":"Initializing custom report..."),Je(null);try{const S=t.customDateRange?P(t.customDateRange.start):Ue(ft(new Date,1)),o=t.customDateRange?P(t.customDateRange.end):new Date,b=[],N=[],$=t.selectedProjects.length;for(let l=0;l<$;l++){const i=t.selectedProjects[l],f=j.find(De=>De.projet_id===i);f&&N.push(f),_(Math.round(l/$*25)),te(r==="fr"?`Récupération projet ${l+1}/${$}...`:`Fetching project ${l+1}/${$}...`);const V=await Ut(i,S,o);b.push(...V)}if(_(30),b.length===0){q.warning(g.noEntries),ct(!1),_(0),te("");return}te(r==="fr"?"Analyse détaillée de l'équipe...":"Detailed team analysis...");const H=br(b.map(l=>({user:l.user,task_type:l.task_type,duree_minutes:l.duree_minutes})),r),Y=N.map(l=>l.nom_projet),L=t.selectedProjects.length>1?vr(b.map(l=>({user:l.user,task_type:l.task_type,duree_minutes:l.duree_minutes})),Y,r):[];if(_(35),L.length>0&&t.selectedProjects.length>1){const l=b.reduce((V,De)=>V+De.duree_minutes,0),i=Math.round(l/60*10)/10,f=H.map(V=>({name:V.name,hours:V.totalHours,roles:V.roles,projects:Y}));await new Promise(V=>{yt({teamMembers:f,inconsistencies:L,projectNames:Y,totalHours:i,continueGeneration:()=>{jt(!1),yt(null),V()}}),jt(!0)})}const I=t.reportTitle||N.map(l=>l.nom_projet).join(" + "),je=[...new Set(N.map(l=>{var i;return(i=l.client)==null?void 0:i.nom_client}).filter(Boolean))].join(", ")||"Multiple Clients",xe=new Map;b.forEach(l=>{var We;const i=((We=l.task_type)==null?void 0:We.nom)||(r==="fr"?"Autre":"Other"),f=l.duree_minutes/60,V=l.est_facturable!==!1;xe.has(i)||xe.set(i,{total:0,inScope:0,outOfScope:0});const De=xe.get(i);De.total+=f,V?De.inScope+=f:De.outOfScope+=f});const F=Array.from(xe.entries()).map(([l,i],f)=>({name:l,hours:Math.round(i.total*10)/10,inScopeHours:Math.round(i.inScope*10)/10,outOfScopeHours:Math.round(i.outOfScope*10)/10,color:qe[f%qe.length]})).sort((l,i)=>i.hours-l.hours),X=b.map(l=>{var i;return{date:l.date,description:l.description_structuree||l.description_brute||(r==="fr"?"Travail effectué":"Work completed"),type:((i=l.task_type)==null?void 0:i.nom)||(r==="fr"?"Autre":"Other"),inScope:l.est_facturable!==!1}}),et=Rt(b,r),ke=et,Ae=H.map(l=>l.name),Te=b.reduce((l,i)=>l+i.duree_minutes,0),Se=Math.round(Te/60*10)/10,Ie=b.filter(l=>l.est_facturable!==!1).reduce((l,i)=>l+i.duree_minutes,0),ae=Math.round(Ie/60*10)/10,Fe=Math.round((Se-ae)*10)/10;_(40),te(r==="fr"?"Génération du contenu IA...":"Generating AI content...");const a=b.map(l=>
44l.description_structuree||l.description_brute).filter(Boolean).join(` 45- `),C=await Gt(b,I,r,X);_(55),te(r==="fr"?"Vérification rigoureuse (multi-projets)...":"Rigorous verification (multi-project)...");let Q=C;try{const{data:l,error:i}=await me.functions.invoke("verify-report-data",{body:{accomplishments:C.accomplishments,recommendations:C.recommendations,professionalDescriptions:C.professionalDescriptions,originalData:{projectName:I,totalEntries:b.length,descriptions:a,isMultiProject:t.selectedProjects.length>1,projectCount:t.selectedProjects.length},language:r}});_(75),!i&&l&&(((s=l.verifiedAccomplishments)==null?void 0:s.length)>0&&(Q.accomplishments=l.verifiedAccomplishments),((p=l.verifiedRecommendations)==null?void 0:p.length)>0&&(Q.recommendations=l.verifiedRecommendations),((w=l.verifiedDescriptions)==null?void 0:w.length)>0&&(Q.professionalDescriptions=l.verifiedDescriptions),Je({isValid:l.isValid,confidence:l.confidence,issues:l.issues||[]}),console.log("Custom report verification:",{isValid:l.isValid,confidence:l.confidence,issues:l.issues,multiProject:t.selectedProjects.length>1}),(!l.isValid||l.confidence<85)&&q.warning(r==="fr"?`â ï¸ Rapport multi-projets: ${l.confidence}% de confiance. Vérifiez les données.`:`â ï¸ Multi-project report: ${l.confidence}% confidence. Please verify data.`,{duration:6e3}))}catch(l){console.error("Custom report verification error (non-blocking):",l),Je({isValid:!0,confidence:65,issues:[r==="fr"?"Vérification automatique non disponible pour rapport personnalisé":"Automatic verification unavailable for custom report"]})}_(85),te(r==="fr"?"Finalisation...":"Finalizing...");const $e=X.map(l=>{const i=Q.professionalDescriptions.find(f=>f.original.toLowerCase().includes(l.description.toLowerCase().substring(0,20))||l.description.toLowerCase().includes(f.original.toLowerCase().substring(0,20)));return{...l,professionalDescription:(i==null?void 0:i.professional)||l.description}}),Be=[{label:g.inScopeHours,value:`${ae}h`,trend:"up",trendValue:`${Math.round(ae/Se*100)}% ${r==="fr"?"du total":"of total"}`},{label:g.outOfScopeHours,value:`${Fe}h`,trend:Fe>0?"neutral":"up",trendValue:r==="fr"?"Non facturé":"Not billed"},{label:r==="fr"?"Heures totales":"Total Hours",value:`${Se}h`,trend:"neutral",trendValue:`${t.selectedProjects.length} ${r==="fr"?"projets":"projects"}`},{label:g.teamSize,value:`${Ae.length}`,trend:"neutral",trendValue:Ae.slice(0,2).join(", ")+(Ae.length>2?"...":"")}],_e=r==="fr"?pe:de,pt=t.customDateRange?`${x(S,"d MMM",{locale:_e})} - ${x(o,"d MMM yyyy",{locale:_e})}`:`${x(S,"MMMM yyyy",{locale:_e})}`,wt=$e.map(l=>({date:l.date,description:l.description})),At=Lt(wt,I,r),Ce={projectName:I,clientName:je,period:pt,periodKey:"custom",language:r,projectStartDate:x(S,"yyyy-MM-dd"),projectEndDate:x(o,"yyyy-MM-dd"),projectStatus:"ongoing",totalHours:Se,inScopeHours:ae,outOfScopeHours:Fe,hoursBreakdown:F,accomplishments:Q.accomplishments,phases:et,fullProjectPhases:ke,reportPeriodStart:x(S,"yyyy-MM-dd"),reportPeriodEnd:x(o,"yyyy-MM-dd"),timeline:$e,teamMembers:Ae,recommendations:Q.recommendations,kpis:Be,comparison:null,scopeChanges:[],scopeChangeTemplate:Ot[r],risksAndDependencies:"",meetings:[],nextSteps:[],milestones:At,timeEntries:b.map(l=>({user:l.user,task_type:l.task_type,duree_minutes:l.duree_minutes}))};_(90),G(Ce),ee([]),Re(Ce.accomplishments),T(Ce.recommendations),Ne(Ce.risksAndDependencies),nt(Ce.phases),Ke(Ce.teamMembers),gt(Ce.scopeChanges),bt(Ce.meetings),vt({start:x(S,"yyyy-MM-dd"),end:x(o,"yyyy-MM-dd"),status:"ongoing"}),U(!1),_(95);const{data:ye,error:mt}=await me.from("sbc_generated_reports").insert({projet_id:t.selectedProjects[0],period_start:x(S,"yyyy-MM-dd"),period_end:x(o,"yyyy-MM-dd"),language:r,report_data:Ce,next_steps:[]}).select().single();mt?console.error("Error saving custom report:",mt):(ce(ye.report_id),k(ye.share_token),dt()),_(100),Pt(!1);const Nt=He!=null&&He.confidence?` (${He.confidence}% ${r==="fr"?"vérifié":"verified"})`:"";q.success((r==="fr"?"Rapport personnalisé généré!":"Custom report generated!")+Nt)}catch(S){console.error("Error generating custom report:",S),q.error(r==="fr"?"Erreur lors de la génération":"Generation error")}finally{ct(!1),_(0),te("")}},ys=t=>{const r=t;G(r),Re(r.accomplishments||[]),T(r.recommendations||[]),Ne(r.risksAndDependencies||""),nt(r.phases||[]),Ke(r.teamMembers||[]),gt(r.scopeChanges||[]),bt(r.meetings||[]),ee(r.nextSteps||[]),U(!1)},Gt=async(t,r,s,p)=>{try{const w=t.map(N=>
45N.description_structuree||N.description_brute).filter(Boolean).join(` 46- `),S=p.map(N=>({description:N.description})),{data:o,error:b}=await me.functions.invoke("generate-client-report",{body:{projectName:r,descriptions:w,totalEntries:t.length,language:s,timelineItems:S}});if(b)throw b;return{accomplishments:o.accomplishments||[],recommendations:o.recommendations||[],professionalDescriptions:o.professionalDescriptions||[]}}catch(w){console.error("AI content error:",w);const S=new Map;return t.forEach(N=>{var H;const $=((H=N.task_type)==null?void 0:H.nom)||"Work";S.set($,(S.get($)||0)+1)}),{accomplishments:Array.from(S.entries()).sort((N,$)=>$[1]-N[1]).slice(0,5).map(([N,$])=>s==="fr"?`${N}: ${$} session${$>1?"s":""} de travail`:`${N}: ${$} work session${$>1?"s":""}`),recommendations:s==="fr"?["Continuer sur la lancée actuelle","Planifier les prochaines étapes"]:["Continue current momentum","Plan next steps"],professionalDescriptions:[]}}},Kt=()=>v?`https://studentbrains.ai/report/${v}`:"",ws=()=>{const t=Kt();t&&(navigator.clipboard.writeText(t),q.success(g.linkCopied))},Ns=()=>{if(y){le(!0);try{const t={...y,accomplishments:Pe,recommendations:m,risksAndDependencies:ve,phases:Oe,teamMembers:Ge,scopeChanges:ot,meetings:lt,projectStartDate:re.start,projectEndDate:re.end,projectStatus:re.status},r=Ss(t,D),s=new Blob([r],{type:"text/html"}),p=URL.createObjectURL(s);window.open(p,"_blank"),q.success(n==="fr"?"Présentation ouverte!":"Presentation opened!")}catch(t){console.error("Slides export error:",t),q.error(n==="fr"?"Erreur lors de l'export":"Export error")}finally{le(!1)}}},ks=()=>{if(y){A(!0);try{const t={...y,accomplishments:Pe,recommendations:m,risksAndDependencies:ve,phases:Oe,teamMembers:Ge,scopeChanges:ot,meetings:lt,projectStartDate:re.start,projectEndDate:re.end,projectStatus:re.status},r=$s(t,D),s=new Blob([r],{type:"text/html"}),p=URL.createObjectURL(s),w=window.open(p,"_blank");w&&(w.onload=()=>{setTimeout(()=>w.print(),500)}),q.success(n==="fr"?"PDF prêt à imprimer":"PDF ready to print")}catch(t){console.error("PDF export error:",t),q.error(n==="fr"?"Erreur lors de l'export PDF":"PDF export error")}finally{A(!1)}}},Ss=(t,r)=>{var ae,Fe;const s=t.language,p=Ht[s];t.timeline.reduce((a,C)=>{const Q=C.professionalDescription;return a.find($e=>$e.description===Q)||a.push({date:C.date,description:Q,type:C.type,inScope:C.inScope}),a},[]).slice(0,8);const w=t.projectStartDate?P(t.projectStartDate):new Date,S=t.projectEndDate?P(t.projectEndDate):new Date,o=Math.max(Ye(S,w),1),b=t.phases.map((a,C)=>{const Q=a.startDate?P(a.startDate):new Date,$e=a.endDate?P(a.endDate):new Date,Be=Math.max(0,Ye(Q,w)),_e=Math.max(1,Ye($e,Q)+1);return{name:a.name,startPercent:Math.min(100,Be/o*100),widthPercent:Math.min(100-Be/o*100,_e/o*100),color:qe[C%qe.length],hours:a.totalHours,inScope:a.inScopeHours,outOfScope:a.outOfScopeHours}}),N=t.timeline.map(a=>({date:a.date,description:a.description})),H=Lt(N,t.projectName,s).map(a=>{const C=P(a.date),Q=Math.max(0,Ye(C,w));return{...a,position:Math.min(100,Q/o*100)}}),Y=` 47 * { margin: 0; padding: 0; box-sizing: border-box; } 48 body { font-family: 'Inter', -apple-system, sans-serif; background: #0f172a; color: #f8fafc; overflow-x: hidden; } 49 50 .slide { 51 min-height: 100vh; 52 padding: 60px 80px; 53 display: flex; 54 flex-direction: column; 55 page-break-after: always; 56 position: relative; 57 background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); 58 } 59 60 .slide::before { 61 content: ''; 62 position: absolute; 63 top: 0; 64 right: 0; 65 width: 40%; 66 height: 100%; 67 background: linear-gradient(135deg, transparent 0%, rgba(59, 130, 246, 0.05) 100%); 68 pointer-events: none; 69 } 70 71 .slide-number { 72 position: absolute; 73 bottom: 30px; 74 right: 40px; 75 font-size: 14px; 76 color: #64748b; 77 font-weight: 500; 78 } 79 80 .logo { 81 font-size: 14px; 82 font-weight: 600; 83 color: #64748b; 84 letter-spacing: 2px; 85 text-transform: uppercase; 86 margin-bottom: 40px; 87 } 88 89 .title-slide { 90 justify-content: center; 91 align-items: center; 92 text-align: center; 93 background: linear-gradient(135deg, #1e40af 0%, #3b82f6 50%, #0ea5e9 100%); 94 } 95 96 .title-slide .client-badge { 97 background: rgba(255,255,255,0.15); 98 backdrop-filter: blur(10px); 99 padding: 8px 24px; 100 border-radius: 30px; 101 font-size: 14px; 102 font-weight: 500; 103 margin-bottom: 24px; 104 border: 1px solid rgba(255,255,255,0.2); 105 } 106 107 .title-slide h1 { 108 font-size: 64px; 109 font-weight: 800; 110 line-height: 1.1; 111 margin-bottom: 16px; 112 text-shadow: 0 4px 30px rgba(0,0,0,0.3); 113 } 114 115 .title-slide .subtitle { font-size: 24px; opacity: 0.9; font-weight: 500; margin-bottom: 20px; } 116 .title-slide .project-dates { 117 font-size: 18px; 118 opacity: 0.85; 119 margin-bottom: 30px; 120 display: flex; 121 align-items: center; 122 justify-content: center; 123 gap: 20px; 124 } 125 .title-slide .date-badge { 126 background: rgba(255,255,255,0.1); 127 padding: 8px 16px; 128 border-radius: 8px; 129 display: flex; 130 align-items: center; 131 gap: 8px; 132 } 133 .title-slide .meta-row { display: flex; gap: 40px; font-size: 18px; opacity: 0.85; } 134 .title-slide .meta-row span { display: flex; align-items: center; gap: 8px; } 135 136 .slide-header { margin-bottom: 50px; } 137 .slide-header h2 { 138 font-size: 42px; 139 font-weight: 700; 140 color: #f8fafc; 141 display: flex; 142 align-items: center; 143 gap: 16px; 144 } 145 .slide-header h2 .icon { 146 width: 52px; 147 height: 52px; 148 border-radius: 14px; 149 display: flex; 150 align-items: center; 151 justify-content: center; 152 font-size: 26px; 153 } 154 155 .icon-blue { background: linear-gradient(135deg, #3b82f6, #2563eb); } 156 .icon-green { background: linear-gradient(135deg, #22c55e, #16a34a); } 157 .icon-amber { background: linear-gradient(135deg, #f59e0b, #d97706); } 158 .icon-purple { background: linear-gradient(135deg, #8b5cf6, #7c3aed); } 159 .icon-cyan { background: linear-gradient(135deg, #06b6d4, #0891b2); } 160 .icon-red { background: linear-gradient(135deg, #ef4444, #dc2626); } 161 162 .kpi-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 30px; flex: 1; align-content: center; } 163 .kpi-card { 164 background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.03)); 165 backdrop-filter: blur(10px); 166 border: 1px solid rgba(255,255,255,0.1); 167 border-radius: 20px; 168 padding: 36px; 169 position: relative; 170 overflow: hidden; 171 } 172 .kpi-card::before { 173 content: ''; 174 position: absolute; 175 top: 0; 176 left: 0; 177 width: 4px; 178 height: 100%; 179 background: linear-gradient(180deg, #3b82f6, #8b5cf6); 180 } 181 .kpi-label { font-size: 14px; text-transform: uppercase; letter-spacing: 1.5px; color: #94a3b8; font-weight: 600; margin-bottom: 12px; } 182 .kpi-value { font-size: 48px; font-weight: 800; color: #f8fafc; line-height: 1; margin-bottom: 8px; } 183 .kpi-trend { font-size: 16px; color: #64748b; } 184 185 .content-list { list-style: none; flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 24px; } 186 .content-list li { display: flex; align-items: flex-start; gap: 20px; font-size: 22px; line-height: 1.5; color: #e2e8f0; } 187 .content-list .bullet { 188 width: 36px; 189 height: 36px; 190 border-radius: 10px; 191 display: flex; 192 align-items: center; 193 justify-content: center; 194 font-size: 18px; 195 flex-shrink: 0; 196 margin-top: 2px; 197 } 198 .bullet-green { background: rgba(34, 197, 94, 0.2); color: #22c55e; } 199 .bullet-amber { background: rgba(245, 158, 11, 0.2); color: #f59e0b; } 200 .bullet-blue { background: rgba(59, 130, 246, 0.2); color: #3b82f6; } 201 .bullet-red { background: rgba(239, 68, 68, 0.2); color: #ef4444; } 202 .bullet-purple { background: rgba(139, 92, 246, 0.2); color: #8b5cf6; } 203
204 .chart-container { flex: 1; display: flex; align-items: center; justify-content: center; } 205 .breakdown-table { width: 100%; max-width: 900px; } 206 .breakdown-row { display: flex; align-items: center; padding: 16px 0; border-bottom: 1px solid rgba(255,255,255,0.1); } 207 .breakdown-row:last-child { border-bottom: none; } 208 .breakdown-name { flex: 1; font-size: 18px; font-weight: 500; } 209 .breakdown-bar-container { flex: 2; height: 24px; background: rgba(255,255,255,0.05); border-radius: 6px; overflow: hidden; margin: 0 20px; display: flex; } 210 .breakdown-bar { height: 100%; transition: width 0.5s ease; } 211 .breakdown-bar.in-scope { opacity: 1; } 212 .breakdown-bar.out-of-scope { opacity: 0.5; } 213 .breakdown-values { width: 140px; text-align: right; font-size: 14px; } 214 .breakdown-values .in-scope { color: #22c55e; font-weight: 600; } 215 .breakdown-values .out-of-scope { color: #94a3b8; } 216 217 .team-grid { display: flex; flex-wrap: wrap; gap: 16px; justify-content: center; align-items: center; flex: 1; } 218 .team-member { background: linear-gradient(135deg, rgba(99, 102, 241, 0.2), rgba(139, 92, 246, 0.2)); border: 1px solid rgba(139, 92, 246, 0.3); padding: 16px 32px; border-radius: 40px; font-size: 18px; font-weight: 500; } 219 220 .phases-container { flex: 1; display: flex; flex-direction: column; gap: 24px; } 221 .phase-card { 222 background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.03)); 223 border: 1px solid rgba(255,255,255,0.1); 224 border-radius: 16px; 225 padding: 24px; 226 } 227 .phase-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } 228 .phase-name { font-size: 20px; font-weight: 600; color: #f8fafc; } 229 .phase-hours { font-size: 16px; color: #94a3b8; } 230 .phase-hours .in-scope { color: #22c55e; } 231 .phase-dates { font-size: 14px; color: #64748b; } 232 .task-list { display: flex; flex-direction: column; gap: 8px; } 233 .task-item { 234 display: flex; 235 align-items: center; 236 gap: 12px; 237 padding: 8px 12px; 238 background: rgba(255,255,255,0.03); 239 border-radius: 8px; 240 font-size: 14px; 241 } 242 .task-item.in-scope { border-left: 3px solid #22c55e; } 243 .task-item.out-of-scope { border-left: 3px solid #64748b; opacity: 0.7; } 244 .task-date { color: #64748b; width: 60px; } 245 .task-desc { flex: 1; color: #e2e8f0; } 246 .task-hours { color: #94a3b8; } 247 248 .gantt-container { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 20px; padding: 20px 0; } 249 .gantt-header { display: flex; justify-content: space-between; font-size: 12px; color: #64748b; padding: 0 0 10px 200px; } 250 .gantt-row { display: flex; align-items: center; gap: 16px; } 251 .gantt-label { width: 200px; font-size: 14px; font-weight: 500; color: #e2e8f0; } 252 .gantt-bar-container { flex: 1; height: 32px; background: rgba(255,255,255,0.05); border-radius: 6px; position: relative; } 253 .gantt-bar { 254 position: absolute; 255 height: 100%; 256 border-radius: 6px; 257 display: flex; 258 align-items: center; 259 padding: 0 10px; 260 font-size: 12px; 261 font-weight: 500; 262 color: white; 263 text-shadow: 0 1px 2px rgba(0,0,0,0.3); 264 } 265 .gantt-info { width: 100px; text-align: right; font-size: 12px; color: #94a3b8; } 266 267 .scope-framework { flex: 1; display: flex; flex-direction: column; gap: 16px; } 268 .scope-template-item { 269 background: linear-gradient(135deg, rgba(245, 158, 11, 0.1), rgba(245, 158, 11, 0.05)); 270 border: 1px solid rgba(245, 158, 11, 0.2); 271 border-radius: 12px; 272 padding: 20px; 273 } 274 .scope-template-type { font-size: 18px; font-weight: 600; color: #f59e0b; margin-bottom: 8px; } 275 .scope-template-desc { font-size: 16px; color: #e2e8f0; margin-bottom: 8px; } 276 .scope-template-implications { font-size: 14px; color: #94a3b8; } 277 278 .scope-list { flex: 1; display: flex; flex-direction: column; gap: 16px; overflow-y: auto; } 279 .scope-item { background: rgba(255,255,255,0.05); padding: 20px; border-radius: 12px; border-left: 4px solid #f59e0b; } 280 .scope-item .date { font-size: 12px; color: #64748b; margin-bottom: 4px; } 281 .scope-item .desc { font-size: 18px; color: #e2e8f0; margin-bottom: 8px; } 282 .scope-item .meta { font-size: 14px; color: #94a3b8; } 283 284 .meeting-list { flex: 1; display: flex; flex-direction: column; gap: 16px; overflow-y: auto; } 285 .meeting-item { background: rgba(255,255,255,0.05); padding: 20px; border-radius: 12px; border-left: 4px solid #8b5cf6; } 286 .meeting-item .date { font-size: 12px; color: #64748b; margin-bottom: 4px; } 287 .meeting-item .title { font-size: 20px; color: #e2e8f0; font-weight: 600; } 288 .meeting-item .notes { font-size: 16px; color: #94a3b8; margin-top: 8px; } 289 290 .slide-footer { position: absolute; bottom: 30px; left: 80px; font-size: 14px; color: #64748b; } 291 292 .thank-you { justify-content: center; align-items: center; text-align: center; background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%); } 293 .thank-you h2 { 294 font-size: 56px; 295 font-weight: 800; 296 margin-bottom: 24px; 297 background: linear-gradient(135deg, #3b82f6, #8b5cf6, #06b6d4); 298 -webkit-background-clip: text; 299 -webkit-text-fill-color: transparent; 300 background-clip: text; 301 } 302 .thank-you p { font-size: 20px; color: #94a3b8; } 303 304 .empty-state { font-size: 20px; color: #64748b; font-style: italic; text-align: center; padding: 40px; } 305 306 .legend { display: flex; gap: 24px; margin-top: 20px; justify-content: center; } 307 .legend-item { display: flex; align-items: center; gap: 8px; font-size: 14px; color: #94a3b8; } 308 .legend-dot { width: 12px; height: 12px; border-radius: 3px; } 309 .legend-dot.in-scope { background: #22c55e; } 310 .legend-dot.out-of-scope { background: #64748b; } 311 312 @media print { .slide { page-break-after: always; } body { background: white; } } 313 `;let L=1;const I=[],je=t.projectStartDate?x(P(t.projectStartDate),"d MMM yyyy",{locale:s==="fr"?pe:de}):"â",xe=t.projectStatus==="ongoing"?s==="fr"?"En cours":"Ongoing":t.projectEndDate?x(P(t.projectEndDate),"d MMM yyyy",{locale:s==="fr"?pe:de}):"â",F=((Fe=(ae=j.find(a=>a.projet_id===d))==null?void 0:ae.client)==null?void 0:Fe.nom_client)||"",X=$r(t.projectName,F,s);I.push(` 314<div class="slide title-slide"> 315 <div class="client-badge">${t.clientName}</div> 316 <h1>${t.projectName}</h1> 317 <div class="subtitle">${p.monthlyReport}</div> 318 <div class="project-objective" style="background: rgba(255,255,255,0.1); padding: 12px 24px; border-radius: 12px; margin: 16px 0; font-size: 18px; max-width: 600px;"> 319 ð¯ ${X} 320 </div> 321 <div class="project-dates"> 322 <div class="date-badge"> 323 ð ${s==="fr"?"Début":"Start"}: ${je} 324 </div> 325 <div class="date-badge"> 326 ð¯ ${s==="fr"?"Fin":"End"}: ${xe} 327 </div> 328 </div> 329 <div class="meta-row"> 330 <span>ð ${t.period}</span> 331 </div> 332 <div class="slide-number">${L++}
332</div> 333</div>`),I.push(` 334<div class="slide"> 335 <div class="logo">STUDENTBRAINS CONSULTING</div> 336 <div class="slide-header"> 337 <h2><span class="icon icon-blue">ð</span> ${p.kpis}</h2> 338 </div> 339 <div class="kpi-grid"> 340 ${t.kpis.map(a=>` 341 <div class="kpi-card"> 342 <div class="kpi-label">${a.label}</div> 343 <div class="kpi-value">${a.value}</div> 344 <div class="kpi-trend">${a.trendValue}</div> 345 </div> 346 `).join("")} 347 </div> 348 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 349 <div class="slide-number">${L++}</div> 350</div>`),I.push(` 351<div class="slide"> 352 <div class="logo">STUDENTBRAINS CONSULTING</div> 353 <div class="slide-header"> 354 <h2><span class="icon icon-cyan">ð</span> ${p.phases}</h2> 355 </div> 356 <div class="phases-container"> 357 ${t.phases.map(a=>` 358 <div class="phase-card"> 359 <div class="phase-header"> 360 <div> 361 <div class="phase-name">${a.name}</div> 362 <div class="phase-dates">${a.startDate?x(P(a.startDate),"d MMM",{locale:s==="fr"?pe:de}):""} - ${a.endDate?x(P(a.endDate),"d MMM",{locale:s==="fr"?pe:de}):""}</div> 363 </div> 364 <div class="phase-hours"> 365 <span class="in-scope">${a.inScopeHours}h</span> in scope / ${a.outOfScopeHours}h out 366 </div> 367 </div> 368 <div class="task-list"> 369 ${a.tasks.slice(0,4).map(C=>` 370 <div class="task-item ${C.inScope?"in-scope":"out-of-scope"}"> 371 <span class="task-date">${x(P(C.date),"d/M",{locale:s==="fr"?pe:de})}</span> 372 <span class="task-desc">${C.description.substring(0,60)}${C.description.length>60?"...":""}</span> 373 <span class="task-hours">${C.hours}h</span> 374 </div> 375 `).join("")} 376 ${a.tasks.length>4?`<div style="font-size: 14px; color: #64748b; padding: 8px 12px;">+${a.tasks.length-4} ${s==="fr"?"autres tâches":"more tasks"}...</div>`:""} 377 </div> 378 </div> 379 `).join("")} 380 </div> 381 <div class="legend"> 382 <div class="legend-item"><div class="legend-dot in-scope"></div> In Scope (${s==="fr"?"facturé":"billed"})</div> 383 <div class="legend-item"><div class="legend-dot out-of-scope"></div> Out of Scope (${s==="fr"?"non facturé":"not billed"})</div> 384 </div> 385 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 386 <div class="slide-number">${L++}</div> 387</div>`),I.push(` 388<div class="slide"> 389 <div class="logo">STUDENTBRAINS CONSULTING</div> 390 <div class="slide-header"> 391 <h2><span class="icon icon-purple">ð</span> ${p.ganttChart}</h2> 392 </div> 393 <div class="gantt-container"> 394 <div class="gantt-header"> 395 <span>${je}</span> 396 <span>${xe}</span> 397 </div> 398 <!-- Milestones row --> 399 <div class="gantt-row" style="margin-bottom: 16px;"> 400 <div class="gantt-label" style="font-size: 12px; color: #64748b;">${s==="fr"?"Jalons":"Milestones"}</div> 401 <div class="gantt-bar-container" style="background: transparent; position: relative;"> 402 ${H.map(a=>` 403 <div style="position: absolute; left: ${a.position}%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center;"> 404 <div style="width: 24px; height: 24px; background: ${a.type==="kickoff"?"#22c55e":a.type==="launch"?"#3b82f6":a.type==="version"?"#8b5cf6":"#f59e0b"}; border-radius: 50%; display: flex; align-items: center; justify-content: center;"> 405 <span style="color: white; font-size: 10px;">ð©</span> 406 </div> 407 <div style="font-size: 10px; color: #94a3b8; margin-top: 4px; white-space: nowrap; max-width: 80px; overflow: hidden; text-overflow: ellipsis;">${a.label}</div> 408 </div> 409 `).join("")} 410 </div> 411 <div class="gantt-info"></div> 412 </div> 413 ${b.map((a,C)=>` 414 <div class="gantt-row"> 415 <div class="gantt-label">${a.name}</div> 416 <div class="gantt-bar-container"> 417 <div class="gantt-bar" style="left: ${a.startPercent}%; width: ${Math.max(a.widthPercent,5)}%; background: ${a.color};"> 418 ${a.hours}h 419 </div> 420 </div> 421 <div class="gantt-info"> 422 <div style="color: #22c55e">${a.inScope}h in</div> 423 <div>${a.outOfScope}h out</div> 424 </div> 425 </div> 426 `).join("")} 427 </div> 428 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 429 <div class="slide-number">${L++}
429</div> 430</div>`),I.push(` 431<div class="slide"> 432 <div class="logo">STUDENTBRAINS CONSULTING</div> 433 <div class="slide-header"> 434 <h2><span class="icon icon-cyan">ð</span> ${s==="fr"?"Phases du Projet":"Project Phases"}</h2> 435 </div> 436 <div style="flex: 1; overflow: auto;"> 437 <table class="phases-table" style="width: 100%; border-collapse: collapse; font-size: 14px;"> 438 <thead> 439 <tr style="background: rgba(255,255,255,0.1); text-align: left;"> 440 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Phase</th> 441 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Tâches clés":"Key Tasks"}</th> 442 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Status</th> 443 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Owner</th> 444 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">In Scope</th> 445 </tr> 446 </thead> 447 <tbody> 448 ${t.phases.map((a,C)=>{const Q=a.tasks.slice(0,2).map(pt=>pt.description.substring(0,40)).join(", "),$e=a.tasks.length>0&&a.tasks[0].type||"Team",Be=a.isCurrentPeriod?s==="fr"?"En cours":"In Progress":s==="fr"?"Terminé":"Completed",_e=a.isCurrentPeriod?"#22c55e":"#64748b";return` 449 <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);"> 450 <td style="padding: 12px; font-weight: 500;">${a.name}</td> 451 <td style="padding: 12px; color: #94a3b8; font-size: 13px;">${Q||"â"}</td> 452 <td style="padding: 12px;"><span style="background: ${_e}22; color: ${_e}; padding: 4px 8px; border-radius: 4px; font-size: 12px;">${Be}</span></td> 453 <td style="padding: 12px; color: #e2e8f0;">${$e}</td> 454 <td style="padding: 12px;"><span style="color: #22c55e;">${a.inScopeHours}h</span> / <span style="color: #64748b;">${a.outOfScopeHours}h</span></td> 455 </tr> 456 `}).join("")} 457 </tbody> 458 </table> 459 </div> 460 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 461 <div class="slide-number">${L++}</div> 462</div>`),I.push(` 463<div class="slide"> 464 <div class="logo">STUDENTBRAINS CONSULTING</div> 465 <div class="slide-header"> 466 <h2><span class="icon icon-blue">â±ï¸</span> ${p.timeBreakdown}</h2> 467 </div> 468 <div class="chart-container"> 469 <div class="breakdown-table"> 470 ${t.hoursBreakdown.map(a=>` 471 <div class="breakdown-row"> 472 <div class="breakdown-name">${a.name}</div> 473 <div class="breakdown-bar-container"> 474 <div class="breakdown-bar in-scope" style="width: ${a.inScopeHours/t.totalHours*100}%; background: ${a.color};"></div> 475 <div class="breakdown-bar out-of-scope" style="width: ${a.outOfScopeHours/t.totalHours*100}%; background: ${a.color};"></div> 476 </div> 477 <div class="breakdown-values"> 478 <div class="in-scope">${a.inScopeHours}h in</div> 479 <div class="out-of-scope">${a.outOfScopeHours}h out</div> 480 </div> 481 </div> 482 `).join("")} 483 </div> 484 </div> 485 <div class="legend"> 486 <div class="legend-item"><div class="legend-dot in-scope"></div> In Scope</div> 487 <div class="legend-item"><div class="legend-dot out-of-scope"></div> Out of Scope</div> 488 </div> 489 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 490 <div class="slide-number">${L++}</div> 491</div>`),I.push(` 492<div class="slide"> 493 <div class="logo">STUDENTBRAINS CONSULTING</div> 494 <div class="slide-header"> 495 <h2><span class="icon icon-amber">â¡</span> ${p.scopeChanges}</h2> 496 </div> 497 <div style="flex: 1; overflow: auto;"> 498 <table style="width: 100%; border-collapse: collapse; font-size: 14px;"> 499 <thead> 500 <tr style="background: rgba(255,255,255,0.1); text-align: left;"> 501 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Date</th> 502 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Demandé par":"Requested By"}</th> 503 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Description</th> 504 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Impact</th> 505 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Décision":"Decision"}</th> 506 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Status</th> 507 </tr> 508 </thead> 509 <tbody> 510 ${t.scopeChanges.length>0?t.scopeChanges.slice(0,5).map(a=>` 511 <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);"> 512 <td style="padding: 12px; color: #94a3b8;">${x(P(a.date),"d MMM",{locale:s==="fr"?pe:de})}</td> 513 <td style="padding: 12px;">${a.requested_by}</td> 514 <td style="padding: 12px; max-width: 200px;">${a.description.substring(0,50)}${a.description.length>50?"...":""}</td> 515 <td style="padding: 12px; color: #f59e0b;">${a.impact_hours?`${a.impact_hours}h`:a.impact_scope||"â"}</td> 516 <td style="padding: 12px; color: #94a3b8;">${a.decision||"â"}</td> 517 <td style="padding: 12px;"><span style="background: ${a.status==="approved"?"#22c55e22":a.status==="pending"?"#f59e0b22":"#64748b22"}; color: ${a.status==="approved"?"#22c55e":a.status==="pending"?"#f59e0b":"#64748b"}; padding: 4px 8px; border-radius: 4px; font-size: 12px;">${a.status}</span></td> 518 </tr> 519 `).join(""):` 520 <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);"> 521 <td colspan="6" style="padding: 24px; text-align: center; color: #64748b; font-style: italic;">${p.nothingForNow}</td> 522 </tr> 523 `} 524 </tbody> 525 </table> 526 </div> 527 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 528 <div class="slide-number">${L++}
528</div> 529</div>`);const et=Cr(t.projectName,s);I.push(` 530<div class="slide"> 531 <div class="logo">STUDENTBRAINS CONSULTING</div> 532 <div class="slide-header"> 533 <h2><span class="icon icon-red">â ï¸</span> ${p.risksAndDependencies}</h2> 534 </div> 535 <div style="flex: 1; overflow: auto;"> 536 <table style="width: 100%; border-collapse: collapse; font-size: 14px;"> 537 <thead> 538 <tr style="background: rgba(255,255,255,0.1); text-align: left;"> 539 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Type</th> 540 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Description</th> 541 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Sévérité":"Severity"}</th> 542 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Impact</th> 543 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Mitigation</th> 544 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Owner</th> 545 </tr> 546 </thead> 547 <tbody> 548 ${et.map(a=>` 549 <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);"> 550 <td style="padding: 12px; font-weight: 500; color: #ef4444;">${a.type}</td> 551 <td style="padding: 12px; max-width: 180px;">${a.description}</td> 552 <td style="padding: 12px;"><span style="background: ${a.severity==="Medium"||a.severity==="Moyenne"?"#f59e0b22":"#22c55e22"}; color: ${a.severity==="Medium"||a.severity==="Moyenne"?"#f59e0b":"#22c55e"}; padding: 4px 8px; border-radius: 4px; font-size: 12px;">${a.severity}</span></td> 553 <td style="padding: 12px; color: #94a3b8; font-size: 13px;">${a.impact}</td> 554 <td style="padding: 12px; color: #94a3b8; font-size: 13px;">${a.mitigation}</td> 555 <td style="padding: 12px;">${a.owner}</td> 556 </tr> 557 `).join("")} 558 </tbody> 559 </table> 560 </div> 561 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 562 <div class="slide-number">${L++}</div> 563</div>`),I.push(` 564<div class="slide"> 565 <div class="logo">STUDENTBRAINS CONSULTING</div> 566 <div class="slide-header"> 567 <h2><span class="icon icon-purple">ð¬</span> ${p.meetingLogs}</h2> 568 </div> 569 <div style="flex: 1; overflow: auto;"> 570 <table style="width: 100%; border-collapse: collapse; font-size: 14px;"> 571 <thead> 572 <tr style="background: rgba(255,255,255,0.1); text-align: left;"> 573 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">Date</th> 574 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Participants":"Attendees"}</th> 575 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Points clés":"Key Discussion Points"}</th> 576 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Décisions":"Decisions Made"}</th> 577 <th style="padding: 12px; border-bottom: 2px solid rgba(255,255,255,0.2);">${s==="fr"?"Prochaines étapes":"Next Steps"}</th> 578 </tr> 579 </thead> 580 <tbody> 581 ${t.meetings.length>0?t.meetings.slice(0,5).map(a=>` 582 <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);"> 583 <td style="padding: 12px; color: #94a3b8;">${x(P(a.date),"d MMM",{locale:s==="fr"?pe:de})}</td> 584 <td style="padding: 12px;">${s==="fr"?"Ãquipe SBC, Client":"SBC Team, Client"}</td> 585 <td style="padding: 12px; max-width: 200px;">${a.titre||"â"}</td> 586 <td style="padding: 12px; color: #94a3b8;">${a.notes?a.notes.substring(0,40)+(a.notes.length>40?"...":""):"â"}</td> 587 <td style="padding: 12px; color: #94a3b8;">â</td> 588 </tr> 589 `).join(""):` 590 <tr style="border-bottom: 1px solid rgba(255,255,255,0.1);"> 591 <td colspan="5" style="padding: 24px; text-align: center; color: #64748b; font-style: italic;">${p.nothingForNow}</td> 592 </tr> 593 `} 594 </tbody> 595 </table> 596 </div> 597 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 598 <div class="slide-number">${L++}
598</div> 599</div>`),I.push(` 600<div class="slide"> 601 <div class="logo">STUDENTBRAINS CONSULTING</div> 602 <div class="slide-header"> 603 <h2><span class="icon icon-blue">ð¯</span> ${p.nextSteps}</h2> 604 </div> 605 ${r.length>0?` 606 <ul class="content-list"> 607 ${r.map((a,C)=>` 608 <li> 609 <span class="bullet bullet-blue">${C+1}</span> 610 <span>${a}</span> 611 </li> 612 `).join("")} 613 </ul> 614 `:`<div class="empty-state">${p.nothingForNow}</div>`} 615 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 616 <div class="slide-number">${L++}</div> 617</div>`);const ke=jr(t.timeEntries||[],t.clientName,s),Ae=ke.filter(a=>a.category==="supervision"),Te=ke.filter(a=>a.category==="execution"),Se=ke.filter(a=>a.category==="client"),Ie=a=>{const C=yr(a.category);return` 618 <div style="background: ${C.gradient}; border: 1px solid ${C.border}; padding: 20px; border-radius: 16px; text-align: center;"> 619 <div style="font-size: 18px; font-weight: 600; color: #f8fafc; margin-bottom: 4px;">${a.name}</div> 620 <div style="font-size: 14px; color: #94a3b8;">${a.role}</div> 621 </div> 622 `};return I.push(` 623<div class="slide"> 624 <div class="logo">STUDENTBRAINS CONSULTING</div> 625 <div class="slide-header"> 626 <h2><span class="icon icon-purple">ð¥</span> ${s==="fr"?"Stakeholders & Ãquipe":"Stakeholders & Team"}</h2> 627 </div> 628 <div style="display: flex; flex-direction: column; gap: 24px; flex: 1;"> 629 ${Ae.length>0?` 630 <div> 631 <div style="font-size: 12px; font-weight: 600; color: #a78bfa; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 12px;">${zt("supervision",s)}</div> 632 <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px;"> 633 ${Ae.map(Ie).join("")} 634 </div> 635 </div> 636 `:""} 637 ${Te.length>0?` 638 <div> 639 <div style="font-size: 12px; font-weight: 600; color: #818cf8; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 12px;">${zt("execution",s)}</div> 640 <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px;"> 641 ${Te.map(Ie).join("")} 642 </div> 643 </div> 644 `:""} 645 ${Se.length>0?` 646 <div> 647 <div style="font-size: 12px; font-weight: 600; color: #38bdf8; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 12px;">${zt("client",s)}</div> 648 <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px;"> 649 ${Se.map(Ie).join("")} 650 </div> 651 </div> 652 `:""} 653 </div> 654 <div class="slide-footer">${t.projectName} ⢠${t.period}</div> 655 <div class="slide-number">${L++}</div> 656</div>`),I.push(` 657<div class="slide thank-you"> 658 <h2>${s==="fr"?"Merci":"Thank You"}</h2> 659 <p>StudentBrains Consulting ⢠${x(new Date,"MMMM yyyy",{locale:s==="fr"?pe:de})}</p> 660 <div class="slide-number">${L}</div> 661</div>`),`<!DOCTYPE html> 662<html lang="${s}"> 663<head> 664 <meta charset="UTF-8"> 665 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 666 <title>${p.monthlyReport} - ${t.projectName}</title> 667 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"> 668 <style>${Y}</style> 669</head> 670<body> 671${I.join(` 672`)} 673</body> 674</html>`},$s=(t,r)=>{const s=t.language,p=Ht[s],w=t.projectStartDate?x(P(t.projectStartDate),"d MMM yyyy",{locale:s==="fr"?pe:de}):"â",S=t.projectStatus==="ongoing"?s==="fr"?"En cours":"Ongoing":t.projectEndDate?x(P(t.projectEndDate),"d MMM yyyy",{locale:s==="fr"?pe:de}):"â";return` 675<!DOCTYPE html> 676<html lang="${s}"> 677<head> 678 <meta charset="UTF-8"> 679 <title>${p.monthlyReport} - ${t.projectName}</title> 680 <style> 681 @page { size: A4; margin: 2cm; } 682 body { font-family: 'Segoe UI', Tahoma, sans-serif; color: #1e293b; line-height: 1.6; } 683 .header { background: linear-gradient(135deg, #2563eb, #1d4ed8); color: white; padding: 2rem; border-radius: 8px; margin-bottom: 2rem; } 684 .header h1 { margin: 0 0 0.5rem 0; font-size: 1.75rem; } 685 .header p { margin: 0; opacity: 0.9; } 686 .meta { display: flex; gap: 2rem; margin-top: 1rem; font-size: 0.875rem; flex-wrap: wrap; } 687 .project-dates { display: flex; gap: 1rem; margin-top: 1rem; } 688 .date-box { background: rgba(255,255,255,0.15); padding: 0.5rem 1rem; border-radius: 6px; } 689 .section { margin-bottom: 2rem; page-break-inside: avoid; } 690 .section-title { font-size: 1.25rem; font-weight: 600; color: #1e40af; margin-bottom: 1rem; border-bottom: 2px solid #dbeafe; padding-bottom: 0.5rem; } 691 .kpis { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; } 692 .kpi { background: #f8fafc; padding: 1rem; border-radius: 8px; border-left: 4px solid #2563eb; } 693 .kpi-label { font-size: 0.75rem; color: #64748b; text-transform: uppercase; } 694 .kpi-value { font-size: 1.5rem; font-weight: 700; color: #1e293b; } 695 .kpi-trend { font-size: 0.875rem; color: #64748b; } 696 .accomplishments li, .recommendations li, .nextsteps li { margin-bottom: 0.75rem; padding-left: 0.5rem; } 697 .accomplishments li::marker { color: #22c55e; } 698 .recommendations li::marker { color: #f59e0b; } 699 .nextsteps li::marker { color: #3b82f6; } 700 .breakdown-table { width: 100%; border-collapse: collapse; } 701 .breakdown-table th, .breakdown-table td { padding: 0.75rem; text-align: left; border-bottom: 1px solid #e2e8f0; } 702 .breakdown-table th { background: #f1f5f9; font-weight: 600; } 703 .in-scope { color: #22c55e; } 704 .out-of-scope { color: #64748b; } 705 .team { display: flex; flex-wrap: wrap; gap: 0.5rem; } 706 .team-member { background: #e0e7ff; color: #3730a3; padding: 0.25rem 0.75rem; border-radius: 9999px; font-size: 0.875rem; } 707 .footer { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #e2e8f0; text-align: center; color: #94a3b8; font-size: 0.75rem; } 708 .phase-card { background: #f8fafc; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; border-left: 4px solid #3b82f6; } 709 .phase-header { display: flex; justify-content: space-between; margin-bottom: 0.5rem; } 710 .phase-name { font-weight: 600; color: #1e293b; } 711 .phase-hours { font-size: 0.875rem; color: #64748b; } 712 .task-list { font-size: 0.875rem; } 713 .task-item { padding: 0.25rem 0; display: flex; gap: 0.5rem; } 714 .task-item.in-scope { color: #1e293b; } 715 .task-item.out-of-scope { color: #94a3b8; } 716 .scope-item, .meeting-item { background: #f8fafc; padding: 1rem; border-radius: 8px; margin-bottom: 0.5rem; border-left: 3px solid #f59e0b; } 717 .meeting-item { border-left-color: #8b5cf6; } 718 .empty-state { color: #94a3b8; font-style: italic; padding: 1rem; text-align: center; } 719 .scope-template { background: #fffbeb; border: 1px solid #fde68a; padding: 1rem; border-radius: 8px; margin-bottom: 0.5rem; } 720 .scope-template-type { font-weight: 600; color: #b45309; } 721 .gantt-container { margin: 1rem 0; } 722 .gantt-row { display: flex; align-items: center; margin: 0.5rem 0; } 723 .gantt-label { width: 150px; font-size: 0.75rem; } 724 .gantt-bar-bg { flex: 1; height: 20px; background: #e2e8f0; border-radius: 4px; position: relative; } 725 .gantt-bar { position: absolute; height: 100%; border-radius: 4px; font-size: 0.625rem; color: white; display: flex; align-items: center; padding: 0 4px; } 726 </style> 727</head> 728<body> 729 <div class="header"> 730 <p style="font-size: 0.875rem; opacity: 0.8;">${p.monthlyReport}</p> 731 <h1>${t.projectName}</h1> 732 <p>${t.clientName}</p> 733 <div class="project-dates"> 734 <div class="date-box">ð ${s==="fr"?"Début":"Start"}: ${w}</div> 735 <div class="date-box">ð¯ ${s==="fr"?"Fin":"End"}: ${S}</div> 736 </div> 737 <div class="meta">
738 <span>ð ${t.period}</span> 739 <span>â±ï¸ ${t.totalHours}h total</span> 740 <span>â ${t.inScopeHours}h in scope</span> 741 <span>⪠${t.outOfScopeHours}h out of scope</span> 742 </div> 743 </div> 744 745 <div class="section"> 746 <h2 class="section-title">${p.kpis}</h2> 747 <div class="kpis"> 748 ${t.kpis.map(o=>` 749 <div class="kpi"> 750 <div class="kpi-label">${o.label}</div> 751 <div class="kpi-value">${o.value}</div> 752 <div class="kpi-trend">${o.trendValue}</div> 753 </div> 754 `).join("")} 755 </div> 756 </div> 757 758 <div class="section"> 759 <h2 class="section-title">${p.phases}</h2> 760 ${t.phases.map(o=>` 761 <div class="phase-card"> 762 <div class="phase-header"> 763 <span class="phase-name">${o.name}</span> 764 <span class="phase-hours"><span class="in-scope">${o.inScopeHours}h</span> in / ${o.outOfScopeHours}h out</span> 765 </div> 766 <div class="task-list"> 767 ${o.tasks.slice(0,5).map(b=>` 768 <div class="task-item ${b.inScope?"in-scope":"out-of-scope"}"> 769 <span>${b.date}</span> 770 <span>${b.description.substring(0,50)}${b.description.length>50?"...":""}</span> 771 <span>${b.hours}h</span> 772 </div> 773 `).join("")} 774 </div> 775 </div> 776 `).join("")} 777 </div> 778 779 <div class="section"> 780 <h2 class="section-title">${p.keyAccomplishments}</h2> 781 <ul class="accomplishments"> 782 ${t.accomplishments.map(o=>`<li>${o}</li>`).join("")} 783 </ul> 784 </div> 785 786 <div class="section"> 787 <h2 class="section-title">${p.timeBreakdown}</h2> 788 <table class="breakdown-table"> 789 <thead> 790 <tr> 791 <th>${s==="fr"?"Activité":"Activity"}</th> 792 <th>In Scope</th> 793 <th>Out of Scope</th> 794 <th>Total</th> 795 </tr> 796 </thead> 797 <tbody> 798 ${t.hoursBreakdown.map(o=>` 799 <tr> 800 <td>${o.name}</td> 801 <td class="in-scope">${o.inScopeHours}h</td> 802 <td class="out-of-scope">${o.outOfScopeHours}h</td> 803 <td>${o.hours}h</td> 804 </tr> 805 `).join("")} 806 </tbody> 807 </table> 808 </div> 809 810 <div class="section"> 811 <h2 class="section-title">${p.scopeChangeFramework}</h2> 812 ${t.scopeChangeTemplate.map(o=>` 813 <div class="scope-template"> 814 <div class="scope-template-type">${o.type}</div> 815 <p>${o.description}</p> 816 <p><em>â ${o.implications}</em></p> 817 </div> 818 `).join("")} 819 </div> 820 821 <div class="section"> 822 <h2 class="section-title">${p.scopeChanges}</h2> 823 ${t.scopeChanges.length>0?t.scopeChanges.map(o=>` 824 <div class="scope-item"> 825 <strong>${x(P(o.date),"PPP",{locale:s==="fr"?pe:de})}</strong> - ${o.description}<br> 826 <small>${s==="fr"?"Demandé par":"Requested by"}: ${o.requested_by} ⢠Status: ${o.status}</small> 827 </div> 828 `).join(""):`<p class="empty-state">${p.nothingForNow}</p>`} 829 </div> 830 831 <div class="section"> 832 <h2 class="section-title">${p.risksAndDependencies}</h2> 833 ${t.risksAndDependencies?`<ul class="recommendations">${t.risksAndDependencies.split(` 834`).filter(Boolean).map(o=>`<li>${o}</li>`).join("")}</ul>`:`<p class="empty-state">${p.nothingForNow}</p>`} 835 </div> 836 837 <div class="section"> 838 <h2 class="section-title">${p.meetingLogs}</h2> 839 ${t.meetings.length>0?t.meetings.map(o=>` 840 <div class="meeting-item"> 841 <strong>${x(P(o.date),"PPP",{locale:s==="fr"?pe:de})}</strong> - ${o.titre||(s==="fr"?"Réunion":"Meeting")}<br> 842 ${o.notes?`<small>${o.notes}</small>`:""} 843 </div> 844 `).join(""):`<p class="empty-state">${p.nothingForNow}</p>`} 845 </div> 846 847 <div class="section"> 848 <h2 class="section-title">${p.recommendations}</h2> 849 <ul class="recommendations"> 850 ${t.recommendations.map(o=>`<li>${o}</li>`).join("")} 851 </ul> 852 </div> 853 854 <div class="section"> 855 <h2 class="section-title">${p.nextSteps}</h2> 856 ${r.length>0?`<ol class="nextsteps">${r.map(o=>`<li>${o}</li>`).join("")}</ol>`:`<p class="empty-state">${p.nothingForNow}</p>`} 857 </div> 858 859 <div class="section"> 860 <h2 class="section-title">${p.teamInvolved}</h2> 861 <div class="team"> 862 ${t.teamMembers.map(o=>`<span class="team-member">${o}</span>`).join("")} 863 </div> 864 </div> 865 866 <div class="footer"> 867 <p>StudentBrains Consulting ⢠${s==="fr"?"Généré le":"Generated on"} ${x(new Date,"PPP",{locale:s==="fr"?pe:de})}</p> 868 </div> 869</body> 870</html>`},Cs=()=>{ee([...D,""]),U(!0)},Ds=(t,r)=>{const s=[...D];s[t]=r,ee(s),U(!0)},Ms=t=>{ee(D.filter((r,s)=>s!==t)),U(!0)},_s=()=>{Re([...Pe,""]),U(!0)},Ps=(t,r)=>{const s=[...Pe];s[t]=r,Re(s),U(!0)},Rs=t=>{Re(Pe.filter((r,s)=>s!==t)),U(!0)},Es=()=>{T([...m,""]),U(!0)},As=(t,r)=>{const s=[...m];s[t]=r,T(s),U(!0)},Ts=t=>{T(m.filter((r,s)=>s!==t)),U(!0)},zs=t=>{Ne(t),U(!0)},Ls=()=>{Ke([...Ge,""]),U(!0)},Os=(t,r)=>{const s=[...Ge];s[t]=r,Ke(s),U(!0)},Hs=t=>{Ke(Ge.filter((r,s)=>s!==t)),U(!0)},Et=(t,r)=>{vt(s=>({...s,[t]:r})),U(!0)},Is=(t,r)=>{const s=[...Oe];s[t]={...s[t],name:r},nt(s),U(!0)},Fs=async()=>
870{if(!(!we||!y)){Le(!0);try{const t=D.filter(o=>o.trim()),r=Pe.filter(o=>o.trim()),s=m.filter(o=>o.trim()),p=Ge.filter(o=>o.trim()),w={...y,accomplishments:r,recommendations:s,risksAndDependencies:ve,nextSteps:t,phases:Oe,teamMembers:p,scopeChanges:ot,meetings:lt,projectStartDate:re.start,projectEndDate:re.end,projectStatus:re.status},{error:S}=await me.from("sbc_generated_reports").update({next_steps:t,report_data:w}).eq("report_id",we);if(S)throw S;G(w),U(!1),q.success(g.saved),dt()}catch(t){console.error("Error saving report:",t),q.error("Error saving")}finally{Le(!1)}}},Bs=t=>{G(t.report_data),ee(t.next_steps||[]),Re(t.report_data.accomplishments||[]),T(t.report_data.recommendations||[]),Ne(t.report_data.risksAndDependencies||""),nt(t.report_data.phases||[]),Ke(t.report_data.teamMembers||[]),gt(t.report_data.scopeChanges||[]),bt(t.report_data.meetings||[]),vt({start:t.report_data.projectStartDate||"",end:t.report_data.projectEndDate||"",status:t.report_data.projectStatus||"ongoing"}),ce(t.report_id),k(t.share_token),B(t.language),U(!1),q.success(n==="fr"?"Rapport chargé":"Report loaded")},Vs=async t=>{try{const{error:r}=await me.from("sbc_generated_reports").delete().eq("report_id",t);if(r)throw r;dt(),we===t&&(G(null),ce(null),k(null)),q.success(n==="fr"?"Rapport supprimé":"Report deleted")}catch(r){console.error("Error deleting report:",r),q.error("Error deleting report")}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"h-10 w-10 rounded-lg bg-blue-100 flex items-center justify-center",children:e.jsx(Ft,{className:"h-5 w-5 text-blue-600"})}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold text-slate-900",children:g.title}),e.jsx("p",{className:"text-sm text-slate-500",children:g.subtitle})]})]}),e.jsxs(ie,{children:[e.jsxs(fe,{children:[e.jsxs(ge,{className:"flex items-center gap-2",children:[e.jsx(Qt,{className:"h-5 w-5"}),g.configTitle]}),e.jsx(Bt,{children:g.configDesc})]}),e.jsxs(ne,{className:"space-y-4",children:[e.jsxs("div",{className:"grid md:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(oe,{className:"flex items-center gap-2",children:[e.jsx(Ft,{className:"h-4 w-4"}),g.project]}),e.jsxs(tt,{value:d,onValueChange:h,children:[e.jsx(st,{children:e.jsx(rt,{placeholder:n==="fr"?"Sélectionner...":"Select..."})}),e.jsx(at,{children:j.map(t=>{var r;return e.jsxs(ze,{value:t.projet_id,children:[t.nom_projet," ",(r=t.client)!=null&&r.nom_client?`(${t.client.nom_client})`:""]},t.projet_id)})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(oe,{className:"flex items-center gap-2",children:[e.jsx(it,{className:"h-4 w-4"}),g.period]}),e.jsxs(tt,{value:R,onValueChange:E,children:[e.jsx(st,{children:e.jsx(rt,{})}),e.jsx(at,{children:qt.map(t=>e.jsx(ze,{value:t.value,children:t.label},t.value))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(oe,{className:"flex items-center gap-2",children:[e.jsx(ss,{className:"h-4 w-4"}),g.language]}),e.jsxs(tt,{value:n,onValueChange:t=>B(t),children:[e.jsx(st,{children:e.jsx(rt,{})}),e.jsxs(at,{children:[e.jsx(ze,{value:"fr",children:"ð«ð· Français"}),e.jsx(ze,{value:"en",children:"ð¬ð§ English"})]})]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(z,{onClick:vs,disabled:!d||M,children:M?e.jsxs(e.Fragment,{children:[e.jsx(Xe,{className:"h-4 w-4 mr-2 animate-spin"}),g.generating]}):e.jsxs(e.Fragment,{children:[e.jsx(Dt,{className:"h-4 w-4 mr-2"}),g.generate]})}),e.jsxs(z,{variant:"outline",onClick:()=>Pt(!0),className:"border-dashed",children:[e.jsx(It,{className:"h-4 w-4 mr-2"}),n==="fr"?"Rapport personnalisé":"Custom Report"]})]})]})]}),e.jsx(Sr,{language:n}),e.jsx(wr,{open:ps,onOpenChange:Pt,projects:j,language:n,onGenerate:js,generating:ms}),Ze&&e.jsx(kr,{open:us,onOpenChange:t=>{t||(jt(!1),yt(null),ct(!1),_(0),te(""))},language:n,teamMembers:Ze.teamMembers,inconsistencies:Ze.inconsistencies,projectNames:Ze.projectNames,totalHours:Ze.totalHours,onConfirm:t=>{t&&console.log("User notes for report generation:",t),Ze.continueGeneration()},onCancel:()=>{jt(!1),yt(null),ct(!1),_(0),te(""),q.info(n==="fr"?"Génération annulée":"Generation cancelled")}}),y&&e.jsxs("div",{className:"space-y-6",children:[e.jsx(ie,{className:be?"border-amber-300 bg-amber-50/50":"",children:e.jsxs(ne,{className:"pt-6",children:[be&&e.jsxs("div",{className:"flex items-center gap-2 mb-4 text-amber-700",children:[e.jsx(ht,{className:"h-4 w-4"}),e.jsx("span",{className:"text-sm font-medium",children:n==="fr"?"Modifications non enregistrées":"Unsaved changes"})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsxs(z,{onClick:Fs,disabled:Qe||!be,variant:be?"default":"outline",children:[Qe?e.jsx(Xe,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Jt,{className:"h-4 w-4 mr-2"}),n==="fr"?"Enregistrer les modifications":"Save changes"]}),e.jsxs(z,{onClick:Ns,disabled:he||be,children:[he?e.jsx(Xe,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Js,{className:"h-4 w-4 mr-2"}
870),g.exportSlides]}),e.jsxs(z,{onClick:ks,disabled:c||be,variant:"outline",children:[c?e.jsx(Xe,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Jt,{className:"h-4 w-4 mr-2"}),g.exportPdf]}),v&&!be&&e.jsxs(z,{variant:"outline",onClick:ws,children:[e.jsx(Zs,{className:"h-4 w-4 mr-2"}),g.copyLink]})]}),v&&!be&&e.jsxs("div",{className:"mt-4 p-3 bg-slate-50 rounded-lg",children:[e.jsx(oe,{className:"text-xs text-slate-500",children:g.shareableLink}),e.jsx("p",{className:"text-sm font-mono text-slate-700 mt-1 break-all",children:Kt()})]})]})}),e.jsx(ie,{className:"bg-gradient-to-br from-blue-600 to-blue-800 text-white",children:e.jsxs(ne,{className:"pt-6",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(ue,{variant:"secondary",className:"bg-white/20 text-white border-0",children:g.monthlyReport}),e.jsx(ue,{variant:"secondary",className:"bg-white/20 text-white border-0",children:n==="fr"?"ð«ð·":"ð¬ð§"})]}),e.jsx("h3",{className:"text-2xl font-bold mb-1",children:y.projectName}),e.jsx("p",{className:"text-blue-100",children:y.clientName}),e.jsxs("div",{className:"flex items-center gap-4 mt-4 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(it,{className:"h-4 w-4"}),e.jsx("span",{className:"text-sm",children:y.period})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(xt,{className:"h-4 w-4"}),e.jsxs("span",{className:"text-sm",children:[y.totalHours,"h ",g.hoursWorked]})]}),e.jsxs("div",{className:"flex items-center gap-2 bg-white/10 px-3 py-1 rounded-full",children:[e.jsx(Ct,{className:"h-4 w-4 text-green-300"}),e.jsxs("span",{className:"text-sm",children:[y.inScopeHours,"h in scope"]})]}),e.jsxs("div",{className:"flex items-center gap-2 bg-white/10 px-3 py-1 rounded-full",children:[e.jsx(er,{className:"h-4 w-4 text-slate-300"}),e.jsxs("span",{className:"text-sm",children:[y.outOfScopeHours,"h out of scope"]})]})]})]})}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(tr,{className:"h-5 w-5 text-blue-500"}),g.projectDates]})}),e.jsx(ne,{children:e.jsxs("div",{className:"grid md:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(oe,{children:g.projectStart}),e.jsx(Me,{type:"date",value:re.start,onChange:t=>Et("start",t.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(oe,{children:g.projectEnd}),e.jsx(Me,{type:"date",value:re.end,onChange:t=>Et("end",t.target.value),disabled:re.status==="ongoing"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(oe,{children:"Status"}),e.jsxs(tt,{value:re.status,onValueChange:t=>Et("status",t),children:[e.jsx(st,{children:e.jsx(rt,{})}),e.jsxs(at,{children:[e.jsx(ze,{value:"ongoing",children:g.ongoing}),e.jsx(ze,{value:"completed",children:n==="fr"?"Terminé":"Completed"})]})]})]})]})})]}),e.jsx("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4",children:y.kpis.map((t,r)=>e.jsx(ie,{children:e.jsxs(ne,{className:"pt-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-xs text-slate-500 uppercase tracking-wider",children:t.label}),t.trend==="up"&&e.jsx(Dt,{className:"h-4 w-4 text-green-500"}),t.trend==="down"&&e.jsx(sr,{className:"h-4 w-4 text-red-500"})]}),e.jsx("p",{className:"text-2xl font-bold text-slate-900",children:t.value}),t.trendValue&&e.jsx("p",{className:"text-xs text-slate-500 mt-1",children:t.trendValue})]})},r))}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(rr,{className:"h-5 w-5 text-cyan-500"}),g.phases]})}),e.jsx(ne,{className:"space-y-4",children:Oe.map((t,r)=>e.jsxs("div",{className:"p-4 bg-slate-50 rounded-lg border-l-4 border-blue-500",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx(Me,{value:t.name,onChange:s=>Is(r,s.target.value),className:"font-semibold bg-transparent border-none p-0 h-auto text-lg"}),e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsxs(ue,{variant:"secondary",className:"bg-green-100 text-green-700",children:[t.inScopeHours,"h in scope"]}),e.jsxs(ue,{variant:"secondary",className:"bg-slate-100 text-slate-600",children:[t.outOfScopeHours,"h out"]})]})]}),e.jsxs("p",{className:"text-xs text-slate-500 mb-2",children:[t.startDate&&x(P(t.startDate),"d MMM",{locale:Ee})," - ",t.endDate&&x(P(t.endDate),"d MMM yyyy",{locale:Ee})]}),e.jsxs("div",{className:"space-y-1",children:[t.tasks.slice(0,5).map((s,p)=>e.jsxs("div",{className:`flex items-center gap-2 text-sm p-2 rounded ${s.inScope?"bg-green-50 border-l-2 border-green-400":"bg-slate-100 border-l-2 border-slate-300"}
870`,children:[e.jsx("span",{className:"text-slate-500 w-16",children:x(P(s.date),"d/M")}),e.jsx("span",{className:"flex-1 truncate",children:s.description}),e.jsxs("span",{className:"text-slate-500",children:[s.hours,"h"]})]},p)),t.tasks.length>5&&e.jsxs("p",{className:"text-xs text-slate-500 pt-1",children:["+",t.tasks.length-5," ",n==="fr"?"autres tâches":"more tasks","..."]})]})]},r))})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(ar,{className:"h-5 w-5 text-purple-500"}),g.ganttChart]})}),e.jsxs(ne,{children:[e.jsx("div",{className:"space-y-3",children:Oe.map((t,r)=>{const s=t.startDate?P(t.startDate):new Date,p=t.endDate?P(t.endDate):new Date,w=re.start?P(re.start):s,S=re.end?P(re.end):new Date,o=Math.max(Ye(S,w),1),b=Math.max(0,Ye(s,w)),N=Math.max(1,Ye(p,s)+1),$=Math.min(100,b/o*100),H=Math.min(100-$,N/o*100);return e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("span",{className:"w-48 text-sm font-medium truncate",children:t.name}),e.jsx("div",{className:"flex-1 h-6 bg-slate-100 rounded relative",children:e.jsxs("div",{className:"absolute h-full rounded flex items-center justify-center text-xs text-white font-medium",style:{left:`${$}%`,width:`${Math.max(H,5)}%`,backgroundColor:qe[r%qe.length]},children:[t.totalHours,"h"]})}),e.jsxs("span",{className:"w-24 text-xs text-right",children:[e.jsxs("span",{className:"text-green-600",children:[t.inScopeHours,"h"]})," / ",t.outOfScopeHours,"h"]})]},r)})}),e.jsxs("div",{className:"flex items-center gap-4 mt-4 text-xs text-slate-500",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("div",{className:"w-3 h-3 bg-green-500 rounded"}),e.jsx("span",{children:"In Scope"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("div",{className:"w-3 h-3 bg-slate-400 rounded"}),e.jsx("span",{children:"Out of Scope"})]})]})]})]}),y.customCharts&&y.customCharts.length>0&&e.jsx(gr,{charts:y.customCharts,language:n}),e.jsxs(ie,{children:[e.jsxs(fe,{children:[e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(ir,{className:"h-5 w-5 text-amber-500"}),g.scopeChangeFramework]}),e.jsx(Bt,{children:n==="fr"?"Ce cadre définit les types de changements qui nécessitent une révision du scope et leurs implications.":"This framework defines types of changes that require scope revision and their implications."})]}),e.jsx(ne,{children:e.jsx("div",{className:"grid md:grid-cols-2 gap-3",children:Ot[n].map((t,r)=>e.jsxs("div",{className:"p-3 bg-amber-50 border border-amber-200 rounded-lg",children:[e.jsx("p",{className:"font-semibold text-amber-800",children:t.type}),e.jsx("p",{className:"text-sm text-slate-600 mt-1",children:t.description}),e.jsxs("p",{className:"text-xs text-amber-700 mt-2",children:["â ",t.implications]})]},r))})})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(ht,{className:"h-5 w-5 text-amber-500"}),g.scopeChanges]})}),e.jsx(ne,{children:ot.length>0?e.jsx("div",{className:"space-y-3",children:ot.map(t=>e.jsxs("div",{className:"p-3 bg-amber-50 rounded-lg border-l-3 border-amber-500",children:[e.jsx("p",{className:"text-xs text-slate-500",children:x(P(t.date),"PPP",{locale:Ee})}),e.jsx("p",{className:"text-sm font-medium",children:t.description}),e.jsxs("p",{className:"text-xs text-slate-500",children:[t.requested_by," ⢠",t.status]})]},t.change_id))}):e.jsx("p",{className:"text-sm text-slate-500 italic",children:g.nothingForNow})})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(ht,{className:"h-5 w-5 text-red-500"}),g.risksAndDependencies]})}),e.jsx(ne,{children:e.jsx(Vt,{value:ve,onChange:t=>zs(t.target.value),placeholder:n==="fr"?"Risques et dépendances (un par ligne)...":"Risks and dependencies (one per line)...",className:"min-h-[120px]"})})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(nr,{className:"h-5 w-5 text-purple-500"}),g.meetingLogs]})}),e.jsx(ne,{children:lt.length>0?e.jsx("div",{className:"space-y-3",children:lt.slice(0,5).map(t=>e.jsxs("div",{className:"p-3 bg-purple-50 rounded-lg border-l-3 border-purple-500",children:[e.jsx("p",{className:"text-xs text-slate-500",children:x(P(t.date),"PPP",{locale:Ee})}),e.jsx("p",{className:"text-sm font-medium",children:t.titre||(n==="fr"?"Réunion":"Meeting")}),t.notes&&e.jsx("p",{className:"text-xs text-slate-600 mt-1",children:t.notes})]},t.meeting_id))}):e.jsx("p",{className:"text-sm text-slate-500 italic",children:g.nothingForNow})})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(Qt,{className:"h-5 w-5 text-blue-500"}),g.nextSteps]})}),e.jsxs(ne,{className:"space-y-3",children:[D.map((t,r)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Me,{value:t,onChange:s=>Ds(r,s.target.value),placeholder:n==="fr"?"Prochaine étape...":"Next step...",className:"flex-1"}),e.jsx(z,{variant:"ghost",size:"icon",onClick:()=>Ms(r),children:e.jsx(ut,{className:"h-4 w-4 text-red-500"})})]},r)),e.jsxs(z,{variant:"outline",size:"sm",onClick:Cs,children:[e.jsx($t,{className:"h-4 w-4 mr-2"}),g.addNextStep]})]})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(Dt,{className:"h-5 w-5 text-green-500"}),g.keyAccomplishments]})}),e.jsxs(ne,{className:"space-y-3",children:[Pe.map((t,r)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Me,{value:t,onChange:s=>Ps(r,s.target.value),placeholder:n==="fr"?"Accomplissement...":"Accomplishment...",className:"flex-1"}),e.jsx(z,{variant:"ghost",size:"icon",onClick:()=>Rs(r),children:e.jsx(ut,{className:"h-4 w-4 text-red-500"})})]},r)),e.jsxs(z,{variant:"outline",size:"sm",onClick:_s,children:[e.jsx($t,{className:"h-4 w-4 mr-2"}),n==="fr"?"Ajouter":"Add"]})]})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(or,{className:"h-5 w-5 text-amber-500"}),g.recommendations]})}),e.jsxs(ne,{className:"space-y-3",children:[m.map((t,r)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Me,{value:t,onChange:s=>As(r,s.target.value),placeholder:n==="fr"?"Recommandation...":"Recommendation...",className:"flex-1"}),e.jsx(z,{variant:"ghost",size:"icon",onClick:()=>Ts(r),children:e.jsx(ut,{className:"h-4 w-4 text-red-500"})})]},r)),e.jsxs(z,{variant:"outline",size:"sm",onClick:Es,children:[e.jsx($t,{className:"h-4 w-4 mr-2"}),n==="fr"?"Ajouter":"Add"]})]})]}),e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(_t,{className:"h-5 w-5 text-purple-500"}),g.teamInvolved]})}),e.jsxs(ne,{className:"space-y-3",children:[Ge.map((t,r)=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Me,{value:t,onChange:s=>Os(r,s.target.value),placeholder:n==="fr"?"Nom du membre...":"Member name...",className:"flex-1"}),e.jsx(z,{variant:"ghost",size:"icon",onClick:()=>Hs(r),children:e.jsx(ut,{className:"h-4 w-4 text-red-500"})})]},r)),e.jsxs(z,{variant:"outline",size:"sm",onClick:Ls,children:[e.jsx($t,{className:"h-4 w-4 mr-2"}),n==="fr"?"Ajouter":"Add"]})]})]})]}),se.length>0&&e.jsxs(ie,{children:[e.jsx(fe,{children:e.jsxs(ge,{className:"text-lg flex items-center gap-2",children:[e.jsx(lr,{className:"h-5 w-5 text-slate-500"}),g.previousReports]})}),e.jsx(ne,{children:e.jsx("div",{className:"space-y-3",children:se.map(t=>{var r,s,p;return e.jsxs("div",{className:"flex items-center justify-between p-3 bg-slate-50 rounded-lg",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"font-medium text-sm",children:(r=t.projet)==null?void 0:r.nom_projet}),e.jsxs("p",{className:"text-xs text-slate-500",children:[(p=(s=t.projet)==null?void 0:s.client)==null?void 0:p.nom_client," ⢠",x(P(t.period_start),"MMM yyyy",{locale:Ee})]}),e.jsx("p",{className:"text-xs text-slate-400",children:x(P(t.created_at),"PPp",{locale:Ee})})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(z,{variant:"ghost",size:"sm",onClick:()=>Bs(t),children:[e.jsx(cr,{className:"h-4 w-4 mr-1"}),g.viewReport]}),e.jsx(z,{variant:"ghost",size:"sm",onClick:()=>Vs(t.report_id),children:e.jsx(ut,{className:"h-4 w-4 text-red-500"})})]})]},t.report_id)})})})]}),e.jsx(Nr,{reportData:y,reportId:we,language:n,onReportUpdated:ys})]})}export{ra as SBCReporting};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.