1import { 2 v4_default 3} from "./chunk-33EQSEY6.js"; 4import { 5 AlertController, 6 IonBackButton, 7 IonBadge, 8 IonButton, 9 IonButtons, 10 IonContent, 11 IonHeader, 12 IonInput, 13 IonItem, 14 IonLabel, 15 IonList, 16 IonSpinner, 17 IonTextarea, 18 IonTitle, 19 IonToggle, 20 IonToolbar, 21 ToastController 22} from "./chunk-RLZ522BW.js"; 23import { 24 DatabaseService, 25 EntityType 26} from "./chunk-RLJCY5HS.js"; 27import { 28 TranslateModule, 29 TranslatePipe, 30 TranslateService 31} from "./chunk-O5XYYQCR.js"; 32import { 33 AuthService, 34 News, 35 UserRole 36} from "./chunk-QGEJYSW7.js"; 37import { 38 ApiUrlService 39} from "./chunk-MAIAEXGG.js"; 40import "./chunk-L4O6SE3A.js"; 41import { 42 NgIcon, 43 lucideCalendar, 44 lucideImage, 45 lucidePencil, 46 lucideSave, 47 lucideStar, 48 lucideTrash2, 49 lucideUser, 50 lucideX, 51 provideIcons 52} from "./chunk-GMPIA5L4.js"; 53import { 54 ActivatedRoute, 55 CommonModule, 56 Component, 57 DatePipe, 58 FormsModule, 59 Location, 60 NgControlStatus, 61 NgModel, 62 RequiredValidator, 63 Router, 64 Subject, 65 setClassMetadata, 66 takeUntil, 67 ɵsetClassDebugInfo, 68 ɵɵProvidersFeature, 69 ɵɵadvance, 70 ɵɵconditional, 71 ɵɵdefineComponent, 72 ɵɵdirectiveInject, 73 ɵɵelement, 74 ɵɵelementEnd, 75 ɵɵelementStart, 76 ɵɵgetCurrentView, 77 ɵɵlistener, 78 ɵɵnextContext, 79 ɵɵpipe, 80 ɵɵpipeBind1, 81 ɵɵpipeBind2, 82 ɵɵproperty, 83 ɵɵresetView, 84 ɵɵrestoreView, 85 ɵɵsanitizeUrl, 86 ɵɵtemplate, 87 ɵɵtext, 88 ɵɵtextInterpolate, 89 ɵɵtextInterpolate1, 90 ɵɵtextInterpolate2, 91 ɵɵtwoWayBindingSet, 92 ɵɵtwoWayListener, 93 ɵɵtwoWayProperty 94} from "./chunk-UQ6LLOJ6.js"; 95import "./chunk-V3YFOG6Q.js"; 96import "./chunk-LPMBLWVS.js"; 97import "./chunk-S6LHOZ5A.js"; 98import "./chunk-Y6HZOH3Q.js"; 99import "./chunk-TWQHADEW.js"; 100import "./chunk-3J4L7S6G.js"; 101import "./chunk-IL42VKT6.js"; 102import "./chunk-LONO5O5R.js"; 103import "./chunk-KFBF5L4X.js"; 104import "./chunk-PWC4K6CW.js"; 105import "./chunk-R6JLIESI.js"; 106import "./chunk-UG6K57PI.js"; 107import "./chunk-UR6VIRNL.js"; 108import "./chunk-OJO5RD3M.js"; 109import { 110 __async 111} from "./chunk-CO64IJQE.js"; 112 113// src/app/pages/news-detail/news-detail.page.ts 114function NewsDetailPage_Conditional_7_Template(rf, ctx) { 115 if (rf & 1) { 116 const _r1 = \u0275\u0275getCurrentView(); 117 \u0275\u0275elementStart(0, "ion-button", 7); 118 \u0275\u0275listener("click", function NewsDetailPage_Conditional_7_Template_ion_button_click_0_listener() { 119 \u0275\u0275restoreView(_r1); 120 const ctx_r1 = \u0275\u0275nextContext(); 121 return \u0275\u0275resetView(ctx_r1.enterEditMode()); 122 }); 123 \u0275\u0275element(1, "ng-icon", 8); 124 \u0275\u0275elementEnd(); 125 } 126} 127function NewsDetailPage_Conditional_8_Conditional_1_Template(rf, ctx) { 128 if (rf & 1) { 129 \u0275\u0275element(0, "ion-spinner", 10); 130 } 131} 132function NewsDetailPage_Conditional_8_Conditional_2_Template(rf, ctx) { 133 if (rf & 1) { 134 \u0275\u0275element(0, "ng-icon", 11); 135 } 136} 137function NewsDetailPage_Conditional_8_Template(rf, ctx) { 138 if (rf & 1) { 139 const _r3 = \u0275\u0275getCurrentView(); 140 \u0275\u0275elementStart(0, "ion-button", 9); 141 \u0275\u0275listener("click", function NewsDetailPage_Conditional_8_Template_ion_button_click_0_listener() { 142 \u0275\u0275restoreView(_r3); 143 const ctx_r1 = \u0275\u0275nextContext(); 144 return \u0275\u0275resetView(ctx_r1.saveNews()); 145 }); 146 \u0275\u0275template(1, NewsDetailPage_Conditional_8_Conditional_1_Template, 1, 0, "ion-spinner", 10)(2, NewsDetailPage_Conditional_8_Conditional_2_Template, 1, 0, "ng-icon", 11); 147 \u0275\u0275elementEnd(); 148 } 149 if (rf & 2) { 150 const ctx_r1 = \u0275\u0275nextContext(); 151 \u0275\u0275property("disabled", ctx_r1.saving); 152 \u0275\u0275advance(); 153 \u0275\u0275conditional(ctx_r1.saving ? 1 : 2); 154 } 155} 156function NewsDetailPage_Conditional_10_Template(rf, ctx) { 157 if (rf & 1) { 158 \u0275\u0275elementStart(0, "div", 4); 159 \u0275\u0275element(1, "ion-spinner", 12); 160 \u0275\u0275elementEnd(); 161 } 162} 163function NewsDetailPage_Conditional_11_Conditional_21_Template(rf, ctx) { 164 if (rf & 1) { 165 \u0275\u0275text(0); 166 \u0275\u0275pipe(1, "translate"); 167 } 168 if (rf & 2) { 169 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(1, 1, "news.form.saving"), " "); 170 } 171} 172function NewsDetailPage_Conditional_11_Conditional_22_Template(rf, ctx) { 173 if (rf & 1) { 174 \u0275\u0275text(0); 175 \u0275\u0275pipe(1, "translate"); 176 } 177 if (rf & 2) { 178 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(1, 1, "news.form.save"), " "); 179 } 180} 181function NewsDetailPage_Conditional_11_Conditional_26_Template(rf, ctx) { 182 if (rf & 1) { 183 const _r5 = \u0275\u0275getCurrentView(); 184 \u0275\u0275elementStart(0, "ion-button", 20); 185 \u0275\u0275listener("click", function NewsDetailPage_Conditional_11_Conditional_26_Template_ion_button_click_0_listener() { 186 \u0275\u0275restoreView(_r5); 187 const ctx_r1 = \u0275\u0275nextContext(2);
188 return \u0275\u0275resetView(ctx_r1.confirmDelete()); 189 }); 190 \u0275\u0275element(1, "ng-icon", 21); 191 \u0275\u0275text(2); 192 \u0275\u0275pipe(3, "translate"); 193 \u0275\u0275elementEnd(); 194 } 195 if (rf & 2) { 196 \u0275\u0275advance(2); 197 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(3, 1, "news.delete"), " "); 198 } 199} 200function NewsDetailPage_Conditional_11_Template(rf, ctx) { 201 if (rf & 1) { 202 const _r4 = \u0275\u0275getCurrentView(); 203 \u0275\u0275elementStart(0, "div", 5)(1, "ion-list")(2, "ion-item")(3, "ion-input", 13); 204 \u0275\u0275pipe(4, "translate"); 205 \u0275\u0275pipe(5, "translate"); 206 \u0275\u0275twoWayListener("ngModelChange", function NewsDetailPage_Conditional_11_Template_ion_input_ngModelChange_3_listener($event) { 207 \u0275\u0275restoreView(_r4); 208 const ctx_r1 = \u0275\u0275nextContext(); 209 \u0275\u0275twoWayBindingSet(ctx_r1.formTitle, $event) || (ctx_r1.formTitle = $event); 210 return \u0275\u0275resetView($event); 211 }); 212 \u0275\u0275elementEnd()(); 213 \u0275\u0275elementStart(6, "ion-item")(7, "ion-textarea", 14); 214 \u0275\u0275pipe(8, "translate"); 215 \u0275\u0275pipe(9, "translate"); 216 \u0275\u0275twoWayListener("ngModelChange", function NewsDetailPage_Conditional_11_Template_ion_textarea_ngModelChange_7_listener($event) { 217 \u0275\u0275restoreView(_r4); 218 const ctx_r1 = \u0275\u0275nextContext(); 219 \u0275\u0275twoWayBindingSet(ctx_r1.formContent, $event) || (ctx_r1.formContent = $event); 220 return \u0275\u0275resetView($event); 221 }); 222 \u0275\u0275elementEnd()(); 223 \u0275\u0275elementStart(10, "ion-item")(11, "ion-toggle", 15); 224 \u0275\u0275twoWayListener("ngModelChange", function NewsDetailPage_Conditional_11_Template_ion_toggle_ngModelChange_11_listener($event) { 225 \u0275\u0275restoreView(_r4); 226 const ctx_r1 = \u0275\u0275nextContext(); 227 \u0275\u0275twoWayBindingSet(ctx_r1.formIsFeatured, $event) || (ctx_r1.formIsFeatured = $event); 228 return \u0275\u0275resetView($event); 229 }); 230 \u0275\u0275elementStart(12, "ion-label")(13, "h2"); 231 \u0275\u0275text(14); 232 \u0275\u0275pipe(15, "translate"); 233 \u0275\u0275elementEnd(); 234 \u0275\u0275elementStart(16, "p"); 235 \u0275\u0275text(17); 236 \u0275\u0275pipe(18, "translate"); 237 \u0275\u0275elementEnd()()()()(); 238 \u0275\u0275elementStart(19, "div", 16)(20, "ion-button", 17); 239 \u0275\u0275listener("click", function NewsDetailPage_Conditional_11_Template_ion_button_click_20_listener() { 240 \u0275\u0275restoreView(_r4); 241 const ctx_r1 = \u0275\u0275nextContext(); 242 return \u0275\u0275resetView(ctx_r1.saveNews()); 243 }); 244 \u0275\u0275template(21, NewsDetailPage_Conditional_11_Conditional_21_Template, 2, 3)(22, NewsDetailPage_Conditional_11_Conditional_22_Template, 2, 3); 245 \u0275\u0275elementEnd(); 246 \u0275\u0275elementStart(23, "ion-button", 18); 247 \u0275\u0275listener("click", function NewsDetailPage_Conditional_11_Template_ion_button_click_23_listener() { 248 \u0275\u0275restoreView(_r4); 249 const ctx_r1 = \u0275\u0275nextContext(); 250 return \u0275\u0275resetView(ctx_r1.cancelEdit()); 251 }); 252 \u0275\u0275text(24); 253 \u0275\u0275pipe(25, "translate"); 254 \u0275\u0275elementEnd(); 255 \u0275\u0275template(26, NewsDetailPage_Conditional_11_Conditional_26_Template, 4, 3, "ion-button", 19); 256 \u0275\u0275elementEnd()(); 257 } 258 if (rf & 2) { 259 const ctx_r1 = \u0275\u0275nextContext(); 260 \u0275\u0275advance(3); 261 \u0275\u0275twoWayProperty("ngModel", ctx_r1.formTitle); 262 \u0275\u0275property("label", \u0275\u0275pipeBind1(4, 15, "news.form.title"))("placeholder", \u0275\u0275pipeBind1(5, 17, "news.form.titlePlaceholder")); 263 \u0275\u0275advance(4); 264 \u0275\u0275twoWayProperty("ngModel", ctx_r1.formContent); 265 \u0275\u0275property("label", \u0275\u0275pipeBind1(8, 19, "news.form.content"))("placeholder", \u0275\u0275pipeBind1(9, 21, "news.form.contentPlaceholder"))("autoGrow", true)("rows", 8); 266 \u0275\u0275advance(4); 267 \u0275\u0275twoWayProperty("ngModel", ctx_r1.formIsFeatured); 268 \u0275\u0275advance(3); 269 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(15, 23, "news.form.featured")); 270 \u0275\u0275advance(3); 271 \u0275\u0275textInterpolate(\u0275\u0275pipeBind1(18, 25, "news.form.featuredDescription")); 272 \u0275\u0275advance(3); 273 \u0275\u0275property("disabled", ctx_r1.saving); 274 \u0275\u0275advance(); 275 \u0275\u0275conditional(ctx_r1.saving ? 21 : 22); 276 \u0275\u0275advance(3); 277 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(25, 27, "news.form.cancel"), " "); 278 \u0275\u0275advance(2); 279 \u0275\u0275conditional(!ctx_r1.isNewArticle && ctx_r1.canEdit ? 26 : -1); 280 } 281} 282function NewsDetailPage_Conditional_12_Conditional_1_Template(rf, ctx) { 283 if (rf & 1) { 284 \u0275\u0275elementStart(0, "div", 22); 285 \u0275\u0275element(1, "img", 32); 286 \u0275\u0275elementEnd(); 287 } 288 if (rf & 2) { 289 const ctx_r1 = \u0275\u0275nextContext(2); 290 \u0275\u0275advance(); 291 \u0275\u0275property("src", ctx_r1.imageUrl, \u0275\u0275sanitizeUrl)("alt", ctx_r1.news.entity.title); 292 } 293} 294function NewsDetailPage_Conditional_12_Conditional_3_Template(rf, ctx) { 295 if (rf & 1) { 296 \u0275\u0275elementStart(0, "ion-badge", 24); 297 \u0275\u0275element(1, "ng-icon", 33); 298 \u0275\u0275text(2); 299 \u0275\u0275pipe(3, "translate"); 300 \u0275\u0275elementEnd(); 301 } 302 if (rf & 2) { 303 \u0275\u0275advance(2); 304 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind1(3, 1, "news.featured"), " "); 305 } 306} 307function NewsDetailPage_Conditional_12_Template(rf, ctx) { 308 if (rf & 1) { 309 \u0275\u0275elementStart(0, "div", 6); 310 \u0275\u0275template(1, NewsDetailPage_Conditional_12_Conditional_1_Template, 2, 2, "div", 22); 311 \u0275\u0275elementStart(2, "div", 23); 312 \u0275\u0275template(3, NewsDetailPage_Conditional_12_Conditional_3_Template, 4, 3, "ion-badge", 24); 313 \u0275\u0275elementStart(4, "h1", 25); 314 \u0275\u0275text(5); 315 \u0275\u0275elementEnd(); 316 \u0275\u0275elementStart(6, "div", 26)(7, "span", 27); 317 \u0275\u0275element(8, "ng-icon", 28); 318 \u0275\u0275text(9); 319 \u0275\u0275pipe(10, "date"); 320 \u0275\u0275elementEnd(); 321 \u0275\u0275elementStart(11, "span", 27); 322 \u0275\u0275element(12, "ng-icon", 29); 323 \u0275\u0275text(13); 324 \u0275\u0275pipe(14, "translate"); 325 \u0275\u0275elementEnd()(); 326 \u0275\u0275element(15, "div", 30); 327 \u0275\u0275elementStart(16, "div", 31); 328 \u0275\u0275text(17); 329 \u0275\u0275elementEnd()()(); 330 } 331 if (rf & 2) { 332 const ctx_r1 = \u0275\u0275nextContext(); 333 \u0275\u0275advance(); 334 \u0275\u0275conditional(ctx_r1.imageUrl ? 1 : -1); 335 \u0275\u0275advance(2); 336 \u0275\u0275conditional(ctx_r1.news.entity.isFeatured ? 3 : -1); 337 \u0275\u0275advance(2); 338 \u0275\u0275textInterpolate(ctx_r1.news.entity.title); 339 \u0275\u0275advance(4); 340 \u0275\u0275textInterpolate1(" ", \u0275\u0275pipeBind2(10, 7, ctx_r1.publishedDate, "longDate"), " "); 341 \u0275\u0275advance(4); 342 \u0275\u0275textInterpolate2(" ", \u0275\u0275pipeBind1(14, 10, "news.by"), " ", ctx_r1.authorName, " "); 343 \u0275\u0275advance(4); 344 \u0275\u0275textInterpolate1(" ", ctx_r1.news.entity.content, " "); 345 } 346} 347var _NewsDetailPage = class _NewsDetailPage { 348 constructor(route, router, location, databaseService, authService, apiUrlService, alertController, toastController, translate) { 349 this.route = route; 350 this.router = router; 351 this.location = location; 352 this.databaseService = databaseService; 353 this.authService = authService; 354 this.apiUrlService = apiUrlService; 355 this.alertController = alertController; 356 this.toastController = toastController; 357 this.translate = translate; 358 this.destroy$ = new Subject(); 359 this.newsId = null; 360 this.news = null; 361 this.isEditMode = false;
362 this.isNewArticle = false; 363 this.loading = true; 364 this.saving = false; 365 this.formTitle = ""; 366 this.formContent = ""; 367 this.formIsFeatured = false; 368 this.formCampusId = ""; 369 } 370 ngOnInit() { 371 this.route.paramMap.pipe(takeUntil(this.destroy$)).subscribe((params) => { 372 const id = params.get("id"); 373 if (id === "new" || this.router.url === "/news/new") { 374 this.isNewArticle = true; 375 this.isEditMode = true; 376 this.loading = false; 377 this.initNewArticle(); 378 } else if (id) { 379 this.newsId = id; 380 this.loadNews(); 381 } 382 }); 383 } 384 ngOnDestroy() { 385 this.destroy$.next(); 386 this.destroy$.complete(); 387 } 388 get canEdit() { 389 return this.authService.hasRole(UserRole.Moderator); 390 } 391 get imageUrl() { 392 var _a; 393 if (!((_a = this.news) == null ? void 0 : _a.entity.imageUploadId)) 394 return null; 395 return `${this.apiUrlService.getSelectedUrl()}/api/v1/media/${this.news.entity.imageUploadId}`; 396 } 397 get authorName() { 398 var _a, _b; 399 return ((_b = (_a = this.news) == null ? void 0 : _a.author) == null ? void 0 : _b.entity.name) || this.translate.instant("news.unknownAuthor"); 400 } 401 get publishedDate() { 402 var _a; 403 if (!((_a = this.news) == null ? void 0 : _a.entity.publishedAt)) 404 return null; 405 return new Date(this.news.entity.publishedAt); 406 } 407 get pageTitle() { 408 var _a; 409 if (this.isNewArticle) 410 return this.translate.instant("news.create"); 411 if (this.isEditMode) 412 return this.translate.instant("news.edit"); 413 return ((_a = this.news) == null ? void 0 : _a.entity.title) || ""; 414 } 415 initNewArticle() { 416 var _a; 417 for (const [, model] of this.databaseService.Models) { 418 if (model.type === EntityType.PERSON_CAMPUS) { 419 const pc = model.entity; 420 if (pc.personId === ((_a = this.authService.currentUserValue) == null ? void 0 : _a.id) && pc.campusId) { 421 this.formCampusId = pc.campusId; 422 break; 423 } 424 } 425 } 426 if (!this.formCampusId && this.authService.hasRole(UserRole.Admin)) { 427 for (const [, model] of this.databaseService.Models) { 428 if (model.type === EntityType.CAMPUS && !model.entity.isDeleted) { 429 this.formCampusId = model.entity.id; 430 break; 431 } 432 } 433 } 434 } 435 loadNews() { 436 const model = this.databaseService.Models.get(this.newsId); 437 if (model && model.type === EntityType.NEWS) { 438 this.news = model; 439 this.populateForm(); 440 } 441 this.loading = false; 442 } 443 populateForm() { 444 if (!this.news) 445 return; 446 this.formTitle = this.news.entity.title || ""; 447 this.formContent = this.news.entity.content || ""; 448 this.formIsFeatured = this.news.entity.isFeatured || false; 449 this.formCampusId = this.news.entity.campusId || ""; 450 } 451 enterEditMode() { 452 this.isEditMode = true; 453 this.populateForm(); 454 } 455 cancelEdit() { 456 if (this.isNewArticle) { 457 this.location.back(); 458 } else { 459 this.isEditMode = false; 460 this.populateForm(); 461 } 462 } 463 saveNews() { 464 return __async(this, null, function* () { 465 var _a; 466 if (!this.formTitle.trim()) { 467 this.showToast(this.translate.instant("news.validation.titleRequired"), "warning"); 468 return; 469 } 470 if (!this.formContent.trim()) { 471 this.showToast(this.translate.instant("news.validation.contentRequired"), "warning"); 472 return; 473 } 474 this.saving = true; 475 try { 476 if (this.isNewArticle) { 477 const newNews = new News(); 478 newNews.id = v4_default(); 479 newNews.isDeleted = false; 480 newNews.version = 0; 481 newNews.campusId = this.formCampusId; 482 newNews.title = this.formTitle.trim(); 483 newNews.content = this.formContent.trim(); 484 newNews.isFeatured = this.formIsFeatured; 485 newNews.publishedAt = (/* @__PURE__ */ new Date()).toISOString(); 486 newNews.authorId = ((_a = this.authService.currentUserValue) == null ? void 0 : _a.id) || void 0; 487 yield this.databaseService.addEntity(newNews); 488 this.showToast(this.translate.instant("news.success.created"), "success"); 489 this.router.navigate(["/news"]); 490 } else if (this.news) { 491 this.news.entity.title = this.formTitle.trim(); 492 this.news.entity.content = this.formContent.trim(); 493 this.news.entity.isFeatured = this.formIsFeatured; 494 yield this.databaseService.updateEntity(this.news.entity); 495 this.showToast(this.translate.instant("news.success.updated"), "success"); 496 this.isEditMode = false;
497 } 498 } catch (error) { 499 console.error("Failed to save news:", error); 500 this.showToast(this.translate.instant("news.error.save"), "danger"); 501 } finally { 502 this.saving = false; 503 } 504 }); 505 } 506 confirmDelete() { 507 return __async(this, null, function* () { 508 const alert = yield this.alertController.create({ 509 header: this.translate.instant("news.deleteConfirm.title"), 510 message: this.translate.instant("news.deleteConfirm.message"), 511 buttons: [ 512 { 513 text: this.translate.instant("news.form.cancel"), 514 role: "cancel" 515 }, 516 { 517 text: this.translate.instant("news.delete"), 518 role: "destructive", 519 handler: () => this.deleteNews() 520 } 521 ] 522 }); 523 yield alert.present(); 524 }); 525 } 526 deleteNews() { 527 return __async(this, null, function* () { 528 if (!this.news) 529 return; 530 try { 531 yield this.databaseService.deleteEntity(this.news.entity); 532 this.showToast(this.translate.instant("news.success.deleted"), "success"); 533 this.router.navigate(["/news"]); 534 } catch (error) { 535 console.error("Failed to delete news:", error); 536 this.showToast(this.translate.instant("news.error.delete"), "danger"); 537 } 538 }); 539 } 540 showToast(message, color) { 541 return __async(this, null, function* () { 542 const toast = yield this.toastController.create({ 543 message, 544 duration: 3e3, 545 color, 546 position: "bottom" 547 }); 548 yield toast.present(); 549 }); 550 } 551}; 552_NewsDetailPage.\u0275fac = function NewsDetailPage_Factory(__ngFactoryType__) { 553 return new (__ngFactoryType__ || _NewsDetailPage)(\u0275\u0275directiveInject(ActivatedRoute), \u0275\u0275directiveInject(Router), \u0275\u0275directiveInject(Location), \u0275\u0275directiveInject(DatabaseService), \u0275\u0275directiveInject(AuthService), \u0275\u0275directiveInject(ApiUrlService), \u0275\u0275directiveInject(AlertController), \u0275\u0275directiveInject(ToastController), \u0275\u0275directiveInject(TranslateService)); 554}; 555_NewsDetailPage.\u0275cmp = /* @__PURE__ */ \u0275\u0275defineComponent({ type: _NewsDetailPage, selectors: [["app-news-detail"]], features: [\u0275\u0275ProvidersFeature([], [provideIcons({ 556 lucideCalendar, 557 lucideUser, 558 lucidePencil, 559 lucideTrash2, 560 lucideSave, 561 lucideX, 562 lucideImage, 563 lucideStar 564})])], decls: 13, vars: 4, consts: [["slot", "start"], ["defaultHref", "/news"], ["slot", "end"], [3, "disabled"], [1, "loading-container"], [1, "edit-form"], [1, "article-view"], [3, "click"], ["name", "lucidePencil", "size", "1.2em"], [3, "click", "disabled"], ["name", "crescent", "size", "small"], ["name", "lucideSave", "size", "1.2em"], ["name", "crescent"], ["labelPlacement", "stacked", "type", "text", "required", "", 3, "ngModelChange", "ngModel", "label", "placeholder"], ["labelPlacement", "stacked", "required", "", 3, "ngModelChange", "ngModel", "label", "placeholder", "autoGrow", "rows"], ["labelPlacement", "start", 3, "ngModelChange", "ngModel"], [1, "form-actions"], ["expand", "block", 3, "click", "disabled"], ["expand", "block", "fill", "outline", 3, "click"], ["expand", "block", "fill", "clear", "color", "danger"], ["expand", "block", "fill", "clear", "color", "danger", 3, "click"], ["name", "lucideTrash2", "size", "1.1em", "slot", "start"], [1, "article-image"], [1, "article-content"], ["color", "warning", 1, "featured-badge"], [1, "article-title"], [1, "article-meta"], [1, "meta-item"], ["name", "lucideCalendar", "size", "1em"], ["name", "lucideUser", "size", "1em"], [1, "article-divider"], [1, "article-body"], [3, "src", "alt"], ["name", "lucideStar", "size", "0.9em"]], template: function NewsDetailPage_Template(rf, ctx) { 565 if (rf & 1) { 566 \u0275\u0275elementStart(0, "ion-header")(1, "ion-toolbar")(2, "ion-buttons", 0); 567 \u0275\u0275element(3, "ion-back-button", 1); 568 \u0275\u0275elementEnd(); 569 \u0275\u0275elementStart(4, "ion-title"); 570 \u0275\u0275text(5); 571 \u0275\u0275elementEnd(); 572 \u0275\u0275elementStart(6, "ion-buttons", 2); 573 \u0275\u0275template(7, NewsDetailPage_Conditional_7_Template, 2, 0, "ion-button")(8, NewsDetailPage_Conditional_8_Template, 3, 2, "ion-button", 3); 574 \u0275\u0275elementEnd()()(); 575 \u0275\u0275elementStart(9, "ion-content"); 576 \u0275\u0275template(10, NewsDetailPage_Conditional_10_Template, 2, 0, "div", 4)(11, NewsDetailPage_Conditional_11_Template, 27, 29, "div", 5)(12, NewsDetailPage_Conditional_12_Template, 18, 12, "div", 6); 577 \u0275\u0275elementEnd(); 578 } 579 if (rf & 2) { 580 \u0275\u0275advance(5); 581 \u0275\u0275textInterpolate(ctx.pageTitle); 582 \u0275\u0275advance(2); 583 \u0275\u0275conditional(!ctx.isEditMode && ctx.canEdit && ctx.news ? 7 : -1); 584 \u0275\u0275advance(); 585 \u0275\u0275conditional(ctx.isEditMode ? 8 : -1); 586 \u0275\u0275advance(2); 587 \u0275\u0275conditional(ctx.loading ? 10 : ctx.isEditMode ? 11 : ctx.news ? 12 : -1); 588 } 589}, dependencies: [ 590 CommonModule, 591 DatePipe, 592 FormsModule, 593 NgControlStatus, 594 RequiredValidator, 595 NgModel, 596 TranslateModule, 597 TranslatePipe, 598 NgIcon, 599 IonHeader, 600 IonToolbar, 601 IonButtons, 602 IonBackButton, 603 IonTitle, 604 IonContent, 605 IonButton, 606 IonBadge, 607 IonSpinner, 608 IonInput, 609 IonTextarea,
610 IonToggle, 611 IonItem, 612 IonLabel, 613 IonList 614], styles: ["\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 50vh;\n}\n.article-view[_ngcontent-%COMP%] .article-image[_ngcontent-%COMP%] {\n width: 100%;\n max-height: 300px;\n overflow: hidden;\n}\n.article-view[_ngcontent-%COMP%] .article-image[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.article-view[_ngcontent-%COMP%] .article-content[_ngcontent-%COMP%] {\n padding: 20px;\n}\n@media (min-width: 768px) {\n .article-view[_ngcontent-%COMP%] .article-content[_ngcontent-%COMP%] {\n max-width: 800px;\n margin: 0 auto;\n padding: 24px 32px;\n }\n}\n.article-view[_ngcontent-%COMP%] .featured-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n.article-view[_ngcontent-%COMP%] .article-title[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 700;\n line-height: 1.3;\n margin: 0 0 16px;\n color: var(--ion-text-color);\n}\n@media (min-width: 768px) {\n .article-view[_ngcontent-%COMP%] .article-title[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n}\n.article-view[_ngcontent-%COMP%] .article-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 16px;\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n margin-bottom: 20px;\n}\n.article-view[_ngcontent-%COMP%] .article-meta[_ngcontent-%COMP%] .meta-item[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.article-view[_ngcontent-%COMP%] .article-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--ion-color-light);\n margin: 20px 0;\n}\n.article-view[_ngcontent-%COMP%] .article-body[_ngcontent-%COMP%] {\n font-size: 1.05rem;\n line-height: 1.7;\n color: var(--ion-text-color);\n white-space: pre-wrap;\n word-wrap: break-word;\n}\n.edit-form[_ngcontent-%COMP%] {\n padding: 16px;\n}\n@media (min-width: 768px) {\n .edit-form[_ngcontent-%COMP%] {\n max-width: 700px;\n margin: 0 auto;\n padding: 24px;\n }\n}\n.edit-form[_ngcontent-%COMP%] ion-list[_ngcontent-%COMP%] {\n background: transparent;\n padding: 0;\n}\n.edit-form[_ngcontent-%COMP%] ion-item[_ngcontent-%COMP%] {\n --background: var(--ion-card-background);\n --border-radius: 8px;\n margin-bottom: 12px;\n --padding-start: 16px;\n --padding-end: 16px;\n --inner-padding-end: 0;\n}\n.edit-form[_ngcontent-%COMP%] ion-input[_ngcontent-%COMP%], \n.edit-form[_ngcontent-%COMP%] ion-textarea[_ngcontent-%COMP%] {\n --padding-top: 12px;\n --padding-bottom: 12px;\n}\n.edit-form[_ngcontent-%COMP%] ion-toggle[_ngcontent-%COMP%] ion-label[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 500;\n margin: 0 0 4px;\n}\n.edit-form[_ngcontent-%COMP%] ion-toggle[_ngcontent-%COMP%] ion-label[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--ion-color-medium);\n margin: 0;\n}\n.edit-form[_ngcontent-%COMP%] .form-actions[_ngcontent-%COMP%] {\n margin-top: 24px;\n}\n.edit-form[_ngcontent-%COMP%] .form-actions[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n.edit-form[_ngcontent-%COMP%] .form-actions[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\nion-toolbar[_ngcontent-%COMP%] ion-button[_ngcontent-%COMP%] {\n --padding-start: 8px;\n --padding-end: 8px;\n}"] }); 615var NewsDetailPage = _NewsDetailPage; 616(() => { 617 (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NewsDetailPage, [{ 618 type: Component, 619 args: [{ selector: "app-news-detail", standalone: true, imports: [ 620 CommonModule, 621 FormsModule, 622 TranslateModule, 623 NgIcon, 624 IonHeader, 625 IonToolbar, 626 IonButtons, 627 IonBackButton, 628 IonTitle, 629 IonContent, 630 IonButton, 631 IonBadge, 632 IonSpinner, 633 IonInput, 634 IonTextarea,
635 IonToggle, 636 IonItem, 637 IonLabel, 638 IonList 639 ], viewProviders: [provideIcons({ 640 lucideCalendar, 641 lucideUser, 642 lucidePencil, 643 lucideTrash2, 644 lucideSave, 645 lucideX, 646 lucideImage, 647 lucideStar 648 })], template: `<ion-header> 649 <ion-toolbar> 650 <ion-buttons slot="start"> 651 <ion-back-button defaultHref="/news"></ion-back-button> 652 </ion-buttons> 653 <ion-title>{{ pageTitle }}</ion-title> 654 <ion-buttons slot="end"> 655 @if (!isEditMode && canEdit && news) { 656 <ion-button (click)="enterEditMode()"> 657 <ng-icon name="lucidePencil" size="1.2em"></ng-icon> 658 </ion-button> 659 } 660 @if (isEditMode) { 661 <ion-button (click)="saveNews()" [disabled]="saving"> 662 @if (saving) { 663 <ion-spinner name="crescent" size="small"></ion-spinner> 664 } @else { 665 <ng-icon name="lucideSave" size="1.2em"></ng-icon> 666 } 667 </ion-button> 668 } 669 </ion-buttons> 670 </ion-toolbar> 671</ion-header> 672 673<ion-content> 674 @if (loading) { 675 <div class="loading-container"> 676 <ion-spinner name="crescent"></ion-spinner> 677 </div> 678 } @else if (isEditMode) { 679 <!-- Edit Mode --> 680 <div class="edit-form"> 681 <ion-list> 682 <ion-item> 683 <ion-input 684 [(ngModel)]="formTitle" 685 [label]="'news.form.title' | translate" 686 labelPlacement="stacked" 687 [placeholder]="'news.form.titlePlaceholder' | translate" 688 type="text" 689 required> 690 </ion-input> 691 </ion-item> 692 693 <ion-item> 694 <ion-textarea 695 [(ngModel)]="formContent" 696 [label]="'news.form.content' | translate" 697 labelPlacement="stacked" 698 [placeholder]="'news.form.contentPlaceholder' | translate" 699 [autoGrow]="true" 700 [rows]="8" 701 required> 702 </ion-textarea> 703 </ion-item> 704 705 <ion-item> 706 <ion-toggle [(ngModel)]="formIsFeatured" labelPlacement="start"> 707 <ion-label> 708 <h2>{{ 'news.form.featured' | translate }}</h2> 709 <p>{{ 'news.form.featuredDescription' | translate }}</p> 710 </ion-label> 711 </ion-toggle> 712 </ion-item> 713 </ion-list> 714 715 <div class="form-actions"> 716 <ion-button expand="block" (click)="saveNews()" [disabled]="saving"> 717 @if (saving) { 718 {{ 'news.form.saving' | translate }} 719 } @else { 720 {{ 'news.form.save' | translate }} 721 } 722 </ion-button> 723 724 <ion-button expand="block" fill="outline" (click)="cancelEdit()"> 725 {{ 'news.form.cancel' | translate }} 726 </ion-button> 727 728 @if (!isNewArticle && canEdit) { 729 <ion-button expand="block" fill="clear" color="danger" (click)="confirmDelete()"> 730 <ng-icon name="lucideTrash2" size="1.1em" slot="start"></ng-icon> 731 {{ 'news.delete' | translate }} 732 </ion-button> 733 } 734 </div> 735 </div> 736 } @else if (news) { 737 <!-- View Mode --> 738 <div class="article-view"> 739 @if (imageUrl) { 740 <div class="article-image"> 741 <img [src]="imageUrl" [alt]="news.entity.title" /> 742 </div> 743 } 744 745 <div class="article-content"> 746 @if (news.entity.isFeatured) { 747 <ion-badge color="warning" class="featured-badge"> 748 <ng-icon name="lucideStar" size="0.9em"></ng-icon> 749 {{ 'news.featured' | translate }} 750 </ion-badge> 751 } 752 753 <h1 class="article-title">{{ news.entity.title }}</h1> 754 755 <div class="article-meta"> 756 <span class="meta-item"> 757 <ng-icon name="lucideCalendar" size="1em"></ng-icon> 758 {{ publishedDate | date:'longDate' }} 759 </span> 760 <span class="meta-item"> 761 <ng-icon name="lucideUser" size="1em"></ng-icon> 762 {{ 'news.by' | translate }} {{ authorName }} 763 </span> 764 </div> 765 766 <div class="article-divider"></div> 767 768 <div class="article-body"> 769 {{ news.entity.content }} 770 </div> 771 </div> 772 </div> 773 } 774</ion-content> 775`, styles: ["/* src/app/pages/news-detail/news-detail.page.scss */\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 50vh;\n}\n.article-view .article-image {\n width: 100%;\n max-height: 300px;\n overflow: hidden;\n}\n.article-view .article-image img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.article-view .article-content {\n padding: 20px;\n}\n@media (min-width: 768px) {\n .article-view .article-content {\n max-width: 800px;\n margin: 0 auto;\n padding: 24px 32px;\n }\n}\n.article-view .featured-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 12px;\n}\n.article-view .article-title {\n font-size: 1.75rem;\n font-weight: 700;\n line-height: 1.3;\n margin: 0 0 16px;\n color: var(--ion-text-color);\n}\n@media (min-width: 768px) {\n .article-view .article-title {\n font-size: 2rem;\n }\n}\n.article-view .article-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 16px;\n font-size: 0.9rem;\n color: var(--ion-color-medium);\n margin-bottom: 20px;\n}\n.article-view .article-meta .meta-item {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.article-view .article-divider {\n height: 1px;\n background: var(--ion-color-light);\n margin: 20px 0;\n}\n.article-view .article-body {\n font-size: 1.05rem;\n line-height: 1.7;\n color: var(--ion-text-color);\n white-space: pre-wrap;\n word-wrap: break-word;\n}\n.edit-form {\n padding: 16px;\n}\n@media (min-width: 768px) {\n .edit-form {\n max-width: 700px;\n margin: 0 auto;\n padding: 24px;\n }\n}\n.edit-form ion-list {\n background: transparent;\n padding: 0;\n}\n.edit-form ion-item {\n --background: var(--ion-card-background);\n --border-radius: 8px;\n margin-bottom: 12px;\n --padding-start: 16px;\n --padding-end: 16px;\n --inner-padding-end: 0;\n}\n.edit-form ion-input,\n.edit-form ion-textarea {\n --padding-top: 12px;\n --padding-bottom: 12px;\n}\n.edit-form ion-toggle ion-label h2 {\n font-size: 1rem;\n font-weight: 500;\n margin: 0 0 4px;\n}\n.edit-form ion-toggle ion-label p {\n font-size: 0.85rem;\n color: var(--ion-color-medium);\n margin: 0;\n}\n.edit-form .form-actions {\n margin-top: 24px;\n}\n.edit-form .form-actions ion-button {\n margin-bottom: 8px;\n}\n.edit-form .form-actions ion-button:last-child {\n margin-bottom: 0;\n}\nion-toolbar ion-button {\n --padding-start: 8px;\n --padding-end: 8px;\n}\n"] }] 776 }], () => [{ type: ActivatedRoute }, { type: Router }, { type: Location }, { type: DatabaseService }, { type: AuthService }, { type: ApiUrlService }, { type: AlertController }, { type: ToastController }, { type: TranslateService }], null); 777})(); 778(() => { 779 (typeof ngDevMode === "undefined" || ngDevMode) && \u0275setClassDebugInfo(NewsDetailPage, { className: "NewsDetailPage", filePath: "src/app/pages/news-detail/news-detail.page.ts", lineNumber: 58 }); 780})(); 781export { 782 NewsDetailPage 783};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.