@aggdirect/coolmap 5.0.4 → 5.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -103,11 +103,11 @@ class JobDetailsComponent {
103
103
  this.isDragging = false;
104
104
  }
105
105
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: JobDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
106
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: JobDetailsComponent, isStandalone: true, selector: "lib-job-details", inputs: { modalOpen: { classPropertyName: "modalOpen", publicName: "modalOpen", isSignal: true, isRequired: false, transformFunction: null }, routeData: { classPropertyName: "routeData", publicName: "routeData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modalOpenChange: "modalOpenChange" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp()" } }, ngImport: i0, template: "@if (modalOpen()) {\n<div class=\"z-[111] xl:z-[80] bottom-0 lg:left-[300px] fixed lg:absolute inset-0 overflow-y-auto\">\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ routeData()?.values?.Incomplete || 0 }}</span>\n <span class=\"stat-label\">Imcomplete</span>\n </div>\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 1 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:20px;font-size:12px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
106
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: JobDetailsComponent, isStandalone: true, selector: "lib-job-details", inputs: { modalOpen: { classPropertyName: "modalOpen", publicName: "modalOpen", isSignal: true, isRequired: false, transformFunction: null }, routeData: { classPropertyName: "routeData", publicName: "routeData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modalOpenChange: "modalOpenChange" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp()" } }, ngImport: i0, template: "@if (modalOpen()) {\n<div class=\"z-[111] xl:z-[80] bottom-0 lg:left-[350px] fixed lg:absolute inset-0 overflow-y-auto\">\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ routeData()?.values?.Incomplete || 0 }}</span>\n <span class=\"stat-label\">Imcomplete</span>\n </div>\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 1 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:20px;font-size:12px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
107
107
  }
108
108
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: JobDetailsComponent, decorators: [{
109
109
  type: Component,
110
- args: [{ selector: 'lib-job-details', standalone: true, imports: [LucideAngularModule], template: "@if (modalOpen()) {\n<div class=\"z-[111] xl:z-[80] bottom-0 lg:left-[300px] fixed lg:absolute inset-0 overflow-y-auto\">\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ routeData()?.values?.Incomplete || 0 }}</span>\n <span class=\"stat-label\">Imcomplete</span>\n </div>\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 1 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:20px;font-size:12px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"] }]
110
+ args: [{ selector: 'lib-job-details', standalone: true, imports: [LucideAngularModule], template: "@if (modalOpen()) {\n<div class=\"z-[111] xl:z-[80] bottom-0 lg:left-[350px] fixed lg:absolute inset-0 overflow-y-auto\">\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div class=\"flex min-h-full lg:items-end lg:justify-start items-center justify-center p-3\">\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n [style.transform]=\"'translate(' + dragX() + 'px, ' + dragY() + 'px)'\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b cursor-move border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n (mousedown)=\"startDrag($event)\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Job Details\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[50vh] overflow-y-auto p-2\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ routeData()?.values?.Done || 0 }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ routeData()?.values?.Incomplete || 0 }}</span>\n <span class=\"stat-label\">Imcomplete</span>\n </div>\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ routeData()?.values?.Ongoing || 0 }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ routeData()?.values?.Open || 1 }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n <div\n class=\"location-flow bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg mt-4\"\n >\n <span class=\"pickup truncate block\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-green-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Pickup: {{ routeData()?.pickup_location || 'N/A' }}\n </span>\n <span class=\"delivery truncate block mt-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"inline mr-1 text-blue-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n </svg>\n Delivery: {{ routeData()?.delivery_location || 'N/A' }}\n </span>\n </div>\n <div class=\"device-info mt-2\">\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Jobcode</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.order_number || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Project Name</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.project || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Job Type</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Material</span>\n <span class=\"font-medium truncate max-w-[65%] text-right\">{{ routeData()?.material || 'General Freight' }}</span>\n </div>\n <div\n class=\"flex justify-between py-2 border-b border-gray-200 dark:border-slate-600 text-xs\"\n >\n <span class=\"text-gray-500 dark:text-slate-500\">Customer Contact</span>\n <span class=\"font-medium\">{{ routeData()?.customer_contact || 'None' }}</span>\n </div>\n <div class=\"flex justify-between py-2 text-xs\">\n <span class=\"text-gray-500 dark:text-slate-500\">Delivery Contact</span>\n <span class=\"font-medium\">{{ routeData()?.delivery_contact || 'None' }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [".stats-row{display:flex;align-items:center;gap:20px;font-size:12px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:center;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px}.location-flow .delivery{display:flex;align-items:center;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"] }]
111
111
  }], propDecorators: { modalOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "modalOpen", required: false }] }], routeData: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeData", required: false }] }], modalOpenChange: [{
112
112
  type: Output
