PageSourceSearch

https://le-barreaumetre.fr/assets/actions-Bb3mMmsA.js

js le-barreaumetre.fr collected 2026-10-04 20:35:54 UTC 59,393 bytes, 103 lines download raw bytes

1import{s as a,M as j,n as me}from"./index-DjWeVXQh.js";import{l as G}from"./app-BwwgxGmm.js";import{a as T,e as W,b as H}from"./firm-utils-BjUfpR4x.js";const fe=new Set(["n/a","na","n.a.","n.a","-","--","—","non renseigné","non renseignée","non specifié","non spécifié","not specified","unknown","inconnu","test","exemple","example","à définir","a definir","néant","aucun","none","cabinet","cabinet avocat","cabinet d'avocat","offre sans titre"]);function de(e){if(!e)return!0;const r=e.trim();if(r.length<2)return!0;const t=r.toLowerCase();return!!(fe.has(t)||/^[\s\-—–_.*#/\\0-9]+$/.test(r))}const K=["f226d64e-c07c-499a-87e5-953fc953582c","4052cf34-524d-4eac-a950-9398a940db27","94fb7bcb-9d37-40b5-8f4c-c1c86f753a0a","6a2eac12-ce55-4ba2-83b1-ac9ab03976c9","e06c5a5a-696d-4a5c-8d43-c094e69d704b","478f3e92-5fa1-44ff-9f34-1afbb0d3988d","3bd558f5-3749-4659-aea1-5c12a3b6eaa8"];function _e(e){const r=e.trim();return r&&r.charAt(0).toUpperCase()+r.slice(1)}async function ge(e,r,t){try{const n=_e(e);if(!n||de(n))throw new Error("Le nom de l'employeur est invalide ou manquant");const{data:i,error:o}=await a.from("firm").select("id").ilike("name",n).maybeSingle();if(o&&o.code!=="PGRST116")throw new Error(`Erreur lors de la recherche du cabinet: ${o.message}`);if(i)return{success:!0,firmId:i.id};const{data:s,error:c}=await a.from("firm").insert({name:n,structure_type:r||"other",is_specialized:!0,is_verified:!1,email_domain:t||null}).select("id").single();if(c){if(console.error("[createFirmForEmployer] Insert error:",{code:c.code,message:c.message,details:c.details,hint:c.hint,name:n,structureType:r}),c.message.includes("duplicate")||c.message.includes("unique")){const{data:f}=await a.from("firm").select("id").ilike("name",n).single();if(f)return{success:!0,firmId:f.id}}throw c.code==="42501"||c.message.toLowerCase().includes("row-level security")||c.message.toLowerCase().includes("not authorized")||c.message.toLowerCase().includes("permission")?new Error("Impossible de créer la structure (permissions). Réessayez, ou contactez-nous ici : https://calendar.app.google/1fNpEB8Eiph5mRCB7"):new Error(`Échec de la création du cabinet: ${c.message}`)}if(!s?.id)throw new Error("Aucun ID de cabinet retourné");return{success:!0,firmId:s.id}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function we(e,r){try{if(!e||!r)throw new Error("userId et firmId sont requis");const{data:t}=await a.from("user_roles").select("id").eq("user_id",e).eq("role","firm_manager").eq("firm_id",r).maybeSingle();if(t)return{success:!0};const{error:n}=await a.from("user_roles").insert({user_id:e,role:"firm_manager",firm_id:r});if(n){if(n.message.includes("duplicate")||n.message.includes("unique"))return{success:!0};throw new Error(`Échec de l'attribution du rôle: ${n.message}`)}return{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}function Y(e){const r=typeof e.original_content=="string"?(()=>{try{return JSON.parse(e.original_content)}catch{return e.original_content}})():e.original_content;return{id:e.id,role:e.role,experience_summary:e.experience_summary,status:e.status,created_at:e.created_at,moderated_at:e.moderated_at,moderation_notes:e.moderation_notes,email:e.email||"",culture_rating:Number(e.culture_rating??0),compensation_rating:Number(e.compensation_rating??0),pride_rating:Number(e.pride_rating??0),wellbeing_rating:Number(e.wellbeing_rating??0),management_rating:Number(e.management_rating??0),atmosphere_rating:Number(e.atmosphere_rating??0),worklifebalance_rating:Number(e.worklifebalance_rating??0),original_content:r,firm:{id:e.id_firm||"",name:e.firm_name||"Cabinet inconnu"},department:e.id_department?{id:e.id_department,name:e.department_name||"Département inconnu"}:void 0}}async function ke(e){try{if(!e.role)throw new Error("Le champ 'rôle' est obligatoire");if(!e.cabinet)throw new Error("Le champ 'cabinet' est obligatoire");if(!e.city)throw new Error("Le champ 'city' est obligatoire");if(e.role==="fonction-support"&&e.department&&e.department!=="none")throw new Error("Le champ 'département' est interdit pour ce rôle");const r=parseInt(e.startYear);if(isNaN(r)||r<1980||r>new Date().getFullYear())throw new Error("L'année de début doit être valide (1980 - présent)");if(e.cultureRating===0)throw new Error("La note de culture est obligatoire");if(e.compensationRating===0)throw new Error("La note de rémunération est obligatoire");if(e.prideRating===0)throw new Error("La note de fierté est obligatoire");if(e.wellbeingRating===0)throw new Error("La note de bien-être est obligatoire");if(e.managementRating===0)throw new Error("La note de management est obligatoire");if(e.atmosphereRating===0)throw new Error("La note d'ambiance est obligatoire");if(e.workLifeBalanceRating===0)throw new Error("La note d'équilibre vie pro/perso est obligatoire");if(e.trainingRating===0)throw new Error("La note de formation est obligatoire");if(!e.remoteWork)throw new Error("Le champ 'télétravail' est obligatoire");if(!e.turnover)throw new Error("Le champ 'turnover' est obligatoire");if(e.role?.includes("collaborateur")){if(!e.billingPressure)throw new Error("Le champ 'pression de facturation' est obligatoire");if(!e.personalClients)throw new Error("Le champ 'clients personnels' est obligatoire")}if(!e.experienceSummary||e.experienceSummary.trim().length<100)throw new Error("Le résumé d'expérience doit contenir au moins 100 caractères");const t=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;if(!e.email||!t.test(e.email))throw new Error("L'adresse email doit être valide");let n=e.benefits||[];e.customBenefits&&e.customBenefits.length>0&&n.includes("autre")&&(n=n.filter(s=>
1s!=="autre"),e.customBenefits.forEach(s=>{n.push(`autre:${s.trim()}`)}));const i={role:e.role,id_firm:e.cabinet,id_department:e.department==="none"?null:e.department||null,city:e.city.trim(),start_year:r,culture_rating:e.cultureRating,compensation_rating:e.compensationRating,pride_rating:e.prideRating,wellbeing_rating:e.wellbeingRating,management_rating:e.managementRating,atmosphere_rating:e.atmosphereRating,worklifebalance_rating:e.workLifeBalanceRating,training_rating:e.trainingRating,remote_work:e.remoteWork,remote_work_days:e.remoteWorkDays||null,turnover:e.turnover,billing_pressure:e.billingPressure||null,personal_clients:e.personalClients||null,work_life_balance_actions:e.workLifeBalanceActions??null,benefits:n.length>0?n:null,recruitment_interview_count:e.recruitmentInterviewCount||null,recruitment_duration:e.recruitmentDuration||null,recruitment_rating:e.recruitmentRating||null,would_recommend:e.wouldRecommend,salary_amount:e.salaryAmount||null,billable_hours_target:e.billableHoursTarget||null,experience_summary:e.experienceSummary,email:e.email},{error:o}=await a.from("review").insert([i]);if(o)throw new Error(`Échec de l'insertion: ${o.message}`);e.newsletter&&await ve(e.email.split("@")[0],e.email,e.role||"unknown","review_form");try{await fetch("https://nayyupcnmcvracbdhjtg.supabase.co/functions/v1/send-email",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:"review_confirmation",to:e.email,name:e.email.split("@")[0]})})}catch(s){console.error("Email confirmation non envoyé:",s)}return{success:!0}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function Ae(e,r,t,n){try{if(!e||typeof e!="string")throw new Error("L'identifiant de l'avis est invalide");if(!r||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r))throw new Error("L'adresse email doit être valide");if(!t||!["injurious","defamatory","false","spam","other"].includes(t))throw new Error("La raison du signalement est invalide");const{error:s}=await a.from("review_reports").insert({review_id:e,reported_by_email:r,reason:t,description:n?.trim()||null});if(s)throw new Error(`Échec de l'envoi du signalement: ${s.message}`);return{success:!0}}catch(i){return{success:!1,error:i instanceof Error?i.message:"Une erreur est survenue"}}}async function Ne(e){try{if(e.coaching_quality===0)throw new Error("La note de coaching est obligatoire");if(e.learning_quality===0)throw new Error("La note d'apprentissage est obligatoire");if(e.work_life_balance_quality===0)throw new Error("La note d'équilibre est obligatoire");if(e.work_environment_quality===0)throw new Error("La note d'environnement est obligatoire");if(e.recognition_quality===0)throw new Error("La note de reconnaissance est obligatoire");if(e.values_alignment_quality===0)throw new Error("La note d'alignement est obligatoire");if(e.societal_engagement_quality===0)throw new Error("La note d'engagement est obligatoire");if(e.reputation_quality===0)throw new Error("La note de réputation est obligatoire");const r={coaching_quality:e.coaching_quality,learning_quality:e.learning_quality,work_life_balance_quality:e.work_life_balance_quality,work_environment_quality:e.work_environment_quality,recognition_quality:e.recognition_quality,values_alignment_quality:e.values_alignment_quality,societal_engagement_quality:e.societal_engagement_quality,reputation_quality:e.reputation_quality,comment:e.comment?.trim()||null},{error:t}=await a.from("preference").insert([r]);if(t)throw new Error(`Échec de l'insertion: ${t.message}`);return{success:!0}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function De(){try{let r=[],t=0,n=!0;for(;n;){const{data:i,error:o}=await a.from("firm").select("id, name, domain, structure_type").order("name",{ascending:!0}).range(t,t+1e3-1);if(o)throw new Error(`Erreur lors du chargement des cabinets: ${o.message}`);r=r.concat(i||[]),n=(i?.length||0)===1e3,t+=1e3}return{success:!0,data:r.map(i=>({...i,domain:i.domain||[],structure_type:i.structure_type||"law_firm"}))}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue"}}}async function Ce(e){try{if(!e||typeof e!="string"||e.trim()==="")throw new Error("L'identifiant du cabinet est invalide");const{data:r,error:t}=await a.from("department").select("id, id_firm, name, domain").eq("id_firm",e).order("domain",{ascending:!0});if(t)throw new Error(`Erreur lors du chargement des cabinets: ${t.message}`);return{success:!0,data:(r||[]).map(n=>({...n,domain:n.domain||[]}))}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function Le(e,r,t,n){try{if(!e.trim())throw new Error("Le nom du cabinet est obligatoire");if(typeof r!="boolean")throw new Error("Le champ 'spécialisé' doit être un booléen");if(!Array.isArray(n)||n.length===0)throw new Error("Au moins un domaine est requis");if(n.some(s=>
1typeof s!="string"||!G.includes(s.trim())))throw new Error("Tous les domaines doivent être des valeurs valides parmi les domaines juridiques autorisés");n=[...new Set(n.map(s=>s.trim()))];const{data:i,error:o}=await a.from("firm").insert({name:e.trim(),is_specialized:r,domain:r?n:null}).select("id").single();if(o)throw new Error(`Échec de la création du cabinet: ${o.message}`);if(!i?.id)throw new Error("Aucun ID de cabinet retourné");if(!r){const s=await pe(i.id,t,n);if(!s.success)throw new Error(s.error);return{success:!0,id:i.id,departmentId:s.id}}return{success:!0,id:i.id}}catch(i){return{success:!1,error:i instanceof Error?i.message.includes("firm_name_key")?"Ce cabinet existe déjà":i.message:"Une erreur est survenue"}}}async function pe(e,r,t){try{if(!e)throw new Error("L'ID du cabinet est obligatoire");if(!r||r.trim()==="")throw new Error("Veuillez saisir un nom de département.");if(r.length>150)throw new Error("Le nom du département ne doit pas dépasser 150 caractères.");if(!Array.isArray(t)||t.length===0)throw new Error("Au moins un domaine est requis");if(t.some(o=>typeof o!="string"||!G.includes(o.trim())))throw new Error("Tous les domaines doivent être des valeurs valides parmi les domaines juridiques autorisés");t=[...new Set(t.map(o=>o.trim()))];const{data:n,error:i}=await a.from("department").insert({id_firm:e,name:r,domain:t}).select("id").single();if(i)throw new Error(`Échec de la création du département: ${i.message}`);if(!n?.id)throw new Error("Aucun ID de département retourné");return{success:!0,id:n.id}}catch(n){return{success:!1,error:n instanceof Error?n.message.includes("unique_firm_domain")?"Ce cabinet a déjà un département avec exactement les mêmes domaines":n.message:"Une erreur est survenue"}}}const Z="ranking_cache_v1",U=600*1e3;let D=null;function he(){const e=Date.now();if(D&&e-D.ts<U)return D.payload;try{const r=sessionStorage.getItem(Z);if(!r)return null;const t=JSON.parse(r);return!t?.ts||e-t.ts>=U?null:(D=t,t.payload)}catch{return null}}function ye(e){const r={ts:Date.now(),payload:e};D=r;try{sessionStorage.setItem(Z,JSON.stringify(r))}catch{}}async function x(e,r,t=2e4){let n;const i=new Promise((o,s)=>{n=setTimeout(()=>s(new Error(`Timeout (${t}ms) sur ${r}`)),t)});try{return await Promise.race([Promise.resolve(e),i])}finally{n&&clearTimeout(n)}}async function be(e){const r=e?.includeNonLawFirms===!0;if(!r){const t=he();if(t)return t}try{const{data:t}=await x(a.from("public_job_offers").select("id_firm"),"public_job_offers"),n=new Set(t?.map(u=>u.id_firm)||[]),i=[],o=1e3;for(let u=0;;u+=o){const{data:l,error:h}=await x(a.from("firm").select(`
2            id,
3            name,
4            slug,
5            description,
6            domain,
7            main_domain,
8            structure_type,
9            is_premium,
10            is_verified,
11            logo_url,
12            office_photos,
13            firm_photos,
14            video_url,
15            values,
16            benefits,
17            engagement_rse,
18            pro_bono,
19            litigation_vs_advisory,
20            cities,
21            department (
22              id,
23              name,
24              domain
25            ),
26            review_responses (
27              id
28            )
29          `).not("id","in",`(${K.join(",")})`).order("id",{ascending:!0}).range(u,u+o-1),`firm batch @${u}`);if(h)throw new Error(`Échec de la récupération des cabinets: ${h.message}`);if(!l||l.length===0||(i.push(...l),l.length<o))break}if(i.length===0)throw new Error("Aucune donnée retournée");const s=[],c=1e3;for(let u=0;;u+=c){const{data:l,error:h}=await x(a.from("public_reviews").select("id, id_firm, id_department, role, city, start_year, culture_rating, compensation_rating, pride_rating, wellbeing_rating, management_rating, atmosphere_rating, worklifebalance_rating, training_rating, would_return, would_recommend, remote_work, turnover, billing_pressure, personal_clients").order("id",{ascending:!0}).range(u,u+c-1),`public_reviews batch @${u}`);if(h)throw new Error(`Échec de la récupération des avis: ${h.message}`);if(!l||l.length===0||(s.push(...l),l.length<c))break}const f=new Map;for(const u of s||[]){if(!u.id_firm)continue;const l=f.get(u.id_firm)||[];l.push(u),f.set(u.id_firm,l)}const g=i.filter(u=>f.has(u.id)&&(r||!u.structure_type||u.structure_type==="law_firm")).map(u=>{const l=f.get(u.id)||[],h=Array.isArray(u.department)?u.department:[],q=h.length>0,p=l,R=new Set;p.forEach(d=>{d.city&&d.city.trim()&&R.add(d.city.trim())}
29),Array.isArray(u.cities)&&u.cities.forEach(d=>{d&&d.trim()&&R.add(d.trim())});const A=Array.from(R),C=new Set,F=Array.isArray(u.main_domain)?u.main_domain.filter(d=>d&&d.trim()):[];F.length>0?F.forEach(d=>C.add(d.trim())):q?h.forEach(d=>{Array.isArray(d.domain)&&d.domain.forEach(y=>{y&&y.trim()&&C.add(y.trim())})}):Array.isArray(u.domain)&&u.domain.forEach(d=>{d&&d.trim()&&C.add(d.trim())});const Q=Array.from(C),J=T(p,q),I=W(p),ee=p.length>0?{culture:p.reduce((d,y)=>d+(y.culture_rating||0),0)/p.length,compensation:p.reduce((d,y)=>d+(y.compensation_rating||0),0)/p.length,pride:p.reduce((d,y)=>d+(y.pride_rating||0),0)/p.length,wellbeing:p.reduce((d,y)=>d+(y.wellbeing_rating||0),0)/p.length,management:p.reduce((d,y)=>d+(y.management_rating||0),0)/p.length,atmosphere:p.reduce((d,y)=>d+(y.atmosphere_rating||0),0)/p.length,worklifebalance:p.reduce((d,y)=>d+(y.worklifebalance_rating||0),0)/p.length,training:p.reduce((d,y)=>d+(y.training_rating||0),0)/p.length}:void 0,$=p.filter(d=>d.remote_work),re=$.filter(d=>d.remote_work==="libre"||d.remote_work==="occasionnel").length,te=$.length>0?Math.round(re/$.length*100):null,O=p.filter(d=>d.would_recommend),ie=O.filter(d=>d.would_recommend==="oui").length,ne=O.length>0?Math.round(ie/O.length*100):null,se=q?h.map(d=>{const y=p.filter(k=>k.id_department===d.id),ce=T(y,!1),ue=W(y),z=new Set;y.forEach(k=>{k.id_department===d.id&&k.city&&k.city.trim()&&z.add(k.city.trim())});const le=Array.from(z);return{id:d.id,name:typeof d.name=="string"?d.name:null,cities:le,domains:Array.isArray(d.domain)?d.domain:[],note:ce,reviewCount:y.length,badges:ue}}):[],ae=Array.isArray(u.review_responses)&&u.review_responses.length>0,oe=H(J,{engagement_rse:u.engagement_rse,pro_bono:u.pro_bono,values:u.values,benefits:u.benefits,description:u.description,litigation_vs_advisory:u.litigation_vs_advisory,firm_photos:u.firm_photos,office_photos:u.office_photos,video_url:u.video_url,has_review_responses:ae,review_count:p.length});return{id:u.id,name:u.name,slug:u.slug,logoUrl:u.logo_url||null,cities:A,domains:Q,note:J,reviewCount:p.length,badges:I,detailedRatings:ee,departments:se,isPremium:u.is_premium===!0,isVerified:u.is_verified===!0,hasActiveJobOffers:n.has(u.id),remoteWorkPercent:te,wouldRecommendPercent:ne,_employerScore:oe}});g.sort((u,l)=>{const h=u._employerScore??u.note,q=l._employerScore??l.note;return q!==h?q-h:l.reviewCount!==u.reviewCount?l.reviewCount-u.reviewCount:u.name.localeCompare(l.name,"fr",{sensitivity:"base"})});const b=g.filter(u=>u.reviewCount>=j),v=b.length>0?b.reduce((u,l)=>u+(l._employerScore??l.note),0)/b.length:0,{data:S}=await a.from("rank_snapshot").select("firm_id, rank, snapshot_at").order("snapshot_at",{ascending:!1}).limit(1e3),m=new Map;if(S&&S.length>0){const u=S[0].snapshot_at;for(const l of S)l.snapshot_at===u&&l.firm_id&&!m.has(l.firm_id)&&m.set(l.firm_id,l.rank)}g.filter(u=>(u._employerScore??u.note)>=me&&u.reviewCount>=j).forEach((u,l)=>{const h=l+1,q=m.get(u.id);q===void 0?u.rankDelta=m.size>0?null:void 0:u.rankDelta=q-h});const E={success:!0,data:g,averageScore:v};return r||ye(E),E}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}const V="official_scores_cache_v1";let N=null;async function Ue(){const e=Date.now();if(N&&e-N.ts<U)return new Map(Object.entries(N.scores));try{const i=sessionStorage.getItem(V);if(i){const o=JSON.parse(i);if(o?.ts&&e-o.ts<U)return N=o,new Map(Object.entries(o.scores))}}catch{}const r=await be({includeNonLawFirms:!0});if(!r.success)return new Map;const t={};for(const i of r.data)t[i.id]=i._employerScore??i.note;const n={ts:Date.now(),scores:t};N=n;try{sessionStorage.setItem(V,JSON.stringify(n))}catch{}return new Map(Object.entries(t))}async function Me(){try{const{data:e,error:r}=await a.from("firm").select(`
30        id,
31        engagement_rse,
32        pro_bono,
33        values,
34        benefits,
35        description,
36        litigation_vs_advisory,
37        firm_photos,
38        office_photos,
39        video_url,
40        department (id),
41        review_responses (id)
42      `);if(r)throw new Error(r.message);if(!e)return{success:!0,averageScore:0};const{data:t}=await a.from("public_reviews").select("id_firm, culture_rating, compensation_rating, pride_rating, wellbeing_rating, management_rating, atmosphere_rating, worklifebalance_rating, training_rating"),n=new Map;for(const s of t||[]){if(!s.id_firm)continue;const c=n.get(s.id_firm)||[];c.push(s),n.set(s.id_firm,c)}const i=e.map(s=>{const c=n.get(s.id)||[],f=Array.isArray(s.department)?s.department:[],_=c.length;if(_<j)return null;const g=f.length>0,b=T(c,g),v=Array.isArray(s.review_responses)&&s.review_responses.length>0;return H(b,{engagement_rse:s.engagement_rse,pro_bono:s.pro_bono,values:s.values,benefits:s.benefits,description:s.description,litigation_vs_advisory:s.litigation_vs_advisory,firm_photos:s.firm_photos,office_photos:s.office_photos,video_url:s.video_url,has_review_responses:v,review_count:_})}).filter(s=>s!==null);return{success:!0,averageScore:i.length>0?i.reduce((s,c)=>s+c,0)/i.length:0}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue"}}}async function ve(e,r,t,n="newsletter_form"){try{if(!e||e.trim().length===0)throw new Error("Le nom est requis.");
42if(!r||!/^[\w-.]+@([\w-]+\.)+[\w-]{2,}$/.test(r))throw new Error("L'adresse email n'est pas valide.");if(!t||t.trim().length===0)throw new Error("Le rôle est requis.");const i=await fetch("https://nayyupcnmcvracbdhjtg.supabase.co/functions/v1/newsletter-subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,email:r,role:t,fromWhere:n})}),o=await i.json();if(!i.ok||!o.success)throw new Error(o.error||"Une erreur est survenue");return{success:!0}}catch(i){return{success:!1,error:i instanceof Error?i.message:"Une erreur est survenue"}}}async function M(e){try{const{data:{user:r}}=await a.auth.getUser();if(!r)return{success:!0,canManage:!1};const{data:t,error:n}=await a.rpc("can_manage_firm",{_user_id:r.id,_firm_id:e});if(n)throw new Error(n.message);return{success:!0,canManage:t||!1}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function L(e,r){try{const t=await M(e);if(!t.success||!t.canManage)throw new Error("Vous n'avez pas les droits pour modifier ce cabinet");const{data:n,error:i}=await a.from("firm").update(r).eq("id",e).select().single();if(i)throw new Error(i.message);return{success:!0,data:n}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function Pe(e,r,t){try{const n=await M(e);if(!n.success||!n.canManage)throw new Error("Vous n'avez pas les droits pour uploader des fichiers pour ce cabinet");if(!["image/jpeg","image/jpg","image/png","image/webp"].includes(r.type))throw new Error("Format de fichier non supporté. Utilisez JPG, PNG ou WEBP.");if(r.size>5*1024*1024)throw new Error("Le fichier est trop volumineux. Taille maximale : 5MB");const o=r.name.split(".").pop(),s=t==="photo"||t==="team_photo"?`${e}/photos/${Date.now()}.${o}`:`${e}/${t}.${o}`,{error:c}=await a.storage.from("firm-media").upload(s,r,{upsert:!0});if(c)throw new Error(c.message);const{data:{publicUrl:f}}=a.storage.from("firm-media").getPublicUrl(s);if(t==="logo")await L(e,{logo_url:f});else if(t==="cover")await L(e,{cover_image_url:f});else if(t==="photo"){const{data:_}=await a.from("firm").select("firm_photos").eq("id",e).single(),g=_?.firm_photos||[];await L(e,{firm_photos:[...g,f]})}return{success:!0,url:f}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function $e(e,r){try{const t=await M(e);if(!t.success||!t.canManage)throw new Error("Vous n'avez pas les droits pour supprimer des fichiers pour ce cabinet");let n=null;r.includes("/firm-media/")?n=r.split("/firm-media/")[1]:r.startsWith("http")||r.startsWith("https")?n=null:r.startsWith("/")?n=r.substring(1):n=r;const{data:i}=await a.from("firm").select("firm_photos, culture_photos, custom_sections").eq("id",e).single();let o=!1;if(i){const s={};i.firm_photos&&(s.firm_photos=i.firm_photos.filter(g=>g!==r)),i.culture_photos&&(s.culture_photos=i.culture_photos.filter(g=>g!==r)),i.custom_sections&&Array.isArray(i.custom_sections)&&(s.custom_sections=i.custom_sections.map(g=>g.images?{...g,images:g.images.filter(b=>(typeof b=="string"?b:b.url)!==r)}:g)),await L(e,s);const c=s.firm_photos||[],f=s.culture_photos||[],_=(s.custom_sections||[]).flatMap(g=>(g.images||[]).map(b=>typeof b=="string"?b:b.url));o=[...c,...f,..._].includes(r)}if(n&&!o){const{error:s}=await a.storage.from("firm-media").remove([n]);s&&console.warn("Avertissement storage:",s.message)}return{success:!0}}catch(t){return console.error("Erreur deleteFirmMedia:",t),{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function P(){try{const{data:{user:e}}=await a.auth.getUser();if(!e)return!1;const{data:r}=await a.rpc("has_role",{_user_id:e.id,_role:"admin"});return r===!0}catch{return!1}}async function Oe(e){try{if(!await P())throw new Error("Vous devez être administrateur pour effectuer cette action");if(!e.title?.trim())throw new Error("Le titre du poste est obligatoire");if(!e.experience_years?.trim())throw new Error("L'expérience requise est obligatoire");if(!e.department?.trim()&&(!e.domains||e.domains.length===0))throw new Error("Le domaine / spécialité est obligatoire");if(!e.application_url?.trim())throw new Error("L'URL ou email de candidature est obligatoire");const t=/^https?:\/\/.+/,n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,i=e.application_url.trim();if(!t.test(i)&&!n.test(i))throw new Error("L'URL de candidature doit être valide (http:// ou https://) ou un email");let o={...e};if(e.structure_type&&e.structure_type!=="law_firm"&&e.employer_name?.trim()&&!e.id_firm){const f=await ge(e.employer_name.trim(),e.structure_type);if(!f.success)throw new Error(f.error);o.id_firm=f.firmId,o.employer_name=null}const{data:s,error:c}=await a.from("job_offers").insert({...o,title:o.title.trim(),status:"approved",is_active:!0,published_at:new Date().toISOString()}).select().single();if(c)throw new Error(c.message);return{success:!0,data:s}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function xe(e,r){try{if(!await P())throw new Error("Vous devez être administrateur pour effectuer cette action");if(!e)throw new Error("L'identifiant de l'offre est obligatoire");if(r.title!==void 0&&!r.title?.trim())throw new Error("Le titre du poste est obligatoire");if(r.experience_years!==void 0&&!r.experience_years?.trim())throw new Error("L'expérience requise est obligatoire");if(r.department!==void 0&&!r.department?.trim())throw new Error("Le domaine / spécialité est obligatoire");if(r.application_url!==void 0){if(!r.application_url?.trim())throw new Error("L'URL ou email de candidature est obligatoire");const o=/^https?:\/\/.+/,s=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,c=r.application_url.trim();if(!o.test(c)&&!s.test(c))throw new Error("L'URL de candidature doit être valide (http:// ou https://) ou un email")}const{data:n,error:i}=await a.from("job_offers").update({...r,title:r.title?.trim()??void 0}).eq("id",e).select().single();if(i)throw new Error(i.message);if(!n)throw new Error("Offre non trouvée");return{success:!0,data:n}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function je(e,r){try{if(!await P())throw new Error("Vous devez être administrateur pour effectuer cette action");if(!e)throw new Error("L'identifiant de l'offre est obligatoire");const{error:n}=await a.from("job_offers").update({status:r,is_active:r==="approved",published_at:r==="approved"?new Date().toISOString():void 0}).eq("id",e);if(n)throw new Error(n.message);if(r==="approved"){const{data:i}=await a.from("job_offers").select("id_firm, title").eq("id",e).single();i?.id_firm&&B(e,i.id_firm,i.title||"").catch(()=>{})}return{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function Te(e){try{if(!await P())throw new Error("Admin requis");
42let t=a.from("job_offers").select("id").eq("status","pending");const{data:n,error:i}=await t;if(i)throw i;if(!n||n.length===0)return{success:!0,count:0};const o=n.map(f=>f.id),s=new Date().toISOString(),{error:c}=await a.from("job_offers").update({status:"approved",is_active:!0,published_at:s}).in("id",o);if(c)throw c;if(o.length>0){const{data:f}=await a.from("job_offers").select("id, id_firm, title").in("id",o).not("id_firm","is",null);if(f){const _=new Set;for(const g of f)g.id_firm&&!_.has(g.id_firm)&&(_.add(g.id_firm),B(g.id,g.id_firm,g.title||"").catch(()=>{}))}}return{success:!0,count:o.length}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function Be(e){try{const{data:r,error:t}=await a.from("job_offers").select("id_firm").eq("id",e).single();if(t)throw new Error(t.message);if(!r)throw new Error("Offre introuvable");if(r.id_firm){const i=await M(r.id_firm);if(!i.success||!i.canManage)throw new Error("Vous n'avez pas les droits pour supprimer cette offre")}const{error:n}=await a.from("job_offers").delete().eq("id",e);if(n)throw new Error(n.message);return{success:!0}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function Fe(e){try{const{data:r,error:t}=await a.from("public_job_offers").select("*").eq("id_firm",e).order("published_at",{ascending:!1});if(t)throw new Error(t.message);return{success:!0,data:r||[]}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function Je(){try{const{data:e,error:r}=await a.rpc("get_admin_dashboard_stats");if(r)throw r;const t=e?.[0],{data:n,error:i}=await a.rpc("get_recent_reviews_admin",{p_limit:10});if(i)throw i;return{success:!0,data:{totalReviews:Number(t?.total_reviews||0),pendingReviews:Number(t?.pending_reviews||0),approvedReviews:Number(t?.approved_reviews||0),rejectedReviews:Number(t?.rejected_reviews||0),moderatedReviews:Number(t?.moderated_reviews||0),totalFirms:Number(t?.total_firms||0),totalDepartments:Number(t?.total_departments||0),recentReviews:(n||[]).map(Y)}}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue"}}}async function ze(){try{const{data:{user:e}}=await a.auth.getUser();if(!e)throw new Error("Non authentifié");const{data:r,error:t}=await a.rpc("get_pending_reviews_admin_v2");if(t)throw t;return{success:!0,data:(r||[]).map(Y)}}catch(e){return console.error("[getPendingReviews] Error:",e),{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue"}}}async function We(e,r,t){try{const{data:{user:n}}=await a.auth.getUser();if(!n)throw new Error("Non authentifié");const{data:i}=await a.from("user_roles").select("role").eq("user_id",n.id).eq("role","admin").single();if(!i)throw new Error("Accès refusé: droits administrateur requis");const{error:o}=await a.from("review").update({status:r,moderated_at:new Date().toISOString(),moderated_by:n.id,moderation_notes:t||null}).eq("id",e);if(o)throw o;if(r==="approved")try{const{data:s}=await a.from("review").select(`
43            id,
44            id_firm,
45            culture_rating,
46            compensation_rating,
47            pride_rating,
48            wellbeing_rating,
49            management_rating,
50            atmosphere_rating,
51            worklifebalance_rating,
52            firm:firm!inner(id, name, slug, recruitment_email)
53          `).eq("id",e).single();if(s?.firm){const c=[s.culture_rating,s.compensation_rating,s.pride_rating,s.wellbeing_rating,s.management_rating,s.atmosphere_rating,s.worklifebalance_rating].filter(v=>v!=null),f=c.length>0?Math.round(c.reduce((v,S)=>v+S,0)/c.length*10)/10:null,_=s.firm;let g=_.recruitment_email,b=_.name;if(!g){const{data:v}=await a.from("user_roles").select("user_id").eq("firm_id",s.id_firm).eq("role","firm_manager").limit(1).single();if(v?.user_id){const{data:S}=await a.from("profiles").select("email, full_name").eq("id",v.user_id).single();S?.email&&(g=S.email,b=S.full_name||_.name)}}g&&await a.functions.invoke("send-email",{body:{type:"new_review_notification",to:g,name:b,data:{firmName:_.n
53ame,firmSlug:_.slug,averageRating:f}}})}}catch(s){console.error("Error sending review notification email:",s)}return{success:!0}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function Ve(e,r,t,n=!0){try{const{data:{user:i}}=await a.auth.getUser();if(!i)throw new Error("Non authentifié");const{data:o}=await a.from("user_roles").select("role").eq("user_id",i.id).eq("role","admin").single();if(!o)throw new Error("Accès refusé: droits administrateur requis");const{data:s}=await a.from("review").select("experience_summary, original_experience_summary").eq("id",e).single(),c={experience_summary:r,moderation_notes:t||null,moderated_at:new Date().toISOString(),moderated_by:i.id};s&&!s.original_experience_summary&&(c.original_experience_summary=s.experience_summary),n&&(c.status="approved");const{error:f}=await a.from("review").update(c).eq("id",e);if(f)throw f;return{success:!0}}catch(i){return{success:!1,error:i instanceof Error?i.message:"Une erreur est survenue"}}}async function Ge(e){try{const{data:{user:r}}=await a.auth.getUser();if(!r)throw new Error("Non authentifié");const{data:t}=await a.from("user_roles").select("role").eq("user_id",r.id).eq("role","admin").single();if(!t)throw new Error("Accès refusé: droits administrateur requis");const{error:n}=await a.from("review").delete().eq("id",e);if(n)throw n;return{success:!0}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function He(){try{const{data:{user:e}}=await a.auth.getUser();if(!e)throw new Error("Non authentifié");const{data:r}=await a.from("user_roles").select("role").eq("user_id",e.id).eq("role","admin").single();if(!r)throw new Error("Accès refusé: droits administrateur requis");const{data:t,error:n}=await a.from("review_reports").select(`
54        id,
55        review_id,
56        reported_by_email,
57        reason,
58        description,
59        created_at,
60        status,
61        review:review_id(
62          id,
63          role,
64          experience_summary,
65          status,
66          created_at,
67          email,
68          firm:id_firm(id, name),
69          department:id_department(id, name)
70        )
71      `).eq("status","pending").order("created_at",{ascending:!1});if(n)throw n;return{success:!0,data:t||[]}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue"}}}async function Ke(e,r,t){try{const{data:{user:n}}=await a.auth.getUser();if(!n)throw new Error("Non authentifié");const{data:i}=await a.from("user_roles").select("role").eq("user_id",n.id).eq("role","admin").single();if(!i)throw new Error("Accès refusé: droits administrateur requis");const{data:o}=await a.from("review_reports").select("reported_by_email, review:review_id(firm:id_firm(name))").eq("id",e).single(),{error:s}=await a.from("review_reports").update({status:r,reviewed_by:n.id,reviewed_at:new Date().toISOString()}).eq("id",e);if(s)throw s;let c=!1;if(t?.notifyReporter&&o?.reported_by_email)try{const f=o.review?.firm?.name;await a.functions.invoke("send-email",{body:{type:r==="reviewed"?"review_report_reviewed":"review_report_dismissed",to:o.reported_by_email,data:{firmName:f,adminMessage:t.adminMessage?.trim()||void 0}}}),c=!0}catch(f){console.error("Failed to send report notification email",f)}return{success:!0,emailSent:c}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function Ye(e,r,t){try{const{data:{user:n}}=await a.auth.getUser();if(!n)throw new Error("Non authentifié");if(!t||t.trim().length<10)throw new Error("La réponse doit contenir au moins 10 caractères");const{error:i}=await a.from("review_responses").insert({review_id:e,firm_id:r,response_text:t.trim(),created_by:n.id});if(i)throw i;return{success:!0}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function Ze(e){try{if(e.length===0)return{success:!0,data:[]};const{data:r,error:t}=await a.from("review_responses").select(`
72        id,
73        review_id,
74        firm_id,
75        response_text,
76        created_at,
77        updated_at,
78        firm:firm_id (
79          name,
80          logo_url
81        )
82      `).in("review_id",e).order("created_at",{ascending:!0});if(t)throw t;return{success:!0,data:r||[]}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue",data:[]}}}async function Xe(e,r){try{const{data:{user:t}}=await a.auth.getUser();if(!t)throw new Error("Vous devez être connecté");const{data:n}=await a.rpc("can_manage_firm",{_user_id:t.id,_firm_id:e});if(!n)throw new Error("Vous n'avez pas les droits pour gérer ce cabinet");const i=r.map((c,f)=>a.from("firm_team_members").update({display_order:f}).eq("id",c).eq("id_firm",e));if((await Promise.all(i)).filter(c=>c.error).length>0)throw new Error("Erreur lors de la mise à jour de l'ordre");return{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function Qe(){try{const{data:{user:e}}=await a.auth.getUser();if(!e)throw new Error("Non authentifié");const{data:r,error:t}=await a.rpc("get_pending_job_offers_admin");if(t)throw t;return{success:!0,data:(r||[]).map(i=>({id:i.id,title:i.title,city:i.city,contract_type:i.contract_type,description:i.description,application_url:i.application_url,submitter_email:i.submitter_email,submitter_name:i.submitter_name,status:i.status,is_active:i.is_active,created_at:i.created_at,firm:i.id_firm?{id:i.id_firm,name:i.firm_name||"Cabinet inconnu"}:null}))}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue",data:[]}}}async function B(e,r,t){try{const{data:n}=await a.from("firm").select("name, slug, recruitment_email").eq("id",r).single();if(!n)return;let i=n.recruitment_email;if(!i||i==="NOT_FOUND"){const{data:c}=await a.from("user_roles").select("user_id").eq("firm_id",r).eq("role","firm_manager").limit(1);if(c&&c.length>0){const{data:f}
82=await a.from("profiles").select("email").eq("id",c[0].user_id).single();i=f?.email||null}}if(!i||i==="NOT_FOUND"){console.log(`[notifyFirm] No email for ${n.name}, triggering on-demand discovery...`);try{const{data:c}=await a.functions.invoke("find-firm-emails",{body:{firm_id:r}});c?.email_found&&(i=c.email_found,console.log(`[notifyFirm] Discovered email for ${n.name}: ${i}`))}catch(c){console.warn(`[notifyFirm] Email discovery failed for ${n.name}:`,c)}}if(!i||i==="NOT_FOUND")return;const o=new Date;o.setDate(o.getDate()-30);const{data:s}=await a.from("firm_outreach_logs").select("id").eq("firm_id",r).eq("email_type","job_offer_published").gte("sent_at",o.toISOString()).limit(1);if(s&&s.length>0){console.log(`[notifyFirm] Skipping ${n.name}: already notified within 30 days`);return}await a.functions.invoke("send-email",{body:{type:"job_offer_published_to_firm",to:i,name:n.name,data:{firmName:n.name,firmSlug:n.slug,offerTitle:t||"Nouvelle offre",offerId:e}}}),await a.from("firm_outreach_logs").insert({firm_id:r,email_sent_to:i,email_type:"job_offer_published",metadata:{offer_id:e,offer_title:t}}),console.log(`[notifyFirm] Email sent to ${i} for ${n.name}`)}catch(n){console.error("[notifyFirm] Error:",n)}}async function Ie(e,r){try{const{data:{user:t}}=await a.auth.getUser();if(!t)throw new Error("Non authentifié");const{data:n,error:i}=await a.from("job_offers").select("id_firm, submitter_email, title").eq("id",e).single();if(i)throw i;const o=r==="approved"?{status:"approved",is_active:!0,published_at:new Date().toISOString()}:{status:"rejected",is_active:!1},{error:s}=await a.from("job_offers").update(o).eq("id",e);if(s)throw s;if(r==="approved"&&n?.id_firm&&n?.submitter_email){const{data:c}=await a.from("profiles").select("id").eq("email",n.submitter_email).maybeSingle();c?.id&&await we(c.id,n.id_firm)}return r==="approved"&&n?.id_firm&&B(e,n.id_firm,"").catch(()=>{}),{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function er(e,r,t){try{const{data:{user:n}}=await a.auth.getUser();if(!n)throw new Error("Non authentifié");const{data:i}=await a.from("user_roles").select("role").eq("user_id",n.id).eq("role","admin").single();if(!i)throw new Error("Accès non autorisé - Admin requis");const o={is_urgent:r,urgent_until:r?t||new Date(Date.now()+10080*60*1e3).toISOString():null},{error:s}=await a.from("job_offers").update(o).eq("id",e);if(s)throw s;return{success:!0}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function rr(){try{const{data:e,error:r}=await a.rpc("get_all_job_offers_admin");if(r)throw r;return{success:!0,data:(e||[]).map(n=>({...n,firm:n.firm_id?{id:n.firm_id,name:n.firm_name||"Cabinet inconnu",structure_type:n.firm_structure_type||null}:null}))}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue"}}}async function tr(e,r){try{const{data:{user:t}}=await a.auth.getUser();if(!t)throw new Error("Non authentifié");const{data:n}=await a.from("user_roles").select("role").eq("user_id",t.id).eq("role","admin").single();if(!n)throw new Error("Accès non autorisé - Admin requis");const i={is_active:r};r||(i.is_urgent=!1,i.urgent_until=null);const{error:o}=await a.from("job_offers").update(i).eq("id",e);if(o)throw o;return{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function ir(e){try{const{data:r,error:t}=await a.from("firm_subscriptions").select("*").eq("firm_id",e).maybeSingle();if(t)throw t;return{success:!0,data:r}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function Ee(e,r="free",t="active"){try{const{data:n}=await a.auth.getUser();if(!n?.user?.id)throw new Error("Non authentifié");const{data:i}=await a.from("firm_subscriptions").select("id").eq("firm_id",e).maybeSingle();if(i){const{data:o,error:s}=await a.from("firm_subscriptions").update({plan_type:r,status:t,approved_at:t==="active"?new Date().toISOString():null,approved_by:t==="active"?n.user.id:null}).eq("firm_id",e).select().single();if(s)throw s;return{success:!0,data:o}}else{const{data:o,error:s}=await a.from("firm_subscriptions").insert({firm_id:e,plan_type:r,status:t,approved_at:t==="active"?new Date().toISOString():null,approved_by:t==="active"?n.user.id:null}).select().single();if(s)throw s;return{success:!0,data:o}}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function nr(e,r,t){try{const{data:n}=await a.auth.getUser();if(!n?.user?.id)throw new Error("Non authentifié");let i=r;if(i)await a.from("firm").update({is_verified:!0}).eq("id",i);else{const{data:c}=await a.from("firm").select("id").ilike("name",t.trim()).maybeSingle();if(c)i=c.id;else{const{data:f,error:_}=await a.from("firm").insert([{name:t.trim(),is_specialized:!0,is_verified:!0,slug:""}]).select("id").single();if(_)throw new Error(`Échec création cabinet: ${_.message}`);i=f.id}}const o=await Ee(i,"free","active");if(!o.success)throw new Error(o.error);const{error:s}=await a.from("cabinet_contact_requests").update({status:"approved"}).eq("id",e);if(s)throw s;return{success:!0,firmId:i,subscriptionId:o.data.id}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Une erreur est survenue"}}}async function sr(e){try{const{data:r,error:t}=await a.from("job_offer_credits").select("*").eq("firm_id",e).or("expires_at.is.null,expires_at.gt.now()");if(t)throw t;return{success:!0,data:{totalCredits:(r||[]).reduce((i,o)=>i+(o.credits_remaining||0),0),creditDetails:r||[]}}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function ar(e){try{const{data:r}=await a.from("job_offer_credits").select("id").eq("firm_id",e).eq("credit_type","free_first");
82if(r&&r.length>0)return{success:!0};const{error:t}=await a.from("job_offer_credits").insert({firm_id:e,credit_type:"free_first",credits_remaining:1});if(t)throw t;return{success:!0}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function or(e,r){try{const{error:t}=await a.from("firm_competitors").upsert({firm_id:e,competitor_firm_id:r},{onConflict:"firm_id,competitor_firm_id"});if(t)throw t;return{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Erreur lors de la sauvegarde"}}}async function cr(e,r){try{const{error:t}=await a.from("firm_competitors").delete().eq("firm_id",e).eq("competitor_firm_id",r);if(t)throw t;return{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Erreur lors de la suppression"}}}async function ur(e){try{const{data:r,error:t}=await a.from("firm_competitors").select("competitor_firm_id").eq("firm_id",e);if(t)throw t;return{success:!0,data:(r||[]).map(n=>n.competitor_firm_id)}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Erreur lors du chargement"}}}async function lr(e){if(e.length===0)return{success:!0,data:[]};try{const{data:r,error:t}=await a.from("firm").select(`
83        id,
84        name,
85        review (
86          culture_rating,
87          compensation_rating,
88          pride_rating,
89          wellbeing_rating,
90          management_rating,
91          atmosphere_rating,
92          worklifebalance_rating,
93          training_rating,
94          remote_work,
95          would_recommend,
96          would_return,
97          recruitment_rating,
98          recruitment_interview_count,
99          recruitment_duration,
100          turnover,
101          status
102        )
103      `).in("id",e);if(t)throw t;return r?{success:!0,data:r.map(i=>{const o=(Array.isArray(i.review)?i.review:[]).filter(_=>_.status==="approved"),s=o.reduce((_,g)=>({culture:_.culture+(g.culture_rating||0),compensation:_.compensation+(g.compensation_rating||0),pride:_.pride+(g.pride_rating||0),wellbeing:_.wellbeing+(g.wellbeing_rating||0),management:_.management+(g.management_rating||0),atmosphere:_.atmosphere+(g.atmosphere_rating||0),worklifebalance:_.worklifebalance+(g.worklifebalance_rating||0),training:_.training+(g.training_rating||0)}),{culture:0,compensation:0,pride:0,wellbeing:0,management:0,atmosphere:0,worklifebalance:0,training:0}),c=o.length||1,f=o.filter(_=>_.training_rating&&_.training_rating>0);return{id:i.id,name:i.name,ratings:{culture:s.culture/c,compensation:s.compensation/c,pride:s.pride/c,wellbeing:s.wellbeing/c,management:s.management/c,atmosphere:s.atmosphere/c,worklifebalance:s.worklifebalance/c,training:f.length>0?s.training/f.length:5},reviewCount:o.length,hrIndicators:X(o)}})}:{success:!0,data:[]}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Une erreur est survenue"}}}async function mr(e){try{const{data:r,error:t}=await a.from("review").select("remote_work, would_recommend, would_return, recruitment_rating, recruitment_interview_count, recruitment_duration, turnover").eq("id_firm",e).eq("status","approved");if(t)throw t;return{success:!0,data:X(r||[])}}catch(r){return{success:!1,error:r instanceof Error?r.message:"Erreur"}}}function X(e){if(e.length===0)return{remoteWorkPercent:null,wouldRecommendPercent:null,wouldReturnPercent:null,recruitmentRating:null,avgInterviewCount:null,avgRecruitmentDuration:null,turnoverDistribution:null};const r=e.filter(l=>l.remote_work),t=r.filter(l=>l.remote_work==="libre"||l.remote_work==="occasionnel").length,n=r.length>0?Math.round(t/r.length*100):null,i=e.filter(l=>l.would_recommend),o=i.filter(l=>l.would_recommend==="oui").length,s=i.length>0?Math.round(o/i.length*100):null,c=e.filter(l=>l.would_return),f=c.filter(l=>l.would_return==="oui").length,_=c.length>0?Math.round(f/c.length*100):null,g=e.filter(l=>l.recruitment_rating!=null).map(l=>l.recruitment_rating),b=g.length>0?g.reduce((l,h)=>l+h,0)/g.length:null,v=e.filter(l=>l.recruitment_interview_count!=null).map(l=>l.recruitment_interview_count),S=v.length>0?Math.round(v.reduce((l,h)=>l+h,0)/v.length*10)/10:null,m=e.filter(l=>
103l.recruitment_duration).map(l=>l.recruitment_duration);let w=null;if(m.length>0){const l={};m.forEach(h=>{l[h]=(l[h]||0)+1}),w=Object.entries(l).sort((h,q)=>q[1]-h[1])[0][0]}const E=e.filter(l=>l.turnover);let u=null;if(E.length>0){const l=E.filter(p=>p.turnover==="fort").length,h=E.filter(p=>p.turnover==="raisonnable").length,q=E.filter(p=>p.turnover==="ne-sais-pas").length;u={fort:Math.round(l/E.length*100),raisonnable:Math.round(h/E.length*100),neSaisPas:Math.round(q/E.length*100)}}return{remoteWorkPercent:n,wouldRecommendPercent:s,wouldReturnPercent:_,recruitmentRating:b,avgInterviewCount:S,avgRecruitmentDuration:w,turnoverDistribution:u}}async function fr(e,r){try{if(!e||!r)throw new Error("IDs des cabinets requis");if(e===r)throw new Error("Impossible de fusionner un cabinet avec lui-même");const{data:{user:t}}=await a.auth.getUser();if(!t)throw new Error("Non authentifié");const{data:n}=await a.rpc("has_role",{_user_id:t.id,_role:"admin"});if(!n)throw new Error("Seuls les administrateurs peuvent fusionner des cabinets");const{data:i}=await a.from("firm").select("name, slug").eq("id",r).single();if(!i)throw new Error("Cabinet doublon introuvable");const{data:o}=await a.from("firm").select("name, slug").eq("id",e).single();if(!o)throw new Error("Cabinet principal introuvable");const{error:s}=await a.from("review").update({id_firm:e}).eq("id_firm",r);if(s)throw new Error(`Erreur lors du transfert des avis: ${s.message}`);const{error:c}=await a.from("department").update({id_firm:e}).eq("id_firm",r);if(c)throw new Error(`Erreur lors du transfert des départements: ${c.message}`);const{error:f}=await a.from("firm_team_members").update({id_firm:e}).eq("id_firm",r);f&&console.warn(`Avertissement équipe: ${f.message}`);const{error:_}=await a.from("firm_events").update({id_firm:e}).eq("id_firm",r);_&&console.warn(`Avertissement événements: ${_.message}`);const{error:g}=await a.from("job_offers").update({id_firm:e}).eq("id_firm",r);g&&console.warn(`Avertissement offres d'emploi: ${g.message}`);{const{data:m}=await a.from("cabinet_benefits").select("id").eq("cabinet_id",e).maybeSingle();m?await a.from("cabinet_benefits").delete().eq("cabinet_id",r):await a.from("cabinet_benefits").update({cabinet_id:e}).eq("cabinet_id",r)}{const{data:m}=await a.from("cabinet_culture").select("id").eq("cabinet_id",e).maybeSingle();m?await a.from("cabinet_culture").delete().eq("cabinet_id",r):await a.from("cabinet_culture").update({cabinet_id:e}).eq("cabinet_id",r)}await a.from("firm_competitors").update({firm_id:e}).eq("firm_id",r),await a.from("firm_competitors").update({competitor_firm_id:e}).eq("competitor_firm_id",r),await a.from("firm_competitors").delete().eq("firm_id",e).eq("competitor_firm_id",e);{const{data:m}=await a.from("firm_subscriptions").select("id").eq("firm_id",e).maybeSingle();m?await a.from("firm_subscriptions").delete().eq("firm_id",r):await a.from("firm_subscriptions").update({firm_id:e}).eq("firm_id",r)}await a.from("user_roles").update({firm_id:e}).eq("firm_id",r).eq("role","firm_manager");const{error:b}=await a.from("salary_contributions").update({firm_id:e}).eq("firm_id",r);if(b)throw new Error(`Erreur lors du transfert des rémunérations: ${b.message}`);const v=[{table:"job_applications",column:"firm_id"},{table:"spontaneous_applications",column:"firm_id"},{table:"candidate_favorites",column:"firm_id"},{table:"candidate_saved_jobs",column:"firm_id"},{table:"firm_page_views",column:"firm_id"},{table:"firm_evolution_votes",column:"firm_id"},{table:"firm_events",column:"id_firm"},{table:"firm_reputation_synthesis",column:"firm_id"},{table:"firm_external_review_snippets",column:"firm_id"},{table:"firm_data_reports",column:"firm_id"},{table:"firm_admin_requests",column:"firm_id"},{table:"firm_audit_campaigns",column:"firm_id"},{table:"firm_onboarding_data",column:"firm_id"},{table:"firm_outreach_logs",column:"firm_id"},{table:"rank_snapshot",column:"firm_id"},{table:"review_reports",column:"firm_id"}];for(const m of v){const{error:w}=await a.from(m.table).update({[m.column]:e}).eq(m.column,r);w&&!/does not exist|column .* does not exist/i.test(w.message)&&console.warn(`Transfert ${m.table}.${m.column}: ${w.message}`)}i.slug&&i.slug!==o.slug&&await a.from("firm_slug_redirects").upsert({old_
103slug:i.slug,new_slug:o.slug,firm_id:e},{onConflict:"old_slug"});const{error:S}=await a.from("firm").delete().eq("id",r);if(S)throw new Error(`Erreur lors de la suppression du doublon: ${S.message}`);return await a.from("cron_job_logs").insert({job_name:"firm-merge",affected_rows:1,details:{main_firm_id:e,main_firm_name:o.name,duplicate_firm_id:r,duplicate_firm_name:i.name,duplicate_slug:i.slug,merged_by:t.id,merged_at:new Date().toISOString()}}),{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Une erreur est survenue"}}}async function dr(){try{const e=new Date(Date.now()-6048e5).toISOString(),r=new Date(Date.now()-336*60*60*1e3).toISOString(),{data:t,error:n}=await a.rpc("get_commercial_kpis_admin",{p_since:e,p_previous_since:r});if(n)throw n;const i=t?.[0],o=Array.isArray(i?.recruiters_list)?i.recruiters_list.map(_=>({userId:_.userId||"",fullName:_.fullName||"",email:_.email||"",firmId:_.firmId||"",firmName:_.firmName||"",structureType:_.structureType||null,isPremium:!!_.isPremium,createdAt:_.createdAt||""})):[],s=Number(i?.email_total||0),c=Number(i?.email_with_email||0);return{success:!0,data:{reviews:{total:Number(i?.reviews_total||0),pending:Number(i?.reviews_pending||0),last7Days:Number(i?.reviews_last7||0)},firms:{total:Number(i?.firms_total||0),last7Days:Number(i?.firms_last7||0)},newsletter:{total:Number(i?.newsletter_total||0),verified:Number(i?.newsletter_verified||0),last7Days:Number(i?.newsletter_last7||0)},candidates:{total:Number(i?.candidates_total||0),last7Days:Number(i?.candidates_last7||0)},recruiters:{total:Number(i?.recruiters_total||0),premium:Number(i?.recruiters_premium||0),list:o,last7Days:Number(i?.recruiters_last7||0)},jobOffers:{active:Number(i?.active_job_offers||0),urgent:Number(i?.urgent_job_offers||0),last7Days:Number(i?.job_offers_last7||0)},firmViews:{last7Days:Number(i?.firm_views_last7||0),previous7Days:Number(i?.firm_views_previous7||0)},blog:{totalArticles:Number(i?.blog_total_articles||0),totalViews:Number(i?.blog_total_views||0),last7Days:Number(i?.blog_last7||0)},emailCoverage:{withEmail:c,total:s,percentage:s>0?Math.round(c/s*100):0}}}}catch(e){return console.error("Error loading commercial KPIs:",e),{success:!1,error:e instanceof Error?e.message:"Erreur lors du chargement des KPIs"}}}async function _r(){try{const e=[];let r=0;const t=1e3;let n=!0;for(;n;){const{data:s,error:c}=await a.rpc("get_explore_firms").range(r,r+t-1);if(c)throw new Error(`Erreur lors du chargement des structures: ${c.message}`);s&&s.length>0?(e.push(...s),r+=t,n=s.length===t):n=!1}const o=(e||[]).map(s=>({id:s.id,name:s.name,slug:s.slug,logo_url:s.logo_url,cover_image_url:s.cover_image_url,tagline:s.tagline,description:s.description,structure_type:s.structure_type,is_premium:s.is_premium,is_verified:s.is_verified,cities:s.cities,domain:s.departments&&s.departments.length>0?s.departments:s.domain,departments:s.departments||[],employee_count:s.employee_count,office_photos:s.office_photos,firm_photos:s.firm_photos,avg_rating:s.avg_rating!=null&&Number(s.avg_rating)>0?Number(s.avg_rating):null,review_count:s.review_count||0,job_count:Number(s.job_count)||0,transparency_score:Math.min(s.transparency_score||0,100)}));return{success:!0,data:o,total:o.length}}catch(e){return console.error("Error in fetchExploreFirms:",e),{success:!1,error:e instanceof Error?e.message:"Une erreur est survenue"}}}async function gr(e,r,t,n="annual_gross",i,o,s,c){try{if(!e||!r||!t)throw new Error("Firm, rôle et tranche sont requis");const{error:f}=await a.from("salary_contributions").insert([{firm_id:e,role:r,salary_range:t,salary_type:n,start_year:i||null,city:o||null,bonus_range:s||null,comment:c||null}]);if(f)throw new Error(f.message);return{success:!0}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Erreur"}}}async function wr(e,r){try{const{error:t}=await a.from("review").update({salary_range:r}).eq("id",e);if(t)throw new Error(t.message);return{success:!0}}catch(t){return{success:!1,error:t instanceof Error?t.message:"Erreur"}}}async function pr(){try{let e=function(m){return m<3e4?"< 30k":m<45e3?"30-45k":m<6e4?"45-60k":m<8e4?"60-80k":m<1e5?"80-100k":m<13e4?"100-130k":"130k+"};const{data:r,error:t}=await a.from("salary_contributions").select("firm_id, role, salary_range, city, bonus_range, created_at, comment");
103if(t)throw new Error(t.message);const{data:n,error:i}=await a.from("review").select("id_firm, role, salary_amount, salary_range, city").or("salary_amount.not.is.null,salary_range.not.is.null").eq("status","approved");if(i)throw new Error(i.message);const{data:o,error:s}=await a.from("firm").select("id, name, slug, logo_url, domain, structure_type, employee_count");if(s)throw new Error(s.message);const c=new Map(o?.map(m=>[m.id,{name:m.name,slug:m.slug,logoUrl:m.logo_url,domains:m.domain,structureType:m.structure_type,employeeCount:m.employee_count}])||[]),f=new Map,_=(m,w,E,u,l,h,q)=>{if(K.includes(m))return;const p=c.get(m);if(!p||p.structureType==="recruitment_firm")return;const R=`${m}|${w}|${E}`,A=f.get(R);A?(A.count++,q&&A.comments.push(q)):f.set(R,{firmId:m,firmName:p.name,firmSlug:p.slug,firmLogoUrl:p.logoUrl,firmDomains:p.domains||[],firmStructureType:p.structureType||"law_firm",firmEmployeeCount:p.employeeCount||null,role:w,salaryRange:E,count:1,city:u||void 0,bonusRange:l||void 0,createdAt:h||void 0,comment:q||void 0,comments:q?[q]:[]})};r?.forEach(m=>{_(m.firm_id,m.role,m.salary_range,m.city,m.bonus_range,m.created_at,m.comment)}),n?.forEach(m=>{const w=m.salary_range||(m.salary_amount?e(m.salary_amount):null);w&&_(m.id_firm,m.role,w,m.city)});const{data:g}=await a.from("job_offers").select("id_firm, salary_range, department, experience_years, employer_name, city").eq("status","approved").eq("is_active",!0).not("salary_range","is",null),b=m=>{if(!m)return null;const w=m.toLowerCase().replace(/\s/g,"");if(w.includes("moins-40k")||w.includes("<40"))return"30-45k";if(w.includes("40k-50k")||w.includes("40-50")||w.includes("50k-60k")||w.includes("50-60"))return"45-60k";if(w.includes("60k-80k")||w.includes("60-80"))return"60-80k";if(w.includes("80k-100k")||w.includes("80-100"))return"80-100k";if(w.includes("plus-100k")||w.includes(">100")||w.includes("100k"))return"100-130k";const E=m.match(/(\d{2,3})\s*[k€]/i);if(E){const u=parseInt(E[1],10),l=u<300?u*1e3:u;return e(l)}return null},v=m=>{if(!m)return"collaborateur-1-4-ans";const w=m.toLowerCase();return w.includes("stage")||w.includes("0")?"stagiaire":w.includes("1")||w.includes("2")||w.includes("3")||w.includes("débutant")||w.includes("junior")?"collaborateur-1-4-ans":w.includes("5")||w.includes("6")||w.includes("7")||w.includes("8")||w.includes("9")||w.includes("10")?"collaborateur-5-10-ans":w.includes("15")||w.includes("20")?"collaborateur-11-20-ans":"collaborateur-1-4-ans"};return(g||[]).forEach(m=>{const w=b(m.salary_range);if(!w)return;const E=m.id_firm;if(!E)return;const u=v(m.experience_years);_(E,u,w,m.city)}),{success:!0,data:Array.from(f.values())}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Erreur"}}}async function hr(){try{const{data:e,error:r}=await a.functions.invoke("backfill-recruitment-emails",{body:{}});return r?{success:!1,error:r.message}:e}catch(e){return{success:!1,error:e instanceof Error?e.message:"Erreur inconnue"}}}export{hr as A,dr as B,Je as C,ze as D,He as E,Qe as F,Ie as G,nr as H,ar as I,We as J,Ve as K,Ge as L,Ke as M,Ye as N,ur as O,mr as P,lr as Q,cr as R,or as S,Pe as T,Xe as U,Oe as V,ge as W,ir as X,sr as Y,pr as Z,be as a,gr as b,De as c,Le as d,pe as e,_r as f,Ce as g,ke as h,Ne as i,Me as j,Fe as k,Ue as l,Ae as m,Ze as n,xe as o,L as p,$e as q,je as r,ve as s,rr as t,wr as u,Te as v,er as w,tr as x,Be as y,fr as z};

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.