1import{a as L}from"./chunk-JLCEN7N6.js";import{D as te,Y as ne,Z as ie,_ as ae,ca as oe,da as re,ea as se,i as Y,ja as le,k as J,l as V,m as q,o as Q,q as K,v as $,y as ee}from"./chunk-KMXQE4KL.js";import{b as ce,c as de,d as pe}from"./chunk-LFRTPRFK.js";import{a as A}from"./chunk-GUZO7ZNK.js";import{Aa as M,Db as R,Fb as U,Ha as T,Ia as F,Ib as W,Ic as z,J as w,Lc as Z,Rb as G,Sb as B,Ua as m,Va as I,Vb as H,Vc as X,Wa as P,aa as l,ab as x,bb as O,ca as k,cb as S,fa as N,i as D,lb as h,mb as u,qa as b,sa as E,xa as v,ya as s,za as c}from"./chunk-3RYB6SVN.js";import"./chunk-PW6GA5NL.js";import"./chunk-S5XOBH6Y.js";import"./chunk-Y7EQJLOB.js";import"./chunk-4EXU7QX3.js";import"./chunk-YG5PFMJ7.js";import"./chunk-NER57BGA.js";import"./chunk-DSHYVPZD.js";import"./chunk-PD2PSGYJ.js";import"./chunk-YGDXWWXH.js";import"./chunk-JNMFIV4M.js";import"./chunk-DXRS3GW7.js";import"./chunk-ZDL7X67C.js";import"./chunk-CLVRMGG4.js";import{g as C}from"./chunk-NMDLJX5Q.js";function me(_,f){if(_&1&&(s(0,"div",7),M(1,"ion-img",12),s(2,"div",13),M(3,"ion-icon",14),s(4,"p"),m(5),h(6,"translate"),c()()()),_&2){let ge=F();l(),v("src",ge.projectImg),l(4),I(u(6,2,"Tap to change photo"))}}function he(_,f){_&1&&(s(0,"div",8),M(1,"ion-icon",14),s(2,"p"),m(3),h(4,"translate"),c()()),_&2&&(l(3),I(u(4,1,"Tap to add photo")))}var Te=(()=>{let f=class f{constructor(){this.DISALLOWED_IMAGE_MIME_TYPES=["image/heic","image/heif","image/heic-sequence","image/heif-sequence"],this.DISALLOWED_IMAGE_EXTENSIONS=[".heic",".heif"],this.data={},this.user={},this.projectImg=null,this.imgURL="",this.http=w(W),this.router=w(G),this.loadingController=w(ae),this.alertController=w(ie),this.actionSheetController=w(ne),this.translate=w(ce),this.ngZone=w(k),this.TARGET_WIDTH=1920,this.TARGET_HEIGHT=1440,this.QUALITY=.7,this.MAX_FILE_SIZE=10*1024*1024,this.UPLOAD_URL=A.apiUrl+"project_imgUpload.php"}ngOnInit(){}ionViewWillEnter(){this.data={student:"",address:"",date:new Date().toISOString().substr(0,10),notes:"",project_image:""},this.projectImg=null,this.imgURL="",this.user=JSON.parse(localStorage.getItem("user")||"{}"),this.loadUserData()}replaceAll(i,n,e){return i.replace(new RegExp(n,"g"),e)}loadUserData(){this.data.tutor=this.user.tutor,this.data.user_id=this.user.user_id,this.data.faculty=this.user.faculty,this.data.provider=this.user.provider,this.data.student=this.user.user_id}openCamera(){return C(this,null,function*(){yield(yield this.actionSheetController.create({header:this.translate.instant("Select Image Source"),buttons:[{text:this.translate.instant("Take Picture"),handler:()=>
1{this.takePicture(!0)}},{text:this.translate.instant("Choose from gallery"),handler:()=>{this.takePicture(!1)}},{text:this.translate.instant("Cancel"),role:"cancel"}]})).present()})}takePicture(i){return C(this,null,function*(){let n=document.createElement("input");n.type="file",n.accept="image/jpeg,image/png",i&&(n.capture="environment"),n.onchange=e=>C(this,null,function*(){let a=e.target.files[0];if(!a)return;if(this.isHeicFile(a)){yield this.displayAlert("HEIC/HEIF images are not supported. Please select JPG, PNG, GIF, or WebP.");return}if(!this.isCorrectFileType(a.name.split(".").pop()||"")){yield this.displayAlert("Only JPG, PNG, and GIF images are allowed.");return}if(a.size>this.MAX_FILE_SIZE){yield this.displayAlert(`File is too large. Maximum size is ${this.MAX_FILE_SIZE/(1024*1024)}MB.`);return}let t=yield this.loadingController.create({message:this.translate.instant("Processing image...")});yield t.present();try{let r=yield this.compressImage(a);this.ngZone.run(()=>{this.projectImg=r;let p=new Date,o=p.toISOString().substr(0,19);o=this.replaceAll(o,"-",""),o=this.replaceAll(o,"T","_"),o=this.replaceAll(o,":",""),this.imgURL=o+"_"+p.getTime()+".jpg"})}catch{yield this.displayAlert("Error processing image. Please try again.")}finally{yield t.dismiss()}}),n.click()})}isHeicFile(i){let n=String(i?.name||"").toLowerCase(),e=String(i?.type||"").toLowerCase(),a=this.DISALLOWED_IMAGE_EXTENSIONS.some(r=>n.endsWith(r)),t=this.DISALLOWED_IMAGE_MIME_TYPES.includes(e);return a||t}compressImage(i){return new Promise((n,e)=>{let a=new FileReader;a.onload=t=>{let r=new Image;r.onload=()=>{let p=document.createElement("canvas"),o=p.getContext("2d");if(!o){e(new Error("Canvas context not available"));return}let d=r.width,g=r.height;if(d>this.TARGET_WIDTH||g>this.TARGET_HEIGHT){let j=Math.min(this.TARGET_WIDTH/d,this.TARGET_HEIGHT/g);d=Math.round(d*j),g=Math.round(g*j)}p.width=d,p.height=g,o.fillStyle="#FFFFFF",o.fillRect(0,0,d,g),o.drawImage(r,0,0,d,g);let y=p.toDataURL("image/jpeg",this.QUALITY);n(y)},r.onerror=()=>e(new Error("Failed to load image")),r.src=t.target.result},a.onerror=()=>e(new Error("Failed to read file")),a.readAsDataURL(i)})}isCorrectFileType(i){return/^(gif|jpg|jpeg|png)$/i.test(i)}doSaveData(){return C(this,null,function*(){if(!this.data.address||this.data.address.length<1){yield this.displayAlert("Please input address");return}let i=L.normalizePlainText(this.data.notes||"",1e3),n=L.escapeHtml(i),e={student:this.data.user_id.toString(),address:this.data.address,date:this.data.date,notes:n,image:this.imgURL},a=A.apiUrl+"add_project.php",t=yield this.loadingController.create({message:""});yield t.present();try{let r=new U({"Content-Type":"application/json"}),p=yield D(this.http.post(a,e,{headers:r}));if(yield t.dismiss(),p.error==!0){yield this.displayAlert("Sorry we could not upload your entry, please try again later.");return}yield(yield this.alertController.create({header:this.translate.instant("Success"),message:this.translate.instant("Entry has been uploaded successfully"),buttons:[{text:"Okay",handler:()=>{localStorage.setItem("bLoadProject","1"),localStorage.setItem("projectData",JSON.stringify(e)),this.router.navigateByUrl("/projects")}}]})).present()}catch{yield t.dismiss(),yield this.displayAlert("Sorry we could not upload your entry, please try again later.")}})}doSave(){return C(this,null,function*(){if(!this.projectImg){yield this.doSaveData();return}yield this.uploadImage()})}uploadImage(){return C(this,null,function*(){if(this.projectImg){this.uploadLoading=yield this.loadingController.create({message:""}),yield this.uploadLoading.present();try{let i=this.projectImg.split(",")[1],n=atob(i),e=[];for(let o=0;o<n.length;o+=512){let d=n.slice(o,o+512),g=new Array(d.length);for(let y=0;y<d.length;y++)g[y]=d.charCodeAt(y);e.push(new Uint8Array(g))}let a=new Blob(e,{type:"image/jpeg"}),t=new FormData;t.append("file",a,this.imgURL),t.append("value1",this.imgURL),t.append("value2","param");let r=yield fetch(this.UPLOAD_URL,{method:"POST",body:t}),p=yield r.text();this.uploadLoading&&this.uploadLoading.dismiss(),r.ok?yield this.doSaveData():yield this.displayAlert("We could not upload your photo, please try again later.")}catch{this.uploadLoading&&this.uploadLoading.dismiss(),yield this.displayAlert("We could not upload your photo, please try again later.")}}})}displayAlert(i){return C(this,null,function*(){yield(yield this.alertController.create({header:"Alert",message:i,buttons:["OK"]})).present()})}};f.\u0275fac=function(n){return new(n||f)},f.\u0275cmp=N({type:f,selectors:[["app-new-project"]],decls:37,vars:27,consts:[[1,"ion-padding",3,"fullscreen"],["lines","none"],["position","stacked"],["type","text","placeholder","Enter project name",3,"ngModelChange","ngModel"],["rows","4","placeholder","Add project notes",3,"ngModelChange","ngModel"],["presentation","date",3,"ngModelChange","ngModel"],[1,"image-wrapper",3,"click"],[1,"selected-image"],[1,"image-placeholder"],["expand","block","color","primary",3,"click"],["expand","block","color","warning","routerLink","/projects",1,"cancel-btn"],["slot","start","name","close"],["alt","Selected Image",3,"src"],[1,"image-overlay"],["name","camera"]],template:function(n,e){n&1&&(s(0,"ion-content",0)(1,"ion-card")(2,"ion-card-header")(3,"ion-card-title"),m(4),h(5,"translate"),c()(),s(6,"ion-card-content")(7,"ion-item",1)(8,"ion-label",2),m(9),h(10,"translate"),c(),s(11,"ion-input",3),S("ngModelChange",function(t){return O(e.data.address,t)||(e.data.address=t),t}),c()(),s(12,"ion-item",1)(13,"ion-label",2),m(14),h(15,"translate"),c(),s(16,"ion-textarea",4),S("ngModelChange",function(t){return O(e.data.notes,t)||(e.data.notes=t),t}),c()(),s(17,"ion-item",1)(18,"ion-label",2),m(19),h(20,"translate"),c(),s(21,"ion-datetime",5),S("ngModelChange",function(t){return O(e.data.date,t)||(e.data.date=t),t}),c()()()(),s(22,"ion-card")(23,"ion-card-header")(24,"ion-card-title"),m(25),h(26,"translate"),c()(),s(27,"ion-card-content",6),T("click",function(){return e.openCamera()}),b(28,me,7,4,"div",7),b(29,he,5,3,"div",8),c()(),s(30,"ion-button",9),T("click",function(){return e.doSave()}),m(31),h(32,"translate"),c(),s(33,"ion-button",10),M(34,"ion-icon",11),m(35),h(36,"translate"),c()()),n&2&&(v("fullscreen",!0),l(4),I(u(5,13,"Project Details")),l(5),P(" ",u(10,15,"Address / Project Name")," "),l(2),x("ngModel",e.data.address),l(3),P(" ",u(15,17,"Notes")," "),l(2),x("ngModel",e.data.notes),l(3),P(" ",u(2
10,19,"Start Date")," "),l(2),x("ngModel",e.data.date),l(4),I(u(26,21,"Project Image")),l(3),E(e.projectImg?28:-1),l(),E(e.projectImg?-1:29),l(2),P(" ",u(32,23,"Save Project")," "),l(4),P(" ",u(36,25,"ACTIVITY.CANCEL")," "))},dependencies:[R,X,z,Z,H,B,pe,K,ee,te,se,le,oe,Y,re,$,q,Q,J,V,de],styles:["@media(prefers-color-scheme:dark){ion-content[_ngcontent-%COMP%]{--background: #18191a !important}ion-item[_ngcontent-%COMP%]{--background: #232526 !important}ion-item[_ngcontent-%COMP%] ion-input[_ngcontent-%COMP%], ion-item[_ngcontent-%COMP%] ion-textarea[_ngcontent-%COMP%], ion-item[_ngcontent-%COMP%] ion-datetime[_ngcontent-%COMP%]{--background: #232526 !important;--color: #fafafa !important;border:1px solid #444!important}ion-item[_ngcontent-%COMP%] ion-label[position=stacked][_ngcontent-%COMP%]{color:#fafafa!important}}ion-content[_ngcontent-%COMP%]{--background: #f5f5f5}ion-card[_ngcontent-%COMP%]{margin-bottom:16px;border-radius:12px;box-shadow:0 4px 12px #0000001a}.image-wrapper[_ngcontent-%COMP%]{position:relative;text-align:center;padding:20px;cursor:pointer;min-height:200px;display:flex;align-items:center;justify-content:center;overflow:hidden}.image-wrapper[_ngcontent-%COMP%] .selected-image[_ngcontent-%COMP%]{position:relative;width:100%;height:100%}.image-wrapper[_ngcontent-%COMP%] .selected-image[_ngcontent-%COMP%] ion-img[_ngcontent-%COMP%]{width:100%;height:300px;object-fit:contain;border-radius:8px}.image-wrapper[_ngcontent-%COMP%] .selected-image[_ngcontent-%COMP%] .image-overlay[_ngcontent-%COMP%]{position:absolute;inset:0;background:#00000080;display:flex;flex-direction:column;align-items:center;justify-content:center;color:#fff;opacity:0;transition:opacity .3s ease;border-radius:8px}.image-wrapper[_ngcontent-%COMP%] .selected-image[_ngcontent-%COMP%] .image-overlay[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%]{font-size:48px;margin-bottom:12px}.image-wrapper[_ngcontent-%COMP%] .selected-image[_ngcontent-%COMP%] .image-overlay[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:0;font-size:14px}.image-wrapper[_ngcontent-%COMP%] .selected-image[_ngcontent-%COMP%]:hover .image-overlay[_ngcontent-%COMP%]{opacity:1}.image-placeholder[_ngcontent-%COMP%]{text-align:center;color:#888;padding:40px 20px;width:100%}.image-placeholder[_ngcontent-%COMP%] ion-icon[_ngcontent-%COMP%]{font-size:64px;margin-bottom:16px;color:#ccc}.image-placeholder[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:0;font-size:16px;font-weight:500}ion-item[_ngcontent-%COMP%]{--background: transparent;--padding-start: 0;--inner-padding-end: 0;--border-color: transparent;margin-bottom:16px}ion-item[_ngcontent-%COMP%] ion-label[position=stacked][_ngcontent-%COMP%]{font-weight:500;margin-bottom:8px;color:#333}ion-item[_ngcontent-%COMP%] ion-input[_ngcontent-%COMP%], ion-item[_ngcontent-%COMP%] ion-textarea[_ngcontent-%COMP%]{--background: #f2f2f2;--padding-start: 12px;--padding-end: 12px;border-radius:8px;border:1px solid #ddd}ion-item[_ngcontent-%COMP%] ion-datetime[_ngcontent-%COMP%]{width:100%;--background: #fff;border-radius:8px;border:1px solid #ddd;padding:12px}ion-button[_ngcontent-%COMP%]{margin-top:8px}ion-button[expand=block][_ngcontent-%COMP%]{--border-radius: 8px;height:50px;font-weight:500}ion-button[color=primary][_ngcontent-%COMP%]{--background: var(--ion-color-primary);--background-activated: var(--ion-color-primary-shade)}.cancel-btn[_ngcontent-%COMP%]{--color: #fff !important}.cancel-btn[_ngcontent-%COMP%]::part(native){color:#fff!important}"]});let _=f;return _})();export{Te as NewProjectPage};
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.