113
113
  }], onMouseMove: [{
@@ -211,11 +211,11 @@ class RouteInfoCardComponent {
211
211
  X,
212
212
  };
213
213
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: RouteInfoCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
214
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: RouteInfoCardComponent, isStandalone: true, selector: "lib-route-info-card", inputs: { modalOpen: { classPropertyName: "modalOpen", publicName: "modalOpen", isSignal: true, isRequired: false, transformFunction: null }, routeData: { classPropertyName: "routeData", publicName: "routeData", isSignal: true, isRequired: false, transformFunction: null }, repository: { classPropertyName: "repository", publicName: "repository", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modalOpenChange: "modalOpenChange", edit: "edit" }, ngImport: i0, template: "@if (modalOpen()) {\n<div \n class=\"z-[112] bottom-0 fixed lg:absolute inset-0 overflow-y-auto\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:left-[300px]' : 'lg:right-[300px]'\"\n>\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div \n class=\"flex min-h-full lg:items-end items-center justify-center p-3\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:justify-start' : 'lg:justify-end'\"\n >\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Route Info\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[60vh] overflow-y-auto p-3\">\n <div class=\"space-y-2 bg-gray-50 dark:bg-slate-900/50 border border-gray-200 dark:border-slate-700 p-3 rounded-lg mb-4\">\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Pickup:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.pickup_location || '').split('|')[1] || routeData()?.pickup_location || 'N/A' }}\n </span>\n </p>\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Delivery:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.delivery_location || '').split('|')[1] || routeData()?.delivery_location || 'N/A' }}\n </span>\n </p>\n </div>\n\n <div class=\"space-y-2.5\">\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Name:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.route_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Type:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Distance:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_distance || '0' }} Miles</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Travel Time:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_time || '0' }} Min</span>\n </div>\n\n @if (repository() !== 'customer') {\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Trucker Pay Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.trucker_pay_estimate | currency }}</span>\n </div>\n }\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer Price Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.customer_price_estimate | currency }}</span>\n </div>\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Notes:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4 italic\">{{ routeData()?.note || 'None' }}</span>\n </div>\n </div>\n\n <div class=\"mt-4 pt-3 border-t border-gray-100 dark:border-slate-700 flex justify-between items-center\">\n <p class=\"text-[10px] text-gray-400 italic\">\n Created by {{ routeData()?.created_by_name || routeData()?.user || 'System' }} on {{ formattedDate() }}\n </p>\n @if (displayMode() === 'catalog') {\n <button \n type=\"button\"\n (click)=\"edit.emit(); close()\"\n class=\"px-3 py-1 text-[11px] font-bold uppercase tracking-wider bg-orange-500 hover:bg-orange-600 text-white rounded transition-colors\"\n >\n Edit\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n}", styles: [".location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:flex-start;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px;margin-top:4px}.location-flow .delivery{display:flex;align-items:flex-start;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px;margin-top:4px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i2.CurrencyPipe, name: "currency" }] });
214
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: RouteInfoCardComponent, isStandalone: true, selector: "lib-route-info-card", inputs: { modalOpen: { classPropertyName: "modalOpen", publicName: "modalOpen", isSignal: true, isRequired: false, transformFunction: null }, routeData: { classPropertyName: "routeData", publicName: "routeData", isSignal: true, isRequired: false, transformFunction: null }, repository: { classPropertyName: "repository", publicName: "repository", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modalOpenChange: "modalOpenChange", edit: "edit" }, ngImport: i0, template: "@if (modalOpen()) {\n<div \n class=\"z-[112] bottom-0 fixed lg:absolute inset-0 overflow-y-auto\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:left-[350px]' : 'lg:right-[350px]'\"\n>\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div \n class=\"flex min-h-full lg:items-end items-center justify-center p-3\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:justify-start' : 'lg:justify-end'\"\n >\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Route Info\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[60vh] overflow-y-auto p-3\">\n <div class=\"space-y-2 bg-gray-50 dark:bg-slate-900/50 border border-gray-200 dark:border-slate-700 p-3 rounded-lg mb-4\">\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Pickup:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.pickup_location || '').split('|')[1] || routeData()?.pickup_location || 'N/A' }}\n </span>\n </p>\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Delivery:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.delivery_location || '').split('|')[1] || routeData()?.delivery_location || 'N/A' }}\n </span>\n </p>\n </div>\n\n <div class=\"space-y-2.5\">\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Name:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.route_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Type:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Distance:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_distance || '0' }} Miles</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Travel Time:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_time || '0' }} Min</span>\n </div>\n\n @if (repository() !== 'customer') {\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Trucker Pay Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.trucker_pay_estimate | currency }}</span>\n </div>\n }\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer Price Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.customer_price_estimate | currency }}</span>\n </div>\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Notes:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4 italic\">{{ routeData()?.note || 'None' }}</span>\n </div>\n </div>\n\n <div class=\"mt-4 pt-3 border-t border-gray-100 dark:border-slate-700 flex justify-between items-center\">\n <p class=\"text-[10px] text-gray-400 italic\">\n Created by {{ routeData()?.created_by_name || routeData()?.user || 'System' }} on {{ formattedDate() }}\n </p>\n @if (displayMode() === 'catalog') {\n <button \n type=\"button\"\n (click)=\"edit.emit(); close()\"\n class=\"px-3 py-1 text-[11px] font-bold uppercase tracking-wider bg-orange-500 hover:bg-orange-600 text-white rounded transition-colors\"\n >\n Edit\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n}", styles: [".location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:flex-start;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px;margin-top:4px}.location-flow .delivery{display:flex;align-items:flex-start;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px;margin-top:4px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i2.CurrencyPipe, name: "currency" }] });
215
215
  }
216
216
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: RouteInfoCardComponent, decorators: [{
217
217
  type: Component,
218
- args: [{ selector: 'lib-route-info-card', standalone: true, imports: [LucideAngularModule, CommonModule, CurrencyPipe], template: "@if (modalOpen()) {\n<div \n class=\"z-[112] bottom-0 fixed lg:absolute inset-0 overflow-y-auto\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:left-[300px]' : 'lg:right-[300px]'\"\n>\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div \n class=\"flex min-h-full lg:items-end items-center justify-center p-3\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:justify-start' : 'lg:justify-end'\"\n >\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Route Info\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[60vh] overflow-y-auto p-3\">\n <div class=\"space-y-2 bg-gray-50 dark:bg-slate-900/50 border border-gray-200 dark:border-slate-700 p-3 rounded-lg mb-4\">\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Pickup:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.pickup_location || '').split('|')[1] || routeData()?.pickup_location || 'N/A' }}\n </span>\n </p>\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Delivery:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.delivery_location || '').split('|')[1] || routeData()?.delivery_location || 'N/A' }}\n </span>\n </p>\n </div>\n\n <div class=\"space-y-2.5\">\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Name:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.route_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Type:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Distance:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_distance || '0' }} Miles</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Travel Time:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_time || '0' }} Min</span>\n </div>\n\n @if (repository() !== 'customer') {\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Trucker Pay Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.trucker_pay_estimate | currency }}</span>\n </div>\n }\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer Price Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.customer_price_estimate | currency }}</span>\n </div>\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Notes:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4 italic\">{{ routeData()?.note || 'None' }}</span>\n </div>\n </div>\n\n <div class=\"mt-4 pt-3 border-t border-gray-100 dark:border-slate-700 flex justify-between items-center\">\n <p class=\"text-[10px] text-gray-400 italic\">\n Created by {{ routeData()?.created_by_name || routeData()?.user || 'System' }} on {{ formattedDate() }}\n </p>\n @if (displayMode() === 'catalog') {\n <button \n type=\"button\"\n (click)=\"edit.emit(); close()\"\n class=\"px-3 py-1 text-[11px] font-bold uppercase tracking-wider bg-orange-500 hover:bg-orange-600 text-white rounded transition-colors\"\n >\n Edit\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n}", styles: [".location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:flex-start;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px;margin-top:4px}.location-flow .delivery{display:flex;align-items:flex-start;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px;margin-top:4px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"] }]
218
+ args: [{ selector: 'lib-route-info-card', standalone: true, imports: [LucideAngularModule, CommonModule, CurrencyPipe], template: "@if (modalOpen()) {\n<div \n class=\"z-[112] bottom-0 fixed lg:absolute inset-0 overflow-y-auto\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:left-[350px]' : 'lg:right-[350px]'\"\n>\n <div class=\"fixed inset-0 bg-black/50\" (click)=\"close()\"></div>\n <div \n class=\"flex min-h-full lg:items-end items-center justify-center p-3\"\n [ngClass]=\"displayMode() === 'catalog' ? 'lg:justify-start' : 'lg:justify-end'\"\n >\n <div\n class=\"relative bg-white dark:bg-slate-800 rounded-lg shadow-xl animate-slide-up w-[350px]\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"flex items-center justify-between px-[12px] py-[10px] border-b border-gray-200 dark:border-slate-700 dark:bg-slate-900 rounded-t-lg\"\n >\n <h3 class=\"flex items-center gap-1 font-medium text-gray-900 dark:text-white text-[13px]\">\n Route Info\n </h3>\n <button\n (click)=\"close()\"\n class=\"p-2 hover:bg-gray-100 dark:hover:bg-slate-700 rounded-lg transition-colors\"\n >\n <lucide-icon [img]=\"icons.X\" [size]=\"20\"></lucide-icon>\n </button>\n </div>\n <div class=\"max-h-[60vh] overflow-y-auto p-3\">\n <div class=\"space-y-2 bg-gray-50 dark:bg-slate-900/50 border border-gray-200 dark:border-slate-700 p-3 rounded-lg mb-4\">\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Pickup:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.pickup_location || '').split('|')[1] || routeData()?.pickup_location || 'N/A' }}\n </span>\n </p>\n <p class=\"text-xs\">\n <b class=\"text-gray-900 dark:text-white\">Delivery:</b> \n <span class=\"text-gray-600 dark:text-gray-400\">\n {{ (routeData()?.delivery_location || '').split('|')[1] || routeData()?.delivery_location || 'N/A' }}\n </span>\n </p>\n </div>\n\n <div class=\"space-y-2.5\">\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Name:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.route_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.customer_name || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Type:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.unit || 'N/A' }}</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Distance:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_distance || '0' }} Miles</span>\n </div>\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Travel Time:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4\">{{ routeData()?.estimated_time || '0' }} Min</span>\n </div>\n\n @if (repository() !== 'customer') {\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Trucker Pay Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.trucker_pay_estimate | currency }}</span>\n </div>\n }\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Customer Price Estimate:</b>\n <span class=\"text-brand-blue font-medium text-right ml-4\">{{ routeData()?.customer_price_estimate | currency }}</span>\n </div>\n\n <div class=\"flex justify-between items-start text-xs border-b border-gray-100 dark:border-slate-700/50 pb-2\">\n <b class=\"text-gray-900 dark:text-white whitespace-nowrap\">Notes:</b>\n <span class=\"text-gray-600 dark:text-gray-400 text-right ml-4 italic\">{{ routeData()?.note || 'None' }}</span>\n </div>\n </div>\n\n <div class=\"mt-4 pt-3 border-t border-gray-100 dark:border-slate-700 flex justify-between items-center\">\n <p class=\"text-[10px] text-gray-400 italic\">\n Created by {{ routeData()?.created_by_name || routeData()?.user || 'System' }} on {{ formattedDate() }}\n </p>\n @if (displayMode() === 'catalog') {\n <button \n type=\"button\"\n (click)=\"edit.emit(); close()\"\n class=\"px-3 py-1 text-[11px] font-bold uppercase tracking-wider bg-orange-500 hover:bg-orange-600 text-white rounded transition-colors\"\n >\n Edit\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n}", styles: [".location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:4px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:flex;align-items:flex-start;gap:3px;color:#22c55e}.location-flow .pickup svg{width:8px;height:8px;margin-top:4px}.location-flow .delivery{display:flex;align-items:flex-start;gap:3px;color:#ef4444}.location-flow .delivery svg{width:8px;height:8px;margin-top:4px}@keyframes slide-up{0%{opacity:0;transform:translateY(10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-up{animation:slide-up .2s ease-out}\n"] }]
219
219
  }], propDecorators: { modalOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "modalOpen", required: false }] }], routeData: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeData", required: false }] }], repository: [{ type: i0.Input, args: [{ isSignal: true, alias: "repository", required: false }] }], displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: false }] }], modalOpenChange: [{
220
220
  type: Output
221
221
  }], edit: [{
@@ -436,11 +436,11 @@ class ViewRouteListComponent {
436
436
  return route.job_id || route.route_id || route.route_details_id || '';
437
437
  }
438
438
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ViewRouteListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
439
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ViewRouteListComponent, isStandalone: true, selector: "lib-view-route-list", inputs: { listMode: "listMode", collapsible: "collapsible", routes: "routes", selectedRouteIds: "selectedRouteIds" }, outputs: { routeSelect: "routeSelect", editRoute: "editRoute" }, ngImport: i0, template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n @if (listMode !== 'inline') {\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">View Route</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <lucide-icon [img]=\"icons.ChevronRight\" [size]=\"16\"></lucide-icon>\n } @else {\n <lucide-icon [img]=\"icons.ChevronLeft\" [size]=\"16\"></lucide-icon>\n }\n </button>\n </div>\n } \n \n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n <div class=\"cards-list\">\n @for (route of routes; track getRouteId(route)) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(getRouteId(route))\"\n [class.border-gray-200]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.selected]=\"selectedRouteIds.includes(getRouteId(route))\"\n >\n <div class=\"task-header justify-between items-start mb-1\">\n <h2 class=\"text-sm font-semibold text-gray-900 dark:text-white truncate max-w-[80%]\">\n {{ route.route_name || route.order_number || 'Unnamed Route' }}\n </h2>\n <div class=\"flex gap-2 shrink-0\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">\n {{ route.unit?.charAt(0) || 'U' }}\n </div>\n <button\n type=\"button\"\n class=\"text-gray-400 hover:text-brand-blue transition-colors\"\n (click)=\"$event.stopPropagation(); selectedRoute.set(route); showRouteModal = true\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"18\"></lucide-icon>\n </button>\n </div>\n </div>\n \n @if (route.customer_name) {\n <div class=\"text-[10px] text-gray-500 dark:text-slate-500 mb-2 uppercase tracking-wider font-medium truncate\">\n {{ route.customer_name }}\n </div>\n }\n\n <div class=\"location-flow bg-gray-50 dark:bg-slate-900/50 border border-gray-100 dark:border-slate-700/50 p-2 rounded-lg\">\n <div class=\"text-[11px] truncate flex items-center gap-1.5 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-green-500 shrink-0\"></div>\n {{ (route.pickup_location || '').split('|')[1] || route.pickup_location || 'N/A' }}\n </div>\n <div class=\"text-[11px] truncate flex items-center gap-1.5 mt-1 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-blue-500 shrink-0\"></div>\n {{ (route.delivery_location || '').split('|')[1] || route.delivery_location || 'N/A' }}\n </div>\n </div>\n </div>\n </div>\n } @empty {\n <div class=\"p-8 text-center text-gray-400 text-sm italic\">\n No routes found in this catalog.\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<lib-route-info-card \n [(modalOpen)]=\"showRouteModal\" \n [routeData]=\"selectedRoute()\" \n [repository]=\"config.repository\" \n displayMode=\"catalog\"\n (edit)=\"editRoute.emit(selectedRoute()!)\"\n></lib-route-info-card>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b);white-space:nowrap;text-overflow:ellipsis;max-width:190px;overflow:hidden}:host-context(.dark) .job-code{color:#f1f5f9}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:2px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:inline;align-items:center;gap:3px;color:#22c55e;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px}.location-flow .pickup svg{width:8px;height:8px;position:absolute;left:0;top:5px}.location-flow .delivery{display:inline;align-items:center;gap:3px;color:#ef4444;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px;top:5px}.location-flow .delivery svg{width:8px;height:8px;position:absolute;left:0;top:5px}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: RouteInfoCardComponent, selector: "lib-route-info-card", inputs: ["modalOpen", "routeData", "repository", "displayMode"], outputs: ["modalOpenChange", "edit"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
439
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: ViewRouteListComponent, isStandalone: true, selector: "lib-view-route-list", inputs: { listMode: "listMode", collapsible: "collapsible", routes: "routes", selectedRouteIds: "selectedRouteIds" }, outputs: { routeSelect: "routeSelect", editRoute: "editRoute" }, ngImport: i0, template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n @if (listMode !== 'inline') {\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">View Route</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <lucide-icon [img]=\"icons.ChevronRight\" [size]=\"16\"></lucide-icon>\n } @else {\n <lucide-icon [img]=\"icons.ChevronLeft\" [size]=\"16\"></lucide-icon>\n }\n </button>\n </div>\n } \n \n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n <div class=\"cards-list\">\n @for (route of routes; track getRouteId(route)) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(getRouteId(route))\"\n [class.border-gray-200]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.selected]=\"selectedRouteIds.includes(getRouteId(route))\"\n >\n <div class=\"task-header justify-between items-start mb-1\">\n <h2 class=\"text-sm font-semibold text-gray-900 dark:text-white truncate max-w-[80%]\">\n {{ route.route_name || route.order_number || 'Unnamed Route' }}\n </h2>\n <div class=\"flex gap-2 shrink-0\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">\n {{ route.unit?.charAt(0) || 'U' }}\n </div>\n <button\n type=\"button\"\n class=\"text-gray-400 hover:text-brand-blue transition-colors\"\n (click)=\"$event.stopPropagation(); selectedRoute.set(route); showRouteModal = true\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"18\"></lucide-icon>\n </button>\n </div>\n </div>\n \n @if (route.customer_name) {\n <div class=\"text-[10px] text-gray-500 dark:text-slate-500 mb-2 uppercase tracking-wider font-medium truncate\">\n {{ route.customer_name }}\n </div>\n }\n\n <div class=\"location-flow bg-gray-50 dark:bg-slate-900/50 border border-gray-100 dark:border-slate-700/50 p-2 rounded-lg\">\n <div class=\"text-[11px] truncate flex items-center gap-1.5 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-green-500 shrink-0 bullet\"></div>\n {{ (route.pickup_location || '').split('|')[1] || route.pickup_location || 'N/A' }}\n </div>\n <div class=\"text-[11px] truncate flex items-center gap-1.5 mt-1 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-blue-500 shrink-0 bullet\"></div>\n {{ (route.delivery_location || '').split('|')[1] || route.delivery_location || 'N/A' }}\n </div>\n </div>\n </div>\n </div>\n } @empty {\n <div class=\"p-8 text-center text-gray-400 text-sm italic\">\n No routes found in this catalog.\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<lib-route-info-card \n [(modalOpen)]=\"showRouteModal\" \n [routeData]=\"selectedRoute()\" \n [repository]=\"config.repository\" \n displayMode=\"catalog\"\n (edit)=\"editRoute.emit(selectedRoute()!)\"\n></lib-route-info-card>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b);white-space:nowrap;text-overflow:ellipsis;max-width:190px;overflow:hidden}:host-context(.dark) .job-code{color:#f1f5f9}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:2px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:inline;align-items:center;gap:3px;color:#22c55e;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px}.location-flow .pickup svg{width:8px;height:8px;position:absolute;left:0;top:5px}.location-flow .delivery{display:inline;align-items:center;gap:3px;color:#ef4444;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px;top:5px}.location-flow .delivery svg{width:8px;height:8px;position:absolute;left:0;top:5px}\n"], dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: RouteInfoCardComponent, selector: "lib-route-info-card", inputs: ["modalOpen", "routeData", "repository", "displayMode"], outputs: ["modalOpenChange", "edit"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
440
440
  }
441
441
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ViewRouteListComponent, decorators: [{
442
442
  type: Component,
443
- args: [{ selector: 'lib-view-route-list', standalone: true, imports: [LucideAngularModule, RouteInfoCardComponent, NgClass], template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n @if (listMode !== 'inline') {\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">View Route</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <lucide-icon [img]=\"icons.ChevronRight\" [size]=\"16\"></lucide-icon>\n } @else {\n <lucide-icon [img]=\"icons.ChevronLeft\" [size]=\"16\"></lucide-icon>\n }\n </button>\n </div>\n } \n \n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n <div class=\"cards-list\">\n @for (route of routes; track getRouteId(route)) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(getRouteId(route))\"\n [class.border-gray-200]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.selected]=\"selectedRouteIds.includes(getRouteId(route))\"\n >\n <div class=\"task-header justify-between items-start mb-1\">\n <h2 class=\"text-sm font-semibold text-gray-900 dark:text-white truncate max-w-[80%]\">\n {{ route.route_name || route.order_number || 'Unnamed Route' }}\n </h2>\n <div class=\"flex gap-2 shrink-0\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">\n {{ route.unit?.charAt(0) || 'U' }}\n </div>\n <button\n type=\"button\"\n class=\"text-gray-400 hover:text-brand-blue transition-colors\"\n (click)=\"$event.stopPropagation(); selectedRoute.set(route); showRouteModal = true\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"18\"></lucide-icon>\n </button>\n </div>\n </div>\n \n @if (route.customer_name) {\n <div class=\"text-[10px] text-gray-500 dark:text-slate-500 mb-2 uppercase tracking-wider font-medium truncate\">\n {{ route.customer_name }}\n </div>\n }\n\n <div class=\"location-flow bg-gray-50 dark:bg-slate-900/50 border border-gray-100 dark:border-slate-700/50 p-2 rounded-lg\">\n <div class=\"text-[11px] truncate flex items-center gap-1.5 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-green-500 shrink-0\"></div>\n {{ (route.pickup_location || '').split('|')[1] || route.pickup_location || 'N/A' }}\n </div>\n <div class=\"text-[11px] truncate flex items-center gap-1.5 mt-1 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-blue-500 shrink-0\"></div>\n {{ (route.delivery_location || '').split('|')[1] || route.delivery_location || 'N/A' }}\n </div>\n </div>\n </div>\n </div>\n } @empty {\n <div class=\"p-8 text-center text-gray-400 text-sm italic\">\n No routes found in this catalog.\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<lib-route-info-card \n [(modalOpen)]=\"showRouteModal\" \n [routeData]=\"selectedRoute()\" \n [repository]=\"config.repository\" \n displayMode=\"catalog\"\n (edit)=\"editRoute.emit(selectedRoute()!)\"\n></lib-route-info-card>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b);white-space:nowrap;text-overflow:ellipsis;max-width:190px;overflow:hidden}:host-context(.dark) .job-code{color:#f1f5f9}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:2px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:inline;align-items:center;gap:3px;color:#22c55e;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px}.location-flow .pickup svg{width:8px;height:8px;position:absolute;left:0;top:5px}.location-flow .delivery{display:inline;align-items:center;gap:3px;color:#ef4444;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px;top:5px}.location-flow .delivery svg{width:8px;height:8px;position:absolute;left:0;top:5px}\n"] }]
443
+ args: [{ selector: 'lib-view-route-list', standalone: true, imports: [LucideAngularModule, RouteInfoCardComponent, NgClass], template: "<div\n class=\"cards-list-container\"\n [class.floating]=\"listMode === 'floating'\"\n [class.sidebar]=\"listMode === 'sidebar'\"\n [class.inline]=\"listMode === 'inline'\"\n [class.collapsed]=\"collapsed\"\n>\n @if (listMode !== 'inline') {\n <div class=\"list-header\">\n <div class=\"header-title\">\n <span class=\"title-text\">View Route</span>\n <span class=\"routes-count\">({{ routes.length || 0 }})</span>\n </div>\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse()\"\n [title]=\"collapsed ? 'Expand' : 'Collapse'\"\n >\n @if (collapsed) {\n <lucide-icon [img]=\"icons.ChevronRight\" [size]=\"16\"></lucide-icon>\n } @else {\n <lucide-icon [img]=\"icons.ChevronLeft\" [size]=\"16\"></lucide-icon>\n }\n </button>\n </div>\n } \n \n @if (!collapsed) {\n <div class=\"cards-scroll-container\" #scrollContainer>\n <div class=\"cards-list\">\n @for (route of routes; track getRouteId(route)) {\n <div class=\"card-wrapper\" (click)=\"toggleRouteSelection(route)\">\n <div\n class=\"route-card bg-white dark:bg-slate-800 border transition-all duration-200\"\n [class.border-brand-blue]=\"selectedRouteIds.includes(getRouteId(route))\"\n [class.border-gray-200]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.dark:border-slate-700]=\"!selectedRouteIds.includes(getRouteId(route))\"\n [class.selected]=\"selectedRouteIds.includes(getRouteId(route))\"\n >\n <div class=\"task-header justify-between items-start mb-1\">\n <h2 class=\"text-sm font-semibold text-gray-900 dark:text-white truncate max-w-[80%]\">\n {{ route.route_name || route.order_number || 'Unnamed Route' }}\n </h2>\n <div class=\"flex gap-2 shrink-0\">\n <div class=\"statusunit text-white\" [ngClass]=\"route.unit || ''\">\n {{ route.unit?.charAt(0) || 'U' }}\n </div>\n <button\n type=\"button\"\n class=\"text-gray-400 hover:text-brand-blue transition-colors\"\n (click)=\"$event.stopPropagation(); selectedRoute.set(route); showRouteModal = true\"\n >\n <lucide-icon [img]=\"icons.Info\" [size]=\"18\"></lucide-icon>\n </button>\n </div>\n </div>\n \n @if (route.customer_name) {\n <div class=\"text-[10px] text-gray-500 dark:text-slate-500 mb-2 uppercase tracking-wider font-medium truncate\">\n {{ route.customer_name }}\n </div>\n }\n\n <div class=\"location-flow bg-gray-50 dark:bg-slate-900/50 border border-gray-100 dark:border-slate-700/50 p-2 rounded-lg\">\n <div class=\"text-[11px] truncate flex items-center gap-1.5 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-green-500 shrink-0 bullet\"></div>\n {{ (route.pickup_location || '').split('|')[1] || route.pickup_location || 'N/A' }}\n </div>\n <div class=\"text-[11px] truncate flex items-center gap-1.5 mt-1 text-gray-600 dark:text-gray-400\">\n <div class=\"w-1.5 h-1.5 rounded-full bg-blue-500 shrink-0 bullet\"></div>\n {{ (route.delivery_location || '').split('|')[1] || route.delivery_location || 'N/A' }}\n </div>\n </div>\n </div>\n </div>\n } @empty {\n <div class=\"p-8 text-center text-gray-400 text-sm italic\">\n No routes found in this catalog.\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<lib-route-info-card \n [(modalOpen)]=\"showRouteModal\" \n [routeData]=\"selectedRoute()\" \n [repository]=\"config.repository\" \n displayMode=\"catalog\"\n (edit)=\"editRoute.emit(selectedRoute()!)\"\n></lib-route-info-card>\n", styles: [":host{display:block}.cards-list-container{display:flex;flex-direction:column;height:100%;background:var(--bg-primary, white)}.cards-list-container.floating{position:absolute;top:12px;left:12px;width:280px;max-height:calc(100% - 24px);border-radius:12px;box-shadow:0 4px 24px #00000026;z-index:100;overflow:hidden}.cards-list-container.floating.collapsed{width:48px}.cards-list-container.sidebar{width:100%;border-right:1px solid var(--border-color, #e2e8f0)}.cards-list-container.inline{width:160px;min-width:160px;border-right:1px solid var(--border-color, #e2e8f0)}:host-context(.dark) .cards-list-container{background-color:#1e293b}:host-context(.dark) .cards-list-container.sidebar,:host-context(.dark) .cards-list-container.inline{border-color:#334155}.list-header{display:flex;align-items:center;justify-content:space-between;padding:12px;border-bottom:1px solid var(--border-color, #e2e8f0);background:var(--bg-secondary, #f8fafc)}:host-context(.dark) .list-header{background-color:#0f172a;border-color:#334155}.collapsed .list-header{padding:12px 8px;justify-content:center}.header-title{display:flex;align-items:center;gap:6px}.collapsed .header-title{display:none}.title-text{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b)}:host-context(.dark) .title-text{color:#f1f5f9}.cards-scroll-container{flex:1;overflow-y:auto;overflow-x:hidden}.cards-list{display:flex;flex-direction:column;gap:8px;padding:8px}.card-wrapper{border-radius:8px;transition:all .2s ease}.route-card{position:relative;padding:6px 10px;display:flex;flex-direction:column;gap:2px;border-radius:8px;cursor:pointer;transition:all .15s ease;min-height:72px}.route-card:hover{border-color:var(--accent-color, #3b82f6);box-shadow:0 2px 8px #00000014}.task-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.job-code{font-size:13px;font-weight:600;color:var(--text-primary, #1e293b);white-space:nowrap;text-overflow:ellipsis;max-width:190px;overflow:hidden}:host-context(.dark) .job-code{color:#f1f5f9}.statusunit{border-radius:30px;font-size:12px;text-transform:capitalize;font-weight:600;width:20px;height:20px;text-align:center;line-height:20px}.statusunit.Ton{background:#22c55e}.statusunit.Load{background:#3b82f6}.statusunit.Hourly{background:#f59e0b}.location-flow{display:flex;flex-direction:column;align-items:flex-start;gap:2px;font-size:11px;color:var(--text-secondary, #64748b);margin-bottom:6px}.location-flow .pickup{display:inline;align-items:center;gap:3px;color:#22c55e;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px}.location-flow .pickup svg{width:8px;height:8px;position:absolute;left:0;top:5px}.location-flow .delivery{display:inline;align-items:center;gap:3px;color:#ef4444;white-space:nowrap;text-overflow:ellipsis;max-width:200px;overflow:hidden;position:relative;padding-left:15px;top:5px}.location-flow .delivery svg{width:8px;height:8px;position:absolute;left:0;top:5px}\n"] }]
444
444
  }], propDecorators: { listMode: [{
445
445
  type: Input
446
446
  }], collapsible: [{
@@ -1401,7 +1401,7 @@ class CoolmapComponent {
1401
1401
  }, 0);
1402
1402
  }
1403
1403
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1404
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CoolmapComponent, isStandalone: true, selector: "lib-coolmap", inputs: { mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: false, isRequired: false, transformFunction: null }, activeSection: { classPropertyName: "activeSection", publicName: "activeSection", isSignal: false, isRequired: false, transformFunction: null }, customerRepoDetails: { classPropertyName: "customerRepoDetails", publicName: "customerRepoDetails", isSignal: false, isRequired: false, transformFunction: null }, darkMode: { classPropertyName: "darkMode", publicName: "darkMode", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["mapContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3\">\n @if (activeSection === 'Jobcode') {\n <input\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"w-auto lg:w-[200px] px-3 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n <div class=\"relative items-center flex\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-[150px] xl:w-[300px] pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-50 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-sm font-medium border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize text-xs text-gray-500 dark:text-gray-400 font-normal mr-1\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n }\n </div>\n\n @if (filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-1 rounded bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show All ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full left-1/2 -translate-x-1/2 mt-2 hidden group-hover:block bg-gray-800 text-white text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-1/2 -translate-x-1/2 border-4 border-transparent border-b-gray-800\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n\n <!-- FOR JOBCODE -->\n @if (activeSection === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:50}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "component", type: JobCodeComponent, selector: "lib-job-code", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds", "isLoading"], outputs: ["routeSelect"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: JobRouteListComponent, selector: "lib-job-route-list", inputs: ["customerRepoDetails", "selectedRouteIds", "modalOpen", "initialRoutes"], outputs: ["modalOpenChange", "routeSelect", "masterToggleEvent"] }, { kind: "component", type: ViewRouteListComponent, selector: "lib-view-route-list", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds"], outputs: ["routeSelect", "editRoute"] }, { kind: "component", type: AddRouteComponent, selector: "lib-add-route", inputs: ["modalOpen", "routeData", "customerRepoDetails"], outputs: ["modalOpenChange", "routeDeleted", "routeSaved"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
1404
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CoolmapComponent, isStandalone: true, selector: "lib-coolmap", inputs: { mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: false, isRequired: false, transformFunction: null }, activeSection: { classPropertyName: "activeSection", publicName: "activeSection", isSignal: false, isRequired: false, transformFunction: null }, customerRepoDetails: { classPropertyName: "customerRepoDetails", publicName: "customerRepoDetails", isSignal: false, isRequired: false, transformFunction: null }, darkMode: { classPropertyName: "darkMode", publicName: "darkMode", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["mapContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3\">\n @if (activeSection === 'Jobcode') {\n <input\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"w-auto lg:w-[200px] px-3 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n <div class=\"relative items-center flex\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-[150px] xl:w-[300px] pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-50 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-sm font-medium border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize text-xs text-gray-500 dark:text-gray-400 font-normal mr-1\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n }\n </div>\n\n @if (filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-1 rounded bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show All ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full left-1/2 -translate-x-1/2 mt-2 hidden group-hover:block bg-gray-800 text-white text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-1/2 -translate-x-1/2 border-4 border-transparent border-b-gray-800\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n\n <!-- FOR JOBCODE -->\n @if (activeSection === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:12}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "component", type: JobCodeComponent, selector: "lib-job-code", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds", "isLoading"], outputs: ["routeSelect"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: JobRouteListComponent, selector: "lib-job-route-list", inputs: ["customerRepoDetails", "selectedRouteIds", "modalOpen", "initialRoutes"], outputs: ["modalOpenChange", "routeSelect", "masterToggleEvent"] }, { kind: "component", type: ViewRouteListComponent, selector: "lib-view-route-list", inputs: ["listMode", "collapsible", "routes", "selectedRouteIds"], outputs: ["routeSelect", "editRoute"] }, { kind: "component", type: AddRouteComponent, selector: "lib-add-route", inputs: ["modalOpen", "routeData", "customerRepoDetails"], outputs: ["modalOpenChange", "routeDeleted", "routeSaved"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
1405
1405
  }
1406
1406
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapComponent, decorators: [{
1407
1407
  type: Component,
@@ -1412,7 +1412,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
1412
1412
  ViewRouteListComponent,
1413
1413
  AddRouteComponent,
1414
1414
  ReactiveFormsModule,
1415
- ], template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3\">\n @if (activeSection === 'Jobcode') {\n <input\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"w-auto lg:w-[200px] px-3 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n <div class=\"relative items-center flex\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-[150px] xl:w-[300px] pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-50 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-sm font-medium border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize text-xs text-gray-500 dark:text-gray-400 font-normal mr-1\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n }\n </div>\n\n @if (filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-1 rounded bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show All ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full left-1/2 -translate-x-1/2 mt-2 hidden group-hover:block bg-gray-800 text-white text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-1/2 -translate-x-1/2 border-4 border-transparent border-b-gray-800\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n\n <!-- FOR JOBCODE -->\n @if (activeSection === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:50}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
1415
+ ], template: "<div class=\"center-area\">\n <div [formGroup]=\"filterForm\" class=\"toolbar flex flex-col sm:flex-row md:h-[55px] h-auto py-2 px-2 gap-3 items-center\">\n <div class=\"toolbar-left flex items-center gap-3\">\n @if (activeSection === 'Jobcode') {\n <input\n type=\"date\"\n [value]=\"dateValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"w-auto lg:w-[200px] px-3 py-2 rounded-lg border border-gray-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-blue focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n <span class=\"toolbar-divider hidden sm:flex h-6 w-[1px] bg-gray-200 dark:bg-slate-700\"></span>\n }\n <div class=\"relative items-center flex\">\n <lucide-icon [img]=\"icons.Search\" [size]=\"18\" class=\"absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\"></lucide-icon>\n <input\n type=\"text\"\n formControlName=\"search\"\n [attr.disabled]=\"coolmapService.isLoading() ? true : null\"\n placeholder=\"Search routes...\"\n class=\"w-[150px] xl:w-[300px] pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-amber-500 focus:border-transparent text-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n />\n\n @if (filterForm.value.search) {\n <button (click)=\"filterForm.controls.search.setValue('')\" class=\"absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\">\n <lucide-icon [img]=\"icons.X\" [size]=\"16\"></lucide-icon>\n </button>\n }\n\n <!-- Autocomplete Dropdown -->\n @if (dropdownOpen() && filteredOptions().length > 0) {\n <div class=\"absolute z-50 left-0 right-0 top-full mt-1 max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded shadow-lg\">\n @for (option of filteredOptions(); track option.value + option.type) {\n <div (click)=\"selectFilter(option)\" class=\"px-4 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 cursor-pointer text-sm font-medium border-b border-gray-100 dark:border-slate-700 last:border-0 dark:text-white\">\n <span class=\"capitalize text-xs text-gray-500 dark:text-gray-400 font-normal mr-1\">{{ option.type }}:</span>\n {{ option.label }}\n </div>\n }\n </div>\n }\n </div>\n\n @if (filters().length > 0) {\n <div class=\"flex flex-wrap gap-2 ml-2\">\n @for (filter of filters(); track filter.value + filter.type) {\n <div class=\"inline-flex items-center gap-1 px-2 py-1 rounded bg-slate-200 dark:bg-slate-700 text-gray-800 dark:text-gray-200 text-xs font-medium border border-gray-300 dark:border-slate-600\">\n <span class=\"capitalize opacity-80\">{{ filter.type }}:</span> {{ filter.name }}\n <button type=\"button\" (click)=\"removeFilter(filter)\" class=\"hover:opacity-75 transition-opacity ml-1\">\n <lucide-icon [img]=\"icons.X\" [size]=\"12\"></lucide-icon>\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"toolbar-right\">\n @if (selectedRouteIds().length > 0) {\n <button\n type=\"button\"\n (click)=\"clearSelection()\"\n [disabled]=\"coolmapService.isLoading()\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n >\n Show All ({{ selectedRouteIds().length }})\n </button>\n }\n @if (activeSection === 'ViewRoute') {\n <button\n type=\"button\"\n class=\"inline-flex items-center justify-center gap-2 px-5 sm:px-6 py-2 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white font-medium rounded-lg transition-colors text-xs md:text-sm\"\n [disabled]=\"coolmapService.isLoading()\"\n (click)=\"openAddRouteModal()\">\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Add Route\n </button>\n }\n\n @if(activeSection === 'Jobcode'){\n <button\n class=\"inline-flex items-center gap-2 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed relative group\"\n (click)=\"showRouteList = true\"\n [disabled]=\"coolmapService.isLoading()\">\n <lucide-icon [img]=\"icons.Route\" [size]=\"20\"></lucide-icon>\n <div\n class=\"absolute top-full left-1/2 -translate-x-1/2 mt-2 hidden group-hover:block bg-gray-800 text-white text-[10px] rounded py-1 px-2 whitespace-nowrap\">\n Show Route List\n <div\n class=\"absolute -top-[8px] left-1/2 -translate-x-1/2 border-4 border-transparent border-b-gray-800\">\n </div>\n </div>\n </button>}\n </div>\n </div>\n <div class=\"view-content\">\n <div class=\"full-view\">\n <div class=\"map-container\">\n <div class=\"mapbox-container\" #mapContainer></div>\n </div>\n </div>\n\n <!-- FOR JOBCODE -->\n @if (activeSection === 'Jobcode') {\n <lib-job-code \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n [isLoading]=\"coolmapService.isLoading()\"\n (routeSelect)=\"toggleSelection($event)\">\n </lib-job-code>\n }\n\n <!-- FOR VIEWROUTE -->\n @if (activeSection === 'ViewRoute') {\n <lib-view-route-list \n listMode=\"floating\" \n [routes]=\"activeFilteredRoutes()\"\n [selectedRouteIds]=\"selectedRouteIds()\"\n (routeSelect)=\"toggleSelection($event)\"\n (editRoute)=\"openEditModal($event)\"\n ></lib-view-route-list>\n }\n </div>\n @if (config.repository === 'coolmap') {\n <div class=\"status-bar\">\n <div class=\"stats-row\">\n <div class=\"stat-item active\" title=\"Active routes (assigned + in progress)\">\n <span class=\"stat-count\">{{ masterStats().Done }}</span>\n <span class=\"stat-label\">Done</span>\n </div>\n\n <div class=\"stat-item completed\" title=\"Completed tasks\">\n <span class=\"stat-count\">{{ masterStats().Incomplete }}</span>\n <span class=\"stat-label\">Incomplete</span>\n </div>\n\n <div class=\"stat-item declined\" title=\"Declined routes - needs attention\">\n <span class=\"stat-count\">{{ masterStats().Ongoing }}</span>\n <span class=\"stat-label\">Ongoing</span>\n </div>\n\n <div class=\"stat-item scheduled\" title=\"Scheduled jobs for today\">\n <span class=\"stat-count\">{{ masterStats().Open }}</span>\n <span class=\"stat-label\">Open</span>\n </div>\n </div>\n </div>\n }\n</div>\n<lib-job-route-list \n [initialRoutes]=\"viewRoutesList()\"\n [(modalOpen)]=\"showRouteList\"\n [selectedRouteIds]=\"modalPlottedIds()\"\n (routeSelect)=\"toggleModalRoute($event)\"\n (masterToggleEvent)=\"modalMasterToggle($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n></lib-job-route-list>\n<lib-add-route \n [modalOpen]=\"addRouteModal\"\n (modalOpenChange)=\"onAddRouteModalChange($event)\"\n (routeSaved)=\"onRouteSaved($event)\"\n (routeDeleted)=\"onRouteDeleted($event)\"\n [customerRepoDetails]=\"customerRepoDetails\"\n [routeData]=\"selectedRouteForEdit()\"\n></lib-add-route>\n", styles: [":host{display:block;width:100%;height:100%;min-height:400px}.center-area{height:100%;display:flex;flex-direction:column;overflow:hidden}.view-content{flex:1;position:relative;overflow:hidden;z-index:10}.full-view{position:absolute;inset:0}.map-container,.mapbox-container{width:100%;height:100%}.toolbar{align-items:center;justify-content:space-between;background:var(--bg-primary, white);border-bottom:1px solid var(--border-color, #e2e8f0);flex-shrink:0;gap:8px;position:relative;z-index:12}:host-context(.dark) .toolbar{background:var(--bg-dark-primary, #1e293b);border-color:var(--border-dark, #334155);box-shadow:0 1px 3px #0000004d}.toolbar-left{display:flex;align-items:center;gap:12px;flex-shrink:0}.toolbar-divider{width:1px;height:20px;background:var(--border-color, #e2e8f0);margin:0 2px;flex-shrink:0}:host-context(.dark) .toolbar-divider{background:#475569}.toolbar-right{display:flex;align-items:center;gap:10px;flex-shrink:0}.status-bar{display:flex;align-items:center;height:100%;padding:0 16px;background:var(--status-bar-bg, #1e293b);color:#fff;font-size:12px;gap:20px;flex-shrink:0;height:36px}.stats-row{display:flex;align-items:center;gap:20px}.stat-item{display:flex;align-items:center;gap:6px;cursor:default}.stat-count{font-size:15px;font-weight:700;line-height:1}.stat-item.active .stat-count{color:#60a5fa}.stat-item.completed .stat-count{color:#4ade80}.stat-item.declined .stat-count{color:#f87171}.stat-item.scheduled .stat-count{color:#a78bfa}.stat-item.pending .stat-count{color:#fbbf24}.route-list-wrapper{position:absolute;top:10px;left:10px;bottom:10px;width:380px;z-index:20;pointer-events:none;display:flex;flex-direction:column}@media (max-width: 1024px){.route-list-wrapper{width:320px}}.route-list-wrapper>*{pointer-events:auto}.list-loader{position:absolute;inset:0;background:#fff6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:100;border-radius:12px;border:1px solid rgba(255,255,255,.2);box-shadow:0 8px 32px #1f268712}:host-context(.dark) .list-loader{background:#0f172a66;border-color:#ffffff1a}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
1416
1416
  }], ctorParameters: () => [], propDecorators: { mobileMode: [{
1417
1417
  type: Input
1418
1418
  }], activeSection: [{