cloud-ide-fees 0.0.30 → 0.0.33

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.
@@ -0,0 +1,418 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, output, computed, effect, Component } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import * as i1 from '@angular/forms';
5
+ import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
6
+ import { CideInputComponent, CideSelectComponent, CideTextareaComponent, CideEleButtonComponent, CurrencyPipe } from 'cloud-ide-element';
7
+
8
+ class FeeScholarshipFormComponent {
9
+ // Inputs
10
+ feeId = input.required(...(ngDevMode ? [{ debugName: "feeId" }] : []));
11
+ feeName = input.required(...(ngDevMode ? [{ debugName: "feeName" }] : []));
12
+ feeAmount = input.required(...(ngDevMode ? [{ debugName: "feeAmount" }] : []));
13
+ existingScholarship = input(null, ...(ngDevMode ? [{ debugName: "existingScholarship" }] : []));
14
+ scholarshipTypeOptions = input.required(...(ngDevMode ? [{ debugName: "scholarshipTypeOptions" }] : []));
15
+ // Outputs
16
+ saved = output();
17
+ cancelled = output();
18
+ // Form using signals (modern Angular approach)
19
+ scholarshipForm = new FormGroup({
20
+ scholarship_type_id: new FormControl(''),
21
+ scholarship_category: new FormControl('PARTIAL', [Validators.required]),
22
+ scholarship_percentage: new FormControl(null, [Validators.min(0), Validators.max(100)]),
23
+ scholarship_amount: new FormControl(0, [Validators.min(0)]),
24
+ valid_from: new FormControl(''),
25
+ valid_to: new FormControl(''),
26
+ notes: new FormControl('')
27
+ });
28
+ // Computed values
29
+ calculatedScholarshipAmount = computed(() => {
30
+ const category = this.scholarshipForm.get('scholarship_category')?.value;
31
+ const percentage = this.scholarshipForm.get('scholarship_percentage')?.value;
32
+ const amount = this.scholarshipForm.get('scholarship_amount')?.value || 0;
33
+ if (category === 'FULL') {
34
+ return this.feeAmount();
35
+ }
36
+ else if (category === 'PARTIAL') {
37
+ if (percentage && percentage > 0) {
38
+ return (this.feeAmount() * percentage) / 100;
39
+ }
40
+ else if (amount > 0) {
41
+ return Math.min(amount, this.feeAmount());
42
+ }
43
+ }
44
+ return 0;
45
+ }, ...(ngDevMode ? [{ debugName: "calculatedScholarshipAmount" }] : []));
46
+ constructor() {
47
+ // Initialize form with existing scholarship data
48
+ effect(() => {
49
+ const existing = this.existingScholarship();
50
+ if (existing) {
51
+ this.scholarshipForm.patchValue({
52
+ scholarship_type_id: existing.scholarship_type_id || '',
53
+ scholarship_category: existing.scholarship_category,
54
+ scholarship_percentage: existing.scholarship_percentage || null,
55
+ scholarship_amount: existing.scholarship_amount || 0,
56
+ valid_from: this.formatDateForInput(existing.valid_from),
57
+ valid_to: this.formatDateForInput(existing.valid_to),
58
+ notes: existing.notes || ''
59
+ }, { emitEvent: false });
60
+ }
61
+ });
62
+ // Update validators when category changes
63
+ effect(() => {
64
+ const category = this.scholarshipForm.get('scholarship_category')?.value;
65
+ const percentageControl = this.scholarshipForm.get('scholarship_percentage');
66
+ const amountControl = this.scholarshipForm.get('scholarship_amount');
67
+ if (category === 'PARTIAL') {
68
+ // At least one of percentage or amount should be provided
69
+ percentageControl?.setValidators([Validators.min(0), Validators.max(100)]);
70
+ amountControl?.setValidators([Validators.min(0), Validators.max(this.feeAmount())]);
71
+ }
72
+ else {
73
+ percentageControl?.clearValidators();
74
+ amountControl?.clearValidators();
75
+ }
76
+ percentageControl?.updateValueAndValidity();
77
+ amountControl?.updateValueAndValidity();
78
+ });
79
+ }
80
+ onSave() {
81
+ if (!this.scholarshipForm.valid)
82
+ return;
83
+ const formValue = this.scholarshipForm.value;
84
+ const category = formValue.scholarship_category;
85
+ const scholarshipData = {
86
+ scholarship_type_id: formValue.scholarship_type_id || undefined,
87
+ scholarship_type_title: this.getScholarshipTypeTitle(formValue.scholarship_type_id || ''),
88
+ scholarship_category: category,
89
+ scholarship_percentage: category === 'PARTIAL' ? (formValue.scholarship_percentage || undefined) : undefined,
90
+ scholarship_amount: category === 'FULL'
91
+ ? this.feeAmount()
92
+ : (category === 'PARTIAL' ? (formValue.scholarship_amount || 0) : 0),
93
+ valid_from: formValue.valid_from ? new Date(formValue.valid_from) : undefined,
94
+ valid_to: formValue.valid_to ? new Date(formValue.valid_to) : undefined,
95
+ notes: formValue.notes || undefined
96
+ };
97
+ this.saved.emit(scholarshipData);
98
+ }
99
+ onCancel() {
100
+ this.cancelled.emit();
101
+ }
102
+ formatDateForInput(date) {
103
+ if (!date)
104
+ return '';
105
+ const d = new Date(date);
106
+ return d.toISOString().split('T')[0];
107
+ }
108
+ getScholarshipTypeTitle(typeId) {
109
+ if (!typeId)
110
+ return undefined;
111
+ const type = this.scholarshipTypeOptions().find(t => t.value === typeId);
112
+ return type?.label;
113
+ }
114
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeeScholarshipFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
115
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: FeeScholarshipFormComponent, isStandalone: true, selector: "cide-fee-scholarship-form", inputs: { feeId: { classPropertyName: "feeId", publicName: "feeId", isSignal: true, isRequired: true, transformFunction: null }, feeName: { classPropertyName: "feeName", publicName: "feeName", isSignal: true, isRequired: true, transformFunction: null }, feeAmount: { classPropertyName: "feeAmount", publicName: "feeAmount", isSignal: true, isRequired: true, transformFunction: null }, existingScholarship: { classPropertyName: "existingScholarship", publicName: "existingScholarship", isSignal: true, isRequired: false, transformFunction: null }, scholarshipTypeOptions: { classPropertyName: "scholarshipTypeOptions", publicName: "scholarshipTypeOptions", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, ngImport: i0, template: `
116
+ <div class="tw-p-4 tw-space-y-4">
117
+ <div class="tw-mb-4">
118
+ <h3 class="tw-text-lg tw-font-semibold tw-text-gray-900">
119
+ {{ existingScholarship() ? 'Edit Scholarship' : 'Add Scholarship' }}
120
+ </h3>
121
+ <p class="tw-text-sm tw-text-gray-600 tw-mt-1">{{ feeName() }}</p>
122
+ </div>
123
+
124
+ <form [formGroup]="scholarshipForm" class="tw-space-y-4">
125
+ <!-- Scholarship Type -->
126
+ <div>
127
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
128
+ Scholarship Type
129
+ </label>
130
+ <cide-ele-select
131
+ formControlName="scholarship_type_id"
132
+ [options]="scholarshipTypeOptions()"
133
+ placeholder="Select type"
134
+ size="sm">
135
+ </cide-ele-select>
136
+ </div>
137
+
138
+ <!-- Scholarship Category -->
139
+ <div>
140
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
141
+ Scholarship Category *
142
+ </label>
143
+ <cide-ele-select
144
+ formControlName="scholarship_category"
145
+ [options]="[{value: 'FULL', label: 'Full Scholarship'}, {value: 'PARTIAL', label: 'Partial Scholarship'}]"
146
+ size="sm">
147
+ </cide-ele-select>
148
+ </div>
149
+
150
+ <!-- Percentage or Amount (for PARTIAL) -->
151
+ @if (scholarshipForm.get('scholarship_category')?.value === 'PARTIAL') {
152
+ <div>
153
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
154
+ Percentage or Amount
155
+ </label>
156
+ <div class="tw-flex tw-gap-2 tw-items-center">
157
+ <cide-ele-input
158
+ type="number"
159
+ formControlName="scholarship_percentage"
160
+ placeholder="Percentage"
161
+ [min]="0"
162
+ [max]="100"
163
+ size="sm"
164
+ class="tw-flex-1">
165
+ </cide-ele-input>
166
+ <span class="tw-text-gray-500 tw-text-sm">OR</span>
167
+ <cide-ele-input
168
+ type="number"
169
+ formControlName="scholarship_amount"
170
+ placeholder="Amount"
171
+ [min]="0"
172
+ [max]="feeAmount()"
173
+ size="sm"
174
+ class="tw-flex-1">
175
+ </cide-ele-input>
176
+ </div>
177
+ </div>
178
+ } @else {
179
+ <div class="tw-p-3 tw-bg-gray-50 tw-rounded tw-border tw-border-gray-200">
180
+ <p class="tw-text-xs tw-text-gray-600">
181
+ Full scholarship covers 100% of fees
182
+ </p>
183
+ </div>
184
+ }
185
+
186
+ <!-- Valid From / Valid To -->
187
+ <div class="tw-grid tw-grid-cols-2 tw-gap-4">
188
+ <div>
189
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
190
+ Valid From
191
+ </label>
192
+ <cide-ele-input
193
+ type="date"
194
+ formControlName="valid_from"
195
+ size="sm">
196
+ </cide-ele-input>
197
+ </div>
198
+ <div>
199
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
200
+ Valid To
201
+ </label>
202
+ <cide-ele-input
203
+ type="date"
204
+ formControlName="valid_to"
205
+ size="sm">
206
+ </cide-ele-input>
207
+ </div>
208
+ </div>
209
+
210
+ <!-- Notes -->
211
+ <div>
212
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
213
+ Notes
214
+ </label>
215
+ <cide-ele-textarea
216
+ formControlName="notes"
217
+ rows="2"
218
+ size="sm">
219
+ </cide-ele-textarea>
220
+ </div>
221
+
222
+ <!-- Calculated Scholarship Amount Preview -->
223
+ @if (calculatedScholarshipAmount() > 0) {
224
+ <div class="tw-p-3 tw-bg-purple-50 tw-rounded tw-border tw-border-purple-200">
225
+ <p class="tw-text-sm tw-text-gray-700">
226
+ <span class="tw-font-medium">Scholarship Amount:</span>
227
+ <span class="tw-ml-2 tw-font-semibold tw-text-purple-600">
228
+ {{ calculatedScholarshipAmount() | currency }}
229
+ </span>
230
+ </p>
231
+ </div>
232
+ }
233
+ </form>
234
+
235
+ <!-- Actions -->
236
+ <div class="tw-flex tw-justify-end tw-gap-2 tw-pt-4 tw-border-t tw-border-gray-200">
237
+ <button
238
+ type="button"
239
+ cideEleButton
240
+ variant="ghost"
241
+ size="sm"
242
+ (click)="onCancel()">
243
+ Cancel
244
+ </button>
245
+ <button
246
+ type="button"
247
+ cideEleButton
248
+ variant="primary"
249
+ size="sm"
250
+ [disabled]="!scholarshipForm.valid"
251
+ (click)="onSave()">
252
+ {{ existingScholarship() ? 'Update Scholarship' : 'Save Scholarship' }}
253
+ </button>
254
+ </div>
255
+ </div>
256
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "step", "size"], outputs: ["ngModelChange"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading", "valueKey", "labelKey", "treeView"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideTextareaComponent, selector: "cide-ele-textarea", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "minlength", "maxlength", "rows", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput"], outputs: ["ngModelChange"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "pipe", type: CurrencyPipe, name: "currency" }] });
257
+ }
258
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeeScholarshipFormComponent, decorators: [{
259
+ type: Component,
260
+ args: [{
261
+ selector: 'cide-fee-scholarship-form',
262
+ standalone: true,
263
+ imports: [
264
+ CommonModule,
265
+ ReactiveFormsModule,
266
+ CideInputComponent,
267
+ CideSelectComponent,
268
+ CideTextareaComponent,
269
+ CideEleButtonComponent,
270
+ CurrencyPipe
271
+ ],
272
+ template: `
273
+ <div class="tw-p-4 tw-space-y-4">
274
+ <div class="tw-mb-4">
275
+ <h3 class="tw-text-lg tw-font-semibold tw-text-gray-900">
276
+ {{ existingScholarship() ? 'Edit Scholarship' : 'Add Scholarship' }}
277
+ </h3>
278
+ <p class="tw-text-sm tw-text-gray-600 tw-mt-1">{{ feeName() }}</p>
279
+ </div>
280
+
281
+ <form [formGroup]="scholarshipForm" class="tw-space-y-4">
282
+ <!-- Scholarship Type -->
283
+ <div>
284
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
285
+ Scholarship Type
286
+ </label>
287
+ <cide-ele-select
288
+ formControlName="scholarship_type_id"
289
+ [options]="scholarshipTypeOptions()"
290
+ placeholder="Select type"
291
+ size="sm">
292
+ </cide-ele-select>
293
+ </div>
294
+
295
+ <!-- Scholarship Category -->
296
+ <div>
297
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
298
+ Scholarship Category *
299
+ </label>
300
+ <cide-ele-select
301
+ formControlName="scholarship_category"
302
+ [options]="[{value: 'FULL', label: 'Full Scholarship'}, {value: 'PARTIAL', label: 'Partial Scholarship'}]"
303
+ size="sm">
304
+ </cide-ele-select>
305
+ </div>
306
+
307
+ <!-- Percentage or Amount (for PARTIAL) -->
308
+ @if (scholarshipForm.get('scholarship_category')?.value === 'PARTIAL') {
309
+ <div>
310
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
311
+ Percentage or Amount
312
+ </label>
313
+ <div class="tw-flex tw-gap-2 tw-items-center">
314
+ <cide-ele-input
315
+ type="number"
316
+ formControlName="scholarship_percentage"
317
+ placeholder="Percentage"
318
+ [min]="0"
319
+ [max]="100"
320
+ size="sm"
321
+ class="tw-flex-1">
322
+ </cide-ele-input>
323
+ <span class="tw-text-gray-500 tw-text-sm">OR</span>
324
+ <cide-ele-input
325
+ type="number"
326
+ formControlName="scholarship_amount"
327
+ placeholder="Amount"
328
+ [min]="0"
329
+ [max]="feeAmount()"
330
+ size="sm"
331
+ class="tw-flex-1">
332
+ </cide-ele-input>
333
+ </div>
334
+ </div>
335
+ } @else {
336
+ <div class="tw-p-3 tw-bg-gray-50 tw-rounded tw-border tw-border-gray-200">
337
+ <p class="tw-text-xs tw-text-gray-600">
338
+ Full scholarship covers 100% of fees
339
+ </p>
340
+ </div>
341
+ }
342
+
343
+ <!-- Valid From / Valid To -->
344
+ <div class="tw-grid tw-grid-cols-2 tw-gap-4">
345
+ <div>
346
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
347
+ Valid From
348
+ </label>
349
+ <cide-ele-input
350
+ type="date"
351
+ formControlName="valid_from"
352
+ size="sm">
353
+ </cide-ele-input>
354
+ </div>
355
+ <div>
356
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
357
+ Valid To
358
+ </label>
359
+ <cide-ele-input
360
+ type="date"
361
+ formControlName="valid_to"
362
+ size="sm">
363
+ </cide-ele-input>
364
+ </div>
365
+ </div>
366
+
367
+ <!-- Notes -->
368
+ <div>
369
+ <label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
370
+ Notes
371
+ </label>
372
+ <cide-ele-textarea
373
+ formControlName="notes"
374
+ rows="2"
375
+ size="sm">
376
+ </cide-ele-textarea>
377
+ </div>
378
+
379
+ <!-- Calculated Scholarship Amount Preview -->
380
+ @if (calculatedScholarshipAmount() > 0) {
381
+ <div class="tw-p-3 tw-bg-purple-50 tw-rounded tw-border tw-border-purple-200">
382
+ <p class="tw-text-sm tw-text-gray-700">
383
+ <span class="tw-font-medium">Scholarship Amount:</span>
384
+ <span class="tw-ml-2 tw-font-semibold tw-text-purple-600">
385
+ {{ calculatedScholarshipAmount() | currency }}
386
+ </span>
387
+ </p>
388
+ </div>
389
+ }
390
+ </form>
391
+
392
+ <!-- Actions -->
393
+ <div class="tw-flex tw-justify-end tw-gap-2 tw-pt-4 tw-border-t tw-border-gray-200">
394
+ <button
395
+ type="button"
396
+ cideEleButton
397
+ variant="ghost"
398
+ size="sm"
399
+ (click)="onCancel()">
400
+ Cancel
401
+ </button>
402
+ <button
403
+ type="button"
404
+ cideEleButton
405
+ variant="primary"
406
+ size="sm"
407
+ [disabled]="!scholarshipForm.valid"
408
+ (click)="onSave()">
409
+ {{ existingScholarship() ? 'Update Scholarship' : 'Save Scholarship' }}
410
+ </button>
411
+ </div>
412
+ </div>
413
+ `
414
+ }]
415
+ }], ctorParameters: () => [], propDecorators: { feeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "feeId", required: true }] }], feeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "feeName", required: true }] }], feeAmount: [{ type: i0.Input, args: [{ isSignal: true, alias: "feeAmount", required: true }] }], existingScholarship: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingScholarship", required: false }] }], scholarshipTypeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "scholarshipTypeOptions", required: true }] }], saved: [{ type: i0.Output, args: ["saved"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
416
+
417
+ export { FeeScholarshipFormComponent };
418
+ //# sourceMappingURL=cloud-ide-fees-fee-scholarship-form.component-C2eJrtQT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-ide-fees-fee-scholarship-form.component-C2eJrtQT.mjs","sources":["../../../projects/cloud-ide-fees/src/lib/shared/components/fee-scholarship-form/fee-scholarship-form.component.ts"],"sourcesContent":["\r\nimport { Component, inject, signal, computed, input, output, effect } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\r\nimport { CideInputComponent, CideSelectComponent, CideTextareaComponent, CideEleButtonComponent, CurrencyPipe } from 'cloud-ide-element';\r\n\r\nexport interface FeeScholarshipFormData {\r\n scholarship_type_id?: string;\r\n scholarship_type_title?: string;\r\n scholarship_category: 'FULL' | 'PARTIAL';\r\n scholarship_percentage?: number;\r\n scholarship_amount: number;\r\n valid_from?: Date;\r\n valid_to?: Date;\r\n notes?: string;\r\n}\r\n\r\nexport interface FeeScholarshipFormInputs {\r\n feeId: string;\r\n feeName: string;\r\n feeAmount: number;\r\n existingScholarship?: FeeScholarshipFormData | null;\r\n scholarshipTypeOptions: Array<{ value: string; label: string }>;\r\n}\r\n\r\n@Component({\r\n selector: 'cide-fee-scholarship-form',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n ReactiveFormsModule,\r\n CideInputComponent,\r\n CideSelectComponent,\r\n CideTextareaComponent,\r\n CideEleButtonComponent,\r\n CurrencyPipe\r\n ],\r\n template: `\r\n <div class=\"tw-p-4 tw-space-y-4\">\r\n <div class=\"tw-mb-4\">\r\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-gray-900\">\r\n {{ existingScholarship() ? 'Edit Scholarship' : 'Add Scholarship' }}\r\n </h3>\r\n <p class=\"tw-text-sm tw-text-gray-600 tw-mt-1\">{{ feeName() }}</p>\r\n </div>\r\n\r\n <form [formGroup]=\"scholarshipForm\" class=\"tw-space-y-4\">\r\n <!-- Scholarship Type -->\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Scholarship Type\r\n </label>\r\n <cide-ele-select\r\n formControlName=\"scholarship_type_id\"\r\n [options]=\"scholarshipTypeOptions()\"\r\n placeholder=\"Select type\"\r\n size=\"sm\">\r\n </cide-ele-select>\r\n </div>\r\n\r\n <!-- Scholarship Category -->\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Scholarship Category *\r\n </label>\r\n <cide-ele-select\r\n formControlName=\"scholarship_category\"\r\n [options]=\"[{value: 'FULL', label: 'Full Scholarship'}, {value: 'PARTIAL', label: 'Partial Scholarship'}]\"\r\n size=\"sm\">\r\n </cide-ele-select>\r\n </div>\r\n\r\n <!-- Percentage or Amount (for PARTIAL) -->\r\n @if (scholarshipForm.get('scholarship_category')?.value === 'PARTIAL') {\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Percentage or Amount\r\n </label>\r\n <div class=\"tw-flex tw-gap-2 tw-items-center\">\r\n <cide-ele-input\r\n type=\"number\"\r\n formControlName=\"scholarship_percentage\"\r\n placeholder=\"Percentage\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n size=\"sm\"\r\n class=\"tw-flex-1\">\r\n </cide-ele-input>\r\n <span class=\"tw-text-gray-500 tw-text-sm\">OR</span>\r\n <cide-ele-input\r\n type=\"number\"\r\n formControlName=\"scholarship_amount\"\r\n placeholder=\"Amount\"\r\n [min]=\"0\"\r\n [max]=\"feeAmount()\"\r\n size=\"sm\"\r\n class=\"tw-flex-1\">\r\n </cide-ele-input>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"tw-p-3 tw-bg-gray-50 tw-rounded tw-border tw-border-gray-200\">\r\n <p class=\"tw-text-xs tw-text-gray-600\">\r\n Full scholarship covers 100% of fees\r\n </p>\r\n </div>\r\n }\r\n\r\n <!-- Valid From / Valid To -->\r\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-4\">\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Valid From\r\n </label>\r\n <cide-ele-input\r\n type=\"date\"\r\n formControlName=\"valid_from\"\r\n size=\"sm\">\r\n </cide-ele-input>\r\n </div>\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Valid To\r\n </label>\r\n <cide-ele-input\r\n type=\"date\"\r\n formControlName=\"valid_to\"\r\n size=\"sm\">\r\n </cide-ele-input>\r\n </div>\r\n </div>\r\n\r\n <!-- Notes -->\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Notes\r\n </label>\r\n <cide-ele-textarea\r\n formControlName=\"notes\"\r\n rows=\"2\"\r\n size=\"sm\">\r\n </cide-ele-textarea>\r\n </div>\r\n\r\n <!-- Calculated Scholarship Amount Preview -->\r\n @if (calculatedScholarshipAmount() > 0) {\r\n <div class=\"tw-p-3 tw-bg-purple-50 tw-rounded tw-border tw-border-purple-200\">\r\n <p class=\"tw-text-sm tw-text-gray-700\">\r\n <span class=\"tw-font-medium\">Scholarship Amount:</span>\r\n <span class=\"tw-ml-2 tw-font-semibold tw-text-purple-600\">\r\n {{ calculatedScholarshipAmount() | currency }}\r\n </span>\r\n </p>\r\n </div>\r\n }\r\n </form>\r\n\r\n <!-- Actions -->\r\n <div class=\"tw-flex tw-justify-end tw-gap-2 tw-pt-4 tw-border-t tw-border-gray-200\">\r\n <button\r\n type=\"button\"\r\n cideEleButton\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n (click)=\"onCancel()\">\r\n Cancel\r\n </button>\r\n <button\r\n type=\"button\"\r\n cideEleButton\r\n variant=\"primary\"\r\n size=\"sm\"\r\n [disabled]=\"!scholarshipForm.valid\"\r\n (click)=\"onSave()\">\r\n {{ existingScholarship() ? 'Update Scholarship' : 'Save Scholarship' }}\r\n </button>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class FeeScholarshipFormComponent {\r\n // Inputs\r\n readonly feeId = input.required<string>();\r\n readonly feeName = input.required<string>();\r\n readonly feeAmount = input.required<number>();\r\n readonly existingScholarship = input<FeeScholarshipFormData | null>(null);\r\n readonly scholarshipTypeOptions = input.required<Array<{ value: string; label: string }>>();\r\n\r\n // Outputs\r\n readonly saved = output<FeeScholarshipFormData>();\r\n readonly cancelled = output<void>();\r\n\r\n // Form using signals (modern Angular approach)\r\n scholarshipForm = new FormGroup({\r\n scholarship_type_id: new FormControl<string>(''),\r\n scholarship_category: new FormControl<'FULL' | 'PARTIAL'>('PARTIAL', [Validators.required]),\r\n scholarship_percentage: new FormControl<number | null>(null, [Validators.min(0), Validators.max(100)]),\r\n scholarship_amount: new FormControl<number>(0, [Validators.min(0)]),\r\n valid_from: new FormControl<string>(''),\r\n valid_to: new FormControl<string>(''),\r\n notes: new FormControl<string>('')\r\n });\r\n\r\n // Computed values\r\n readonly calculatedScholarshipAmount = computed(() => {\r\n const category = this.scholarshipForm.get('scholarship_category')?.value;\r\n const percentage = this.scholarshipForm.get('scholarship_percentage')?.value;\r\n const amount = this.scholarshipForm.get('scholarship_amount')?.value || 0;\r\n\r\n if (category === 'FULL') {\r\n return this.feeAmount();\r\n } else if (category === 'PARTIAL') {\r\n if (percentage && percentage > 0) {\r\n return (this.feeAmount() * percentage) / 100;\r\n } else if (amount > 0) {\r\n return Math.min(amount, this.feeAmount());\r\n }\r\n }\r\n return 0;\r\n });\r\n\r\n constructor() {\r\n // Initialize form with existing scholarship data\r\n effect(() => {\r\n const existing = this.existingScholarship();\r\n if (existing) {\r\n this.scholarshipForm.patchValue({\r\n scholarship_type_id: existing.scholarship_type_id || '',\r\n scholarship_category: existing.scholarship_category,\r\n scholarship_percentage: existing.scholarship_percentage || null,\r\n scholarship_amount: existing.scholarship_amount || 0,\r\n valid_from: this.formatDateForInput(existing.valid_from),\r\n valid_to: this.formatDateForInput(existing.valid_to),\r\n notes: existing.notes || ''\r\n }, { emitEvent: false });\r\n }\r\n });\r\n\r\n // Update validators when category changes\r\n effect(() => {\r\n const category = this.scholarshipForm.get('scholarship_category')?.value;\r\n const percentageControl = this.scholarshipForm.get('scholarship_percentage');\r\n const amountControl = this.scholarshipForm.get('scholarship_amount');\r\n\r\n if (category === 'PARTIAL') {\r\n // At least one of percentage or amount should be provided\r\n percentageControl?.setValidators([Validators.min(0), Validators.max(100)]);\r\n amountControl?.setValidators([Validators.min(0), Validators.max(this.feeAmount())]);\r\n } else {\r\n percentageControl?.clearValidators();\r\n amountControl?.clearValidators();\r\n }\r\n percentageControl?.updateValueAndValidity();\r\n amountControl?.updateValueAndValidity();\r\n });\r\n }\r\n\r\n onSave(): void {\r\n if (!this.scholarshipForm.valid) return;\r\n\r\n const formValue = this.scholarshipForm.value;\r\n const category = formValue.scholarship_category!;\r\n\r\n const scholarshipData: FeeScholarshipFormData = {\r\n scholarship_type_id: formValue.scholarship_type_id || undefined,\r\n scholarship_type_title: this.getScholarshipTypeTitle(formValue.scholarship_type_id || ''),\r\n scholarship_category: category,\r\n scholarship_percentage: category === 'PARTIAL' ? (formValue.scholarship_percentage || undefined) : undefined,\r\n scholarship_amount: category === 'FULL'\r\n ? this.feeAmount()\r\n : (category === 'PARTIAL' ? (formValue.scholarship_amount || 0) : 0),\r\n valid_from: formValue.valid_from ? new Date(formValue.valid_from) : undefined,\r\n valid_to: formValue.valid_to ? new Date(formValue.valid_to) : undefined,\r\n notes: formValue.notes || undefined\r\n };\r\n\r\n this.saved.emit(scholarshipData);\r\n }\r\n\r\n onCancel(): void {\r\n this.cancelled.emit();\r\n }\r\n\r\n private formatDateForInput(date?: Date): string {\r\n if (!date) return '';\r\n const d = new Date(date);\r\n return d.toISOString().split('T')[0];\r\n }\r\n\r\n private getScholarshipTypeTitle(typeId: string): string | undefined {\r\n if (!typeId) return undefined;\r\n const type = this.scholarshipTypeOptions().find(t => t.value === typeId);\r\n return type?.label;\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}