Commit 0cb692ee authored by hasan khaddour's avatar hasan khaddour

add scroll top

parent ad1fd4fc
<loading-spinner hidden></loading-spinner> <loading-spinner hidden></loading-spinner>
<router-outlet /> <router-outlet />
...@@ -32,6 +32,8 @@ import { ProjectFAQComponent } from './pages/project-faq/project-faq.component'; ...@@ -32,6 +32,8 @@ import { ProjectFAQComponent } from './pages/project-faq/project-faq.component';
import { PsmStartComponent } from './pages/psm-start/psm-start.component'; import { PsmStartComponent } from './pages/psm-start/psm-start.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { AccessDeniedComponent } from './pages/access-denied/access-denied.component'; import { AccessDeniedComponent } from './pages/access-denied/access-denied.component';
import { ScrollTopModule } from 'primeng/scrolltop';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -54,6 +56,7 @@ import { AccessDeniedComponent } from './pages/access-denied/access-denied.compo ...@@ -54,6 +56,7 @@ import { AccessDeniedComponent } from './pages/access-denied/access-denied.compo
CoreModule, CoreModule,
CustomersModule, CustomersModule,
SharedModule, SharedModule,
ScrollTopModule,
NgxPaginationModule, NgxPaginationModule,
BrowserAnimationsModule, // Required for toast animations BrowserAnimationsModule, // Required for toast animations
ToastrModule.forRoot({ ToastrModule.forRoot({
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
/> />
</div> </div>
<div class="mb-3 col-8 offset-1"> <div class="mb-3 col-7 ">
<label for="attachmentDescription" class="form-label">الوصف</label> <label for="attachmentDescription" class="form-label">الوصف</label>
<textarea <textarea
[cols]="4" [cols]="4"
...@@ -37,7 +37,28 @@ ...@@ -37,7 +37,28 @@
[(ngModel)]="item.file" required /> [(ngModel)]="item.file" required />
</div> </div>
<p-fileUpload
class="col-10 offset-1"
[customUpload]="true"
(uploadHandler)="onFileSelected($event)"
[multiple]="false"
maxFileSize="1000000"
chooseLabel=" اختر ملف "
uploadLabel=" تحميل "
cancelLabel=" إلغاء "
>
<ng-template pTemplate="content">
<ul *ngIf="uploadedFiles.length">
<li *ngFor="let file of uploadedFiles">
{{ file.name }} - {{ file.size }} bytes
</li>
</ul>
</ng-template>
</p-fileUpload>
</div> </div>
<div class="row"> <div class="row">
<button <button
[disabled]="form.invalid" [disabled]="form.invalid"
......
...@@ -13,6 +13,8 @@ import { ProjectService } from '../../../services/project.service'; ...@@ -13,6 +13,8 @@ import { ProjectService } from '../../../services/project.service';
}) })
export class AddAttachmentModalComponent { export class AddAttachmentModalComponent {
@Input() projectId :number @Input() projectId :number
uploadedFiles: any[] = [];
totalSize=0
@Output() itemAdded= new EventEmitter<void>(); @Output() itemAdded= new EventEmitter<void>();
item : AddAttachmentRequest item : AddAttachmentRequest
...@@ -53,11 +55,41 @@ export class AddAttachmentModalComponent { ...@@ -53,11 +55,41 @@ export class AddAttachmentModalComponent {
}) })
} }
onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement; // Method to handle file selection
if (input.files?.length) { onFileSelected(event: any): void {
this.selectedFile = input.files[0]; const files = event.files;
this.totalSize = files.reduce((acc: number, file: File) => acc + file.size, 0);
if (files.length > 0) {
this.selectedFile = files[0]; // Set the selected file
}
}
// Method to handle file upload
onTemplatedUpload(event: { files: File[] }): void {
if (!this.selectedFile) {
return;
}
}
choose(event: any, chooseCallback: Function): void {
chooseCallback();
}
uploadEvent(uploadCallback: Function): void {
uploadCallback();
}
onRemoveTemplatingFile(event: any, file: any, removeFileCallback: Function, index: number): void {
removeFileCallback(index);
} }
// File size formatting helper
formatSize(bytes: number): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
} }
onClose():void { onClose():void {
this.activeModal.close(); this.activeModal.close();
......
...@@ -98,3 +98,7 @@ ...@@ -98,3 +98,7 @@
</div> </div>
</div> </div>
</div> </div>
<card-skeleton *ngif="!spends">
</card-skeleton>
\ No newline at end of file
...@@ -120,4 +120,6 @@ ...@@ -120,4 +120,6 @@
</div> </div>
<card-skeleton *ngIf="!project" class="col-10">
</card-skeleton>
\ No newline at end of file
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { FileUploadModule } from 'primeng/fileupload';
import { TimelineModule } from 'primeng/timeline'; import { TimelineModule } from 'primeng/timeline';
import { ProjectItemComponent } from './components/project-item/project-item.component'; import { ProjectItemComponent } from './components/project-item/project-item.component';
import { ProjectListComponent } from './pages/project-list/project-list.component'; import { ProjectListComponent } from './pages/project-list/project-list.component';
...@@ -54,6 +55,9 @@ import { EditFinancialModalComponent } from './components/edit-financial-modal/e ...@@ -54,6 +55,9 @@ import { EditFinancialModalComponent } from './components/edit-financial-modal/e
import { RemoveFinancialModalComponent } from './components/remove-financial-modal/remove-financial-modal.component'; import { RemoveFinancialModalComponent } from './components/remove-financial-modal/remove-financial-modal.component';
import { CardModule } from 'primeng/card'; import { CardModule } from 'primeng/card';
import { ButtonModule } from 'primeng/button'; import { ButtonModule } from 'primeng/button';
import { BadgeModule } from 'primeng/badge';
import { ProgressBarModule } from 'primeng/progressbar'; import { ProgressBarModule } from 'primeng/progressbar';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -122,6 +126,8 @@ import { ProgressBarModule } from 'primeng/progressbar'; ...@@ -122,6 +126,8 @@ import { ProgressBarModule } from 'primeng/progressbar';
ReactiveFormsModule , ReactiveFormsModule ,
SharedModule, SharedModule,
SkeletonModule, SkeletonModule,
FileUploadModule,
BadgeModule,
NgbTypeaheadModule NgbTypeaheadModule
] ]
}) })
......
<div class="card shadow mb-4 col-8 offset-2" *ngIf="!steps"> <div class="card shadow mb-4 col-8 offset-2">
<div class="card-header py-3"> <div class="card-header py-3">
<div class="row align-items-center"> <div class="row align-items-center">
<div class="col-auto"> <div class="col-auto">
......
...@@ -35,7 +35,8 @@ import { SkeletonModule } from 'primeng/skeleton'; ...@@ -35,7 +35,8 @@ import { SkeletonModule } from 'primeng/skeleton';
], ],
imports: [ imports: [
CommonModule, CommonModule,
RouterModule RouterModule ,
SkeletonModule
], ],
exports:[ exports:[
HeaderComponent, HeaderComponent,
...@@ -45,7 +46,7 @@ import { SkeletonModule } from 'primeng/skeleton'; ...@@ -45,7 +46,7 @@ import { SkeletonModule } from 'primeng/skeleton';
FullnamePipe, FullnamePipe,
StateTranslatePipe, StateTranslatePipe,
CardItemComponent, CardItemComponent,
SkeletonModule, CardSkeletonComponent,
ProgressBarModule, ProgressBarModule,
LoadingSpinnerComponent LoadingSpinnerComponent
],schemas: [CUSTOM_ELEMENTS_SCHEMA] ],schemas: [CUSTOM_ELEMENTS_SCHEMA]
......
...@@ -8,11 +8,19 @@ ...@@ -8,11 +8,19 @@
.nav-link, .navbar-brand { .nav-link, .navbar-brand {
color: #fff!important; color: #fff!important;
} }
.custom-scrolltop {
z-index: 1000; /* Ensure it's above other components */
}
/*-------------------------------------------------------------- /*--------------------------------------------------------------
# Main # Main
--------------------------------------------------------------*/ --------------------------------------------------------------*/
#main { #main {
margin-top: 60px; margin-top: 60px;
overflow-y: auto;
padding: 20px 30px; padding: 20px 30px;
transition: all 0.3s; transition: all 0.3s;
} }
......
...@@ -8,5 +8,6 @@ ...@@ -8,5 +8,6 @@
</div> </div>
<app-sidebar [isToggled]="isToggled"></app-sidebar> <app-sidebar [isToggled]="isToggled"></app-sidebar>
<app-footer [class.maine]="isToggled"></app-footer> <app-footer [class.maine]="isToggled"></app-footer>
<p-scrollTop target="main" styleClass="custom-scrolltop" [threshold]="100" icon="pi pi-arrow-up" />
</div> </div>
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
background-size: var(--bs-accordion-btn-icon-width); background-size: var(--bs-accordion-btn-icon-width);
transition: var(--bs-accordion-btn-icon-transition); transition: var(--bs-accordion-btn-icon-transition);
} }
#toast-container { #toast-container {
width: 100%; width: 100%;
top: 30px; top: 30px;
...@@ -75,6 +76,39 @@ ...@@ -75,6 +76,39 @@
background-color: rgba(255, 255, 255, 0.7); background-color: rgba(255, 255, 255, 0.7);
} }
/* Override Toastr Styles to Look Like PrimeNG Toast */
.toast {
background: var(--surface-card); /* Matches PrimeNG's background */
border: 1px solid var(--surface-border); /* Matches PrimeNG's border */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Subtle shadow */
border-radius: 4px; /* Rounded corners */
color: var(--text-color); /* Matches PrimeNG's text color */
font-family: 'Arial', sans-serif; /* Matches PrimeNG's font */
margin-bottom: 1rem;
padding: 1rem;
width: 300px; /* PrimeNG's default width */
}
.toast-message {
display: flex;
align-items: center;
}
.toast-message .toast-title {
font-weight: bold;
margin-bottom: 0.5rem;
}
.toast-message .toast-body {
margin: 0;
}
.toast-close-button {
color: var(--text-color-secondary); /* Matches PrimeNG's close button color */
}
/*-------------------------------------------------------------- /*--------------------------------------------------------------
# General # General
--------------------------------------------------------------*/ --------------------------------------------------------------*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment