"use strict";(()=>{var e={};e.id=4835,e.ids=[4835],e.modules={53524:e=>{e.exports=require("@prisma/client")},98432:e=>{e.exports=require("bcryptjs")},72934:e=>{e.exports=require("next/dist/client/components/action-async-storage.external.js")},54580:e=>{e.exports=require("next/dist/client/components/request-async-storage.external.js")},45869:e=>{e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},20399:e=>{e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},30517:e=>{e.exports=require("next/dist/compiled/next-server/app-route.runtime.prod.js")},27790:e=>{e.exports=require("assert")},78893:e=>{e.exports=require("buffer")},61282:e=>{e.exports=require("child_process")},84770:e=>{e.exports=require("crypto")},80665:e=>{e.exports=require("dns")},17702:e=>{e.exports=require("events")},92048:e=>{e.exports=require("fs")},20629:e=>{e.exports=require("fs/promises")},32615:e=>{e.exports=require("http")},35240:e=>{e.exports=require("https")},98216:e=>{e.exports=require("net")},19801:e=>{e.exports=require("os")},55315:e=>{e.exports=require("path")},86624:e=>{e.exports=require("querystring")},76162:e=>{e.exports=require("stream")},82452:e=>{e.exports=require("tls")},17360:e=>{e.exports=require("url")},21764:e=>{e.exports=require("util")},71568:e=>{e.exports=require("zlib")},83671:(e,t,a)=>{a.r(t),a.d(t,{originalPathname:()=>A,patchFetch:()=>R,requestAsyncStorage:()=>f,routeModule:()=>g,serverHooks:()=>N,staticGenerationAsyncStorage:()=>w});var n={};a.r(n),a.d(n,{GET:()=>h,POST:()=>y});var s=a(73278),r=a(45002),o=a(54877),i=a(71309),l=a(18445),u=a(73275),c=a(82208),d=a(37642),p=a(73381);let m=d.Ry({firstName:d.Z_().min(1).max(100),lastName:d.Z_().min(1).max(100),email:d.Z_().email().optional().or(d.i0("")),phone:d.Z_().max(20).optional().or(d.i0("")),password:d.Z_().min(8).optional().or(d.i0("")),propertyId:d.Z_().cuid().optional(),unitId:d.Z_().cuid(),leaseStartDate:d.Z_().min(1),leaseEndDate:d.Z_().min(1),monthlyRent:d.Rx().positive(),securityDeposit:d.Rx().min(0).optional(),rentDueDay:d.Rx().min(1).max(31).optional(),emergencyContactName:d.Z_().max(200).optional().or(d.i0("")),emergencyContactPhone:d.Z_().max(20).optional().or(d.i0("")),emergencyContactRelationship:d.Z_().max(50).optional().or(d.i0("")),notes:d.Z_().optional().or(d.i0(""))});async function h(e){try{let t,a;let n=await (0,l.getServerSession)(u.Lz);if(!n?.user?.companyId)return i.NextResponse.json({error:"Unauthorized"},{status:401});let{searchParams:s}=new URL(e.url),r=parseInt(s.get("page")||"1"),o=parseInt(s.get("limit")||"10"),d=s.get("status"),p=s.get("propertyId"),m=s.get("unitId"),h=s.get("search"),y=(r-1)*o,g={companyId:n.user.companyId,deletedAt:null};if(d&&(g.status=d),p&&(g.unit={propertyId:p}),m&&(g.unitId=m),h&&(g.OR=[{firstName:{contains:h,mode:"insensitive"}},{lastName:{contains:h,mode:"insensitive"}},{email:{contains:h,mode:"insensitive"}},{phone:{contains:h,mode:"insensitive"}}]),h){let e=`
        SELECT COUNT(*) as count FROM tenants
        WHERE companyId = ?
        AND deletedAt IS NULL
      `,a=[n.user.companyId];d&&(e+=" AND status = ?",a.push(d)),p&&(e+=" AND unitId IN (SELECT id FROM units WHERE propertyId = ? AND companyId = ?)",a.push(p,n.user.companyId)),m&&(e+=" AND unitId = ?",a.push(m)),e+=` AND (
        LOWER(firstName) LIKE LOWER(?)
        OR LOWER(lastName) LIKE LOWER(?)
        OR LOWER(email) LIKE LOWER(?)
        OR LOWER(phone) LIKE LOWER(?)
      )`,a.push(`%${h}%`,`%${h}%`,`%${h}%`,`%${h}%`);let s=await c._.$queryRawUnsafe(e,...a);t=Number(s[0].count)}else t=await c._.tenant.count({where:g});if(h){let e=(await c._.$queryRawUnsafe(`
        SELECT id FROM tenants
        WHERE companyId = ?
        AND deletedAt IS NULL
        ${d?"AND status = ?":""}
        ${p?"AND unitId IN (SELECT id FROM units WHERE propertyId = ? AND companyId = ?)":""}
        ${m?"AND unitId = ?":""}
        AND (
          LOWER(firstName) LIKE LOWER(?)
          OR LOWER(lastName) LIKE LOWER(?)
          OR LOWER(email) LIKE LOWER(?)
          OR LOWER(phone) LIKE LOWER(?)
        )
        ORDER BY createdAt DESC
        LIMIT ? OFFSET ?
      `,n.user.companyId,...d?[d]:[],...p?[p,n.user.companyId]:[],...m?[m]:[],`%${h}%`,`%${h}%`,`%${h}%`,`%${h}%`,o,y)).map(e=>e.id);a=0===e.length?[]:await c._.tenant.findMany({where:{id:{in:e},companyId:n.user.companyId,deletedAt:null},include:{unit:{include:{property:{select:{id:!0,name:!0,estate:{select:{name:!0,city:!0}}}}}},payments:{where:{status:{in:["pending","overdue"]}},select:{id:!0,amount:!0,dueDate:!0,status:!0,paymentType:!0},orderBy:{dueDate:"asc"},take:3},maintenanceRequests:{where:{status:{in:["open","in_progress"]}},select:{id:!0,title:!0,priority:!0,status:!0,requestedDate:!0},orderBy:{requestedDate:"desc"},take:3},_count:{select:{payments:!0,maintenanceRequests:!0}}},orderBy:{createdAt:"desc"}})}else a=await c._.tenant.findMany({where:g,include:{unit:{include:{property:{select:{id:!0,name:!0,estate:{select:{name:!0,city:!0}}}}}},payments:{where:{status:{in:["pending","overdue"]}},select:{id:!0,amount:!0,dueDate:!0,status:!0,paymentType:!0},orderBy:{dueDate:"asc"},take:3},maintenanceRequests:{where:{status:{in:["open","in_progress"]}},select:{id:!0,title:!0,priority:!0,status:!0,requestedDate:!0},orderBy:{requestedDate:"desc"},take:3},_count:{select:{payments:!0,maintenanceRequests:!0}}},orderBy:{createdAt:"desc"},skip:y,take:o});let f=a.map(e=>{let t=e.payments.filter(e=>"overdue"===e.status).length,a=e.payments.filter(e=>"pending"===e.status).length,n=e._count.payments,s=e.maintenanceRequests.length,r=new Date,o=new Date(e.leaseEndDate),i=Math.ceil((o.getTime()-r.getTime())/864e5),l="active";return i<0?l="expired":i<=30?l="expiring_soon":i<=90&&(l="expiring_medium"),{...e,metrics:{overduePayments:t,pendingPayments:a,totalPayments:n,activeMaintenanceRequests:s,daysUntilLeaseExpiry:Math.max(0,i),leaseStatus:l}}});return i.NextResponse.json({tenants:f,pagination:{page:r,limit:o,total:t,pages:Math.ceil(t/o)}})}catch(e){return console.error("Error fetching tenants:",e),i.NextResponse.json({error:"Internal server error"},{status:500})}}async function y(e){try{let t;let n=await (0,l.getServerSession)(u.Lz);if(!n?.user?.companyId)return i.NextResponse.json({error:"Unauthorized"},{status:401});if(!["company_admin","company_user"].includes(n.user.role))return i.NextResponse.json({error:"Insufficient permissions"},{status:403});let s=[],r=[];if((e.headers.get("content-type")||"").includes("multipart/form-data")){let a=await e.formData();for(let[e,n]of(t={firstName:a.get("firstName"),lastName:a.get("lastName"),email:a.get("email")||void 0,phone:a.get("phone")||void 0,password:a.get("password")||void 0,propertyId:a.get("propertyId")||void 0,unitId:a.get("unitId"),leaseStartDate:a.get("leaseStartDate"),leaseEndDate:a.get("leaseEndDate"),monthlyRent:parseFloat(a.get("monthlyRent")),securityDeposit:a.get("securityDeposit")?parseFloat(a.get("securityDeposit")):void 0,rentDueDay:a.get("rentDueDay")?parseInt(a.get("rentDueDay")):void 0,emergencyContactName:a.get("emergencyContactName")||void 0,emergencyContactPhone:a.get("emergencyContactPhone")||void 0,emergencyContactRelationship:a.get("emergencyContactRelationship")||void 0,notes:a.get("notes")||void 0},a.entries()))"idDocuments"===e&&n instanceof File&&s.push(n),"tenantDocuments"===e&&n instanceof File&&r.push(n)}else t=await e.json();let o=m.parse(t);if(!await c._.unit.findFirst({where:{id:o.unitId,companyId:n.user.companyId,status:"available"},include:{property:!0}}))return i.NextResponse.json({error:"Unit not found or not available"},{status:404});if(await c._.tenant.findFirst({where:{unitId:o.unitId,status:"active",deletedAt:null}}))return i.NextResponse.json({error:"Unit already has an active tenant"},{status:400});let d=null;o.password&&(d=await (0,u.c_)(o.password));let p=await c._.tenant.create({data:{firstName:o.firstName,lastName:o.lastName,email:o.email||null,phone:o.phone||null,unitId:o.unitId,companyId:n.user.companyId,leaseStartDate:new Date(o.leaseStartDate),leaseEndDate:new Date(o.leaseEndDate),monthlyRent:o.monthlyRent,securityDeposit:o.securityDeposit||null,rentDueDay:o.rentDueDay||1,emergencyContactName:o.emergencyContactName||null,emergencyContactPhone:o.emergencyContactPhone||null,emergencyContactRelationship:o.emergencyContactRelationship||null,notes:o.notes||null,status:"active",moveInDate:new Date(o.leaseStartDate),isPrimaryTenant:!0,passwordHash:d},include:{unit:{include:{property:{select:{id:!0,name:!0,estate:{select:{name:!0,city:!0}}}}}}}}),h=[],y=[...s,...r];if(y.length>0){let{saveUploadedFile:e}=await a.e(4260).then(a.bind(a,94260));try{for(let t of y){let a=await e(t,`tenants/${p.id}/documents`);h.push(a.url)}}catch(e){console.error("Error uploading documents:",e)}}if(h.length>0&&(p=await c._.tenant.update({where:{id:p.id},data:{documents:h},include:{unit:{include:{property:{select:{id:!0,name:!0,estate:{select:{name:!0,city:!0}}}}}}}})),await c._.$executeRaw`
      INSERT INTO wallets (id, userType, tenantId, companyId, currencyId, balance, status, createdAt, updatedAt)
      VALUES (?, 'tenant', ?, ?, 'UGX', 0, 'active', NOW(), NOW())
    `,crypto.randomUUID(),p.id,n.user.companyId,await c._.unit.update({where:{id:o.unitId},data:{status:"occupied"}}),p.email&&o.password)try{let{sendWelcomeEmail:e}=await Promise.all([a.e(6742),a.e(6384)]).then(a.bind(a,36384)),t=await c._.company.findUnique({where:{id:n.user.companyId},select:{name:!0}});await e({email:p.email,firstName:p.firstName,lastName:p.lastName,role:"tenant",companyName:t?.name,unitInfo:{unitNumber:p.unit.unitNumber,propertyName:p.unit.property.name,estateName:p.unit.property.estate.name,monthlyRent:p.monthlyRent}})}catch(e){console.error("Error sending welcome email:",e)}return i.NextResponse.json(p,{status:201})}catch(e){if(e instanceof p.jm)return i.NextResponse.json({error:"Validation error",details:e.errors},{status:400});return console.error("Error creating tenant:",e),i.NextResponse.json({error:"Internal server error"},{status:500})}}let g=new s.AppRouteRouteModule({definition:{kind:r.x.APP_ROUTE,page:"/api/tenants/route",pathname:"/api/tenants",filename:"route",bundlePath:"app/api/tenants/route"},resolvedPagePath:"c:\\xampp\\htdocs\\propmaster.io\\src\\app\\api\\tenants\\route.ts",nextConfigOutput:"standalone",userland:n}),{requestAsyncStorage:f,staticGenerationAsyncStorage:w,serverHooks:N}=g,A="/api/tenants/route";function R(){return(0,o.patchFetch)({serverHooks:N,staticGenerationAsyncStorage:w})}},73275:(e,t,a)=>{a.d(t,{Gv:()=>u,Lz:()=>i,c_:()=>l});var n=a(76214),s=a(98432),r=a.n(s),o=a(82208);let i={providers:[(0,n.Z)({name:"credentials",credentials:{email:{label:"Email",type:"email"},password:{label:"Password",type:"password"}},async authorize(e){if(console.log("Auth: Starting authentication for email:",e?.email),!e?.email||!e?.password)return console.log("Auth: Missing credentials"),null;try{console.log("Auth: Checking users table for:",e.email);let t=await o._.user.findUnique({where:{email:e.email},include:{company:{include:{subscriptionPlan:!0}}}});console.log("Auth: User lookup result:",t?`Found user with role: ${t.role}`:"No user found");let a=!1,n=!1;if(t&&"tenant"===t.role){console.log("Auth: User has tenant role, checking tenants table first");try{let n=await o._.tenant.findFirst({where:{email:e.email},include:{company:{include:{subscriptionPlan:!0}},unit:{include:{property:{include:{estate:!0}}}}}});if(console.log("Auth: Tenant lookup result:",n?"Found tenant":"No tenant found"),!n||!n.passwordHash)return console.log("Auth: No tenant found or no password hash, cannot authenticate"),null;{console.log("Auth: Tenant has password hash, verifying password");let s=await r().compare(e.password,n.passwordHash);if(console.log("Auth: Tenant password verification result:",s),!s)return console.log("Auth: Tenant password verification failed"),null;t={id:n.id,email:n.email,passwordHash:n.passwordHash,firstName:n.firstName,lastName:n.lastName,phone:n.phone,role:"tenant",companyId:n.companyId,company:n.company,avatarUrl:null,commissionRate:null,commissionDueDay:null,agreementDocument:null,emailVerified:!0,emailVerifiedAt:null,lastLoginAt:null,passwordResetToken:null,passwordResetExpires:null,preferences:{},timezone:"Africa/Kampala",createdAt:n.createdAt,updatedAt:n.updatedAt,deletedAt:null},a=!0,console.log("Auth: Tenant authentication successful")}}catch(e){return console.error("Auth: Error querying tenants table:",e),null}}else if(!t){console.log("Auth: User not found in users table, checking tenants table for:",e.email);try{let n=await o._.tenant.findFirst({where:{email:e.email},include:{company:{include:{subscriptionPlan:!0}},unit:{include:{property:{include:{estate:!0}}}}}});if(console.log("Auth: Tenant lookup result:",n?"Found tenant":"No tenant found"),n&&n.passwordHash){console.log("Auth: Tenant has password hash, verifying password");let s=await r().compare(e.password,n.passwordHash);console.log("Auth: Password verification result:",s),s?(t={id:n.id,email:n.email,passwordHash:n.passwordHash,firstName:n.firstName,lastName:n.lastName,phone:n.phone,role:"tenant",companyId:n.companyId,company:n.company,avatarUrl:null,commissionRate:null,commissionDueDay:null,agreementDocument:null,emailVerified:!0,emailVerifiedAt:null,lastLoginAt:null,passwordResetToken:null,passwordResetExpires:null,preferences:{},timezone:"Africa/Kampala",createdAt:n.createdAt,updatedAt:n.updatedAt,deletedAt:null},a=!0,console.log("Auth: Tenant authentication successful")):console.log("Auth: Tenant password verification failed")}else n&&console.log("Auth: Tenant found but no password hash")}catch(e){console.error("Auth: Error querying tenants table:",e)}}if(!t){console.log("Auth: User not found in users or tenants table, checking technicians table for:",e.email);try{let a=await o._.technician.findUnique({where:{email:e.email},include:{company:{include:{subscriptionPlan:!0}}}});if(console.log("Auth: Technician lookup result:",a?"Found technician":"No technician found"),a&&a.passwordHash){console.log("Auth: Technician has password hash, verifying password");let s=await r().compare(e.password,a.passwordHash);console.log("Auth: Technician password verification result:",s),s?(t={id:a.id,email:a.email,passwordHash:a.passwordHash,firstName:a.firstName,lastName:a.lastName,phone:a.phone,role:"technician",companyId:a.companyId,company:a.company,avatarUrl:a.avatarUrl,commissionRate:null,commissionDueDay:null,agreementDocument:null,emailVerified:!0,emailVerifiedAt:null,lastLoginAt:null,passwordResetToken:null,passwordResetExpires:null,preferences:{},timezone:"Africa/Kampala",createdAt:a.createdAt,updatedAt:a.updatedAt,deletedAt:null},n=!0,console.log("Auth: Technician authentication successful")):console.log("Auth: Technician password verification failed")}else a&&console.log("Auth: Technician found but no password hash")}catch(e){console.error("Auth: Error querying technicians table:",e)}}if(!t||!t.passwordHash)return console.log("Auth: No user found or no password hash"),null;if(!a&&!await r().compare(e.password,t.passwordHash))return null;return a||n||await o._.user.update({where:{id:t.id},data:{lastLoginAt:new Date}}),console.log("Auth: User company data:",{userId:t.id,companyId:t.companyId,company:t.company,isTenant:a}),{id:t.id,email:t.email,name:`${t.firstName||""} ${t.lastName||""}`.trim(),role:t.role,companyId:t.companyId,company:t.company,firstName:t.firstName,lastName:t.lastName,phone:t.phone,avatarUrl:t.avatarUrl,commissionRate:t.commissionRate,commissionDueDay:t.commissionDueDay,isTenant:a,isTechnician:n}}catch(e){return console.error("Auth error:",e),console.log("Auth: Authentication failed due to error"),null}}})],session:{strategy:"jwt",maxAge:2592e3},jwt:{maxAge:2592e3},callbacks:{jwt:async({token:e,user:t})=>(t&&(e.role=t.role,e.companyId=t.companyId,e.company=t.company,e.firstName=t.firstName,e.lastName=t.lastName,e.phone=t.phone,e.avatarUrl=t.avatarUrl,e.commissionRate=t.commissionRate,e.commissionDueDay=t.commissionDueDay,e.isTenant=t.isTenant,e.isTechnician=t.isTechnician),e),session:async({session:e,token:t})=>(t&&(e.user.id=t.sub,e.user.role=t.role,e.user.companyId=t.companyId,e.user.company=t.company,e.user.firstName=t.firstName,e.user.lastName=t.lastName,e.user.phone=t.phone,e.user.avatarUrl=t.avatarUrl,e.user.commissionRate=t.commissionRate,e.user.commissionDueDay=t.commissionDueDay,e.user.isTenant=t.isTenant,e.user.isTechnician=t.isTechnician,console.log("Auth Session Callback: companyId =",t.companyId)),e)},pages:{signIn:"/auth/login"},secret:process.env.NEXTAUTH_SECRET};async function l(e){return r().hash(e,12)}async function u(e,t){return r().compare(e,t)}},82208:(e,t,a)=>{a.d(t,{_:()=>s});var n=a(53524);let s=globalThis.prisma??new n.PrismaClient({log:["error"]})}};var t=require("../../../webpack-runtime.js");t.C(e);var a=e=>t(t.s=e),n=t.X(0,[7787,9121,4833,7642],()=>a(83671));module.exports=n})();