=============================================== HTML ====================================================================================
Important: ReviewerOne is built to enable peer reviews across multiple journal submission systems. We are in the process of setting up these integrations. In the meanwhile, you are free to upload a manuscipt you are reviewing/want to review on ReviewerOne. However, please ensure that you seek the approval of the journal before doing so. Once you receive the green light from the journal for using ReviewerOne to perform the peer review, feel free to upload the manuscript here. Ensure that you comply with the journal's peer review guidelines. ReviewerOne maintains the confidentiality of all the information and content processed through the platform. However, once the peer review is complete, you are responsible for deleting the uploaded files.

Adding this information will help you track your future reviews and understand your own peer review preferences. It will also help you include accurate information on your CV/academic profile. We will use this information to update your peer review experience on the platform, so that you get review invitations from the right journal for manuscripts that are closely aligned with your area(s) of expertise.

Assignment Title is required.
Manuscript ID is required.
This Manuscript ID already exists.
Manuscript Type is required.
Submission Type is required.
Journal name is required.
Journal abbreviation is required.
Journal URL is required.
Publisher is required.
Editor Name is required.
Invitation Date is required.
Review Due Date is required.
Print ISSN is required.
Online ISSN is required.
Review Type is required.
Editor's note is required.
1
You have accepted the journal's invitation to peer review.
2
Include complete details and all relevent files.
Uploadfile is required.
cloud_upload
to add files
preview
{{ f.name }}
Size: {{ f.sizeMB }} MB
×
success
Manuscript uploaded successfully!
You can now view, access, and work on the manuscript from the "In Review" tab in the "My Peer Reviews" section.
========================================================================= CSS ===================================================== .custom-create { display: flex; align-items: center; align-self: stretch; color: var(--Neutral-90, #232b39); font-family: Poppins; font-size: 1.25vw; font-style: normal; font-weight: 600; line-height: normal; letter-spacing: 0.013vw; padding: 0vw 0vw 0.833vw 0vw; } .custom-manu { color: var(--Neutral-90, #232b39); text-align: center; font-family: Poppins; font-size: 1.042vw; font-style: normal; font-weight: 600; line-height: normal; letter-spacing: 0.005vw; padding-left: 0.625vw; } ::ng-deep .custom-calender input::placeholder { color: var(--Neutral-60, #707784) !important; font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 400; line-height: 1.25vw; } .custom-input:focus, .custom-input1:focus, .custom-input2:focus { border-color: #86b7fe; box-shadow: 0 0 0 0.07vw rgba(13, 110, 253, 0.25); outline:none; } .text-danger{ margin-top:0.3125vw; font-size: 0.7291vw !important; font-family: Poppins; } .custom-btnbrowse { display: flex; justify-content: center; width: 45.45678vw; } .browse-text { color: #0065FF; font-weight: 600; text-decoration: underline; cursor: pointer; } .custom-mainr { margin: 0vw; border-radius: 0.8333333333333334vw; background: var(--Neutral-10, #fff); padding: 0.833vw; } .form-group label { font-weight: 500; } .custom-input, .custom-input1, .custom-input2 { width: 100%; padding: 0.677vw 0.521vw; border-radius: 0.417vw; border: 0.052vw solid var(--Neutral-30, #e5e7eb); background: var(--Neutral-10, #fff); border-radius: 0.3vw; outline: none !important; font-size: 0.833vw; // box-shadow: none !important; } .custom-calender { width: 100%; border-radius: 0.417vw; border: 0.052vw solid var(--Neutral-30, #e5e7eb); background: var(--Neutral-10, #fff); border-radius: 0.3vw; outline: none !important; } ::ng-deep .mat-mdc-form-field-subscript-wrapper, ::ng-deep .mat-mdc-form-field-bottom-align::before { display: none !important; } ::ng-deep .mdc-text-field--filled .mdc-line-ripple::before { border-bottom: none !important; height: 0 !important; visibility: hidden !important; } ::ng-deep .mat-mdc-form-field-flex { display: inline-flex; align-items: center !important; height: 2.34375vw; width: 100%; box-sizing: border-box; } ::ng-deep .mat-mdc-form-field-infix { display: flex; align-items: center; height: 100%; padding: 0 0.4166666666666667vw; box-sizing: border-box; } /* Make input align vertically */ ::ng-deep .mat-mdc-input-element { padding: 0 !important; margin: 0 !important; line-height: normal; height: 100%; display: flex; align-items: center; } ::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled) { background: none !important; background-color: transparent !important; border-radius: 0.20833333333333334vw; box-shadow: none; } ::ng-deep .mat-datepicker-toggle { cursor: pointer; } /* Remove filled background */ ::ng-deep .mdc-text-field--filled { background: transparent !important; background-color: transparent !important; box-shadow: none !important; border: none !important; } ::ng-deep .custom-calender .mdc-text-field, ::ng-deep .custom-calender .mdc-text-field__input, ::ng-deep .custom-calender .mdc-text-field__ripple, ::ng-deep .custom-calender .mdc-text-field__touch-target-wrapper { padding: 0 !important; margin: 0 !important; } /* Remove the bottom blue focus/hover line (active indicator) */ ::ng-deep .mdc-line-ripple { display: none !important; } /* Also remove hover + focus overlay background */ ::ng-deep .mat-mdc-form-field-focus-overlay { background: transparent !important; display: none !important; } /* Remove calendar icon background on hover/focus */ ::ng-deep .mat-mdc-icon-button:hover, ::ng-deep .mat-mdc-icon-button:focus { background-color: transparent !important; box-shadow: none !important; } /* Remove ripple effect from calendar icon */ ::ng-deep .mat-mdc-icon-button .mat-ripple { display: none !important; } ::ng-deep .mat-mdc-form-field.mat-focused .mdc-text-field--filled { border: 1px solid #86b7fe !important; box-shadow: 0 0 0 0.07vw rgba(13, 110, 253, 0.25) !important; outline: none !important; background-color: transparent !important; border-radius: 0.20833333333333334vw; } .custom-article { width: 100%; padding: 0vw; border: 0vw solid #ccc; border-radius: 0.3vw; } ::ng-deep .create-assignment .ng-select.ng-select-single .ng-select-container { height: 2.5vw !important; border-radius: 0.4167vw; background: #fff; display: flex; //color: var(--Neutral-60, #707784); font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 400; line-height: 1.25vw; } .disclamer-Data { display: flex; align-items: center; gap: 0.4167vw; padding: 0.625vw 1.25vw; border-radius: 0.3125vw; border: 0.052vw solid #BB9000; background: #FFF3CD; } .disclamer-text { display: flex; gap: 0.20833333333333334vw; //font-size: 0.9vw; // align-items: center; } .disclamer-head { color: #A56404; font-family: Poppins; font-size: 0.725vw; font-weight: 700; margin: 0; } .user-msg { color: #A56404; font-family: Poppins; font-size: 0.725vw; font-weight: 500; } .warning-icon { display: flex; align-items: center; justify-content: center; width: 1.25vw; height: 1.25vw; } .warning-icon svg path:first-child { fill: #FED200; } .warning-icon svg path:nth-child(2), .warning-icon svg circle { stroke: #A56404; fill: #A56404; } .warning-icon svg { width: 1.25vw; height: 1.25vw; } .mt-3 { margin-top: 1.25vw; } .custom-assign { color: var(--Neutral-90, #232b39); font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 500; line-height: 1.25vw; padding: 1.25vw 0vw 0.26vw 0.781vw !important; } .custom-rest { color: var(--Error-Hover, #e00000); font-family: Poppins; font-size: 0.8333333333333334vw; font-style: normal; font-weight: 500; line-height: 1.25vw; } .custom-journal { color: var(--Neutral-90, #232b39); font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 500; line-height: 1.25vw; padding: 0vw 0vw 0.313vw 0vw !important; } .custom-col-9 { width: 72%; padding: 1.25vw 1.25vw 1.25vw 0.625vw; box-sizing: border-box; } // .custom-col-3 { // width: 25%; // padding: 0vw; // box-sizing: border-box; // } .custom-col-3 { position: fixed; // top: 8.4vw; top: 12.8vw; right: 1.5vw; height: auto; width: 21%; padding: 0vw; box-sizing: border-box; background-color: #fff; overflow-y: hidden; /* z-index: 1000; */ } .custom-side { margin-right: 0.521vw; display: flex; margin-top: 2vw; flex-direction: column; align-items: flex-start; padding: 1.25vw; gap: 1vw; border-radius: 0.625vw; background: #fff; box-shadow: 0 0 0.521vw rgba(0, 0, 0, 0.05); } .custom-step { font-size: 1.1vw; font-weight: 600; margin-bottom: -0.5vw; } .col-2 { flex: 0 0 2.5vw; padding: 0vw; } .col { flex: 1; margin-left: 0vw; } .row { --bs-gutter-x: 1.5rem; --bs-gutter-y: 0; display: flex; flex-wrap: wrap; margin-top: calc(var(--bs-gutter-y) * -1); margin-right: calc(var(--bs-gutter-x) * -0.5); margin-left: calc(var(--bs-gutter-x) * 0); } .custom-work { color: var(--Neutral-90, #232b39); text-align: center; font-family: Poppins; font-size: 0.8333333333333334vw; font-style: normal; font-weight: 600; line-height: 1.0416666666666667vw; } .custom-label { display: flex; flex-direction: column; align-items: center; gap: 1.5625vw; } .custom-initial { color: var(--Neutral-90, #232b39); font-family: Poppins; font-size: 0.8333333333333334vw; font-style: normal; font-weight: 400; line-height: normal; margin-left: 0.625vw; } .custom-radio { width: 0.677vw; height: 0.677vw; transform: scale(1.5); accent-color: #00488a; cursor: pointer; // margin-right: 0.5vw; } .issue-radio{ margin-left: 1vw; } label.selected { font-weight: 500; } .selected { font-weight: bold; } .custom-revise { color: var(--Neutral-90, #232b39); font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 500; line-height: normal; } input::placeholder { color: var(--Neutral-60, #707784); font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 400; line-height: 1.25vw; } .ng-select .ng-select-container:focus { outline: none !important; box-shadow: none !important; border-radius: 0.417vw; border: 0.052vw solid var(--Neutral-30, #e5e7eb); background: var(--Neutral-10, #fff); } .file-preview-box { position: relative; border-radius: 0.20833333333333334vw; background: var(--Neutral-20, #F4F5F6); border-radius: 0.521vw; margin: 1.1458333333333333vw 0px 0px 0px; display: flex; align-items: center; } .custum-stap-one { width: 2.0833333333333335vw; height: 2.0833333333333335vw; border-radius: 50%; background: #495AFF; color: white; display: flex; justify-content: center; align-items: center; color: var(--color-white-solid, #FFF); font-family: Poppins; font-size: 0.7291666666666666vw; font-style: normal; font-weight: 600; line-height: 180%; /* 25.2px */ } .custum-stap-inprogress{ width: 2.0833333333333335vw; height: 2.0833333333333335vw; border-radius: 50%; border: 2px solid #495AFF; display: flex; justify-content: center; align-items: center; color: #495AFF; font-family: Poppins; font-size: 0.7291666666666666vw; font-style: normal; font-weight: 600; line-height: 180%; } .custum-stap-incomplite{ width: 2.0833333333333335vw; height: 2.0833333333333335vw; border-radius: 50%; background: var(--Neutral-30, #E5E7EB); display: flex; justify-content: center; align-items: center; color: var(--Neutral-90, #232B39); font-family: Poppins; font-size: 0.7291666666666666vw; font-style: normal; font-weight: 600; line-height: 180%; /* 25.2px */ } .file-content-row { display: flex; align-items: center; width: 100%; } .preview-wrapper { width: 3.125vw; height: 3.125vw; margin-right: 0.521vw; display: flex; align-items: center; justify-content: center; } .preview-wrapper img { width: 2.0833333333333335vw; height: 2.0833333333333335vw; object-fit: contain; } .file-preview-container { max-height: 15.625vw; /* adjust as needed */ overflow-y: auto; padding: 0.5208333333333334vw; margin-top: 0.5208333333333334vw; } .error-msg{ margin-top: 0.4166666666666667vw; } .error-msg small { font-size: 0.625vw; } /* Scrollbar styling (optional, for WebKit browsers) */ .file-preview-container::-webkit-scrollbar { width: 0.4166666666666667vw; } .file-preview-container::-webkit-scrollbar-thumb { background: #aaa; border-radius: 0.20833333333333334vw; } .file-preview-container::-webkit-scrollbar-track { background: #f1f1f1; } .file-icon-placeholder { font-size: 1.667vw; color: #888; } .file-info { flex-grow: 1; display: flex; flex-direction: column; justify-content: center; } .file-name { color: var(--textColor-default, #0B0B0B); font-family: Poppins; font-size: 0.625vw; font-style: normal; font-weight: 500; line-height: 0.9375vw; word-break: break-word; } .file-size { color: var(--textColor-secDefault, #6D6D6D); font-family: Poppins; font-size: 0.625vw; font-style: normal; font-weight: 400; line-height: 0.8333333333333334vw; } .remove-btn { position: absolute; top: 50%; right: 0.521vw; transform: translateY(-50%); background: transparent; border: none; color:black; font-size: 1.042vw; font-weight: bold; cursor: pointer; } .remove-btn:hover{ color: black; } .custom-dashed { display: flex; padding: 1.38vw 0.725vw; flex-direction: column; justify-content: center; align-items: center; gap: 0.7333333333333334vw; align-self: stretch; border-radius: 0.5208333333333334vw; background: var(--Neutral-White-White, #fff); margin: 0.833vw 1.873vw; position: relative; border-width: 0.05208vw; border-style: solid; border-image: repeating-linear-gradient( 51deg, #a0a8b0 0 0.5208333333333334vw, transparent 0.5208333333333334vw 1.0416666666666667vw ) 1; margin-top: 0.7vw; margin-left: 2vw; } .custom-uploadicon { padding-left: 85vw; top: 2vw; left: 50vw; transform: translateX(-50%); width: 3vw; height: auto; fill: var(--Primary-Main, #00488a); z-index: 1000; } .custom-drag { color: var(--Neutral-90, #232b39); font-family: Poppins; font-size: 0.8333333333333334vw; font-style: normal; font-weight: 600; padding: 0.6770833333333334vw; line-height: 140%; letter-spacing: 0.004vw; margin-top: -0.5208333333333334vw; } .spinner { display: inline-block; width: 0.802083vw; height: 0.802083vw; border: 0.14166667vw solid #f3f3f3; border-top: 0.1404166667vw solid #007bff; border-radius: 50%; animation: spin 0.8s linear infinite; vertical-align: middle; margin-right: 0.4166666667vw; } ::ng-deep .ng-select .ng-arrow-wrapper { display: flex !important; opacity: 1 !important; /* always visible */ visibility: visible !important; } ::ng-deep .ng-select .ng-arrow { //border-top-color: #000 !important; /* arrow color (black) */ } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .custom-browse { display: flex; justify-content: center; align-items: center; gap: 0.41667vw; padding: 0.52vw 0.83vw; width: 4.17vw; margin-left: 40.57vw; background: var(--Neutral-20, #f4f5f6); color: var(--Primary-Main, #112030); border: none; border-radius: 0.52vw; cursor: pointer; font-family: "Poppins", sans-serif; font-size: 0.73vw; font-style: normal; font-weight: 600; line-height: 1.4; letter-spacing: 0.004vw; } .custom-browse-loading { display: flex; justify-content: center; align-items: center; gap: 0.41667vw; width: 8.177083333333334vw; padding: 0.8333333333333334vw; margin-left: 40.57vw; background: var(--Neutral-20, #f4f5f6); color: var(--Primary-Main, #112030); border: none; border-radius: 0.52vw; cursor: pointer; font-family: "Poppins", sans-serif; font-size: 0.73vw; font-style: normal; font-weight: 600; line-height: 1.4; letter-spacing: 0.004vw; } .custom-format { color: var(--Neutral-Black-Black-400, #858d9d); font-family: Poppins; font-size: 0.7291666666666666vw; font-style: normal; font-weight: 400; padding: 0.6770833333333334vw; line-height: 140%; //margin-left: 1.0416666666666667vw; letter-spacing: 0.004vw; } .main-container { padding: 1.771vw; } .custom-upload-container.dragging { border: 0.10416666666666667vw dashed #007bff; background-color: #f9fbff; } .custom-message { color: var(--Neutral-60, #707784); font-family: Poppins; font-size: 0.729vw; font-style: normal; font-weight: 400; line-height: 1.25vw; margin-top: 0.3vw; } // .custom-message1 { // color: #495aff; // font-family: Poppins; // font-size: 0.729vw; // font-style: normal; // font-weight: 400; // line-height: 1.25vw; // margin-top: 0.3vw; // } .custom-Receive2 { color: var(--Neutral-70, #515966); font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 500; line-height: 1.042vw; } .custom-Receive { color: var(--Neutral-90, #232b39); text-align: center; font-family: Poppins; font-size: 0.833vw; font-style: normal; font-weight: 500; line-height: 1.042vw; } // .custom-Receive1 { // color: #495aff; // font-family: Poppins; // font-size: 0.833vw; // font-style: normal; // font-weight: 600; // line-height: 1.042vw; // } .custom-line, .custom-line1 { width: 0.078vw; height: 3vw; background: #ccc; margin: 0.938vw 1.104vw 0.469vw 0.999vw; } .custom-Elli { width: 2vw; height: 2vw; } .card-content { padding: 0vw !important; display: flex; justify-content: space-between; gap: 0.521vw; } .button-footer { display: flex; justify-content: flex-end; gap: 1vw; padding: 1.5vw 2vw; position: relative; z-index: 1; display: flex; margin-right: 20vw; //margin-top: 1.25vw; } button.custom-cancel { padding: 0.7291666666666666vw 0.8333333333333334vw; border-radius: 0.5208333333333334vw; background: var(--Neutral-Black-Black-100, #E0E2E7); cursor: pointer; color: var(--Neutral-70, #515966); font-family: Poppins; font-size: 0.8333333333333334vw; font-style: normal; font-weight: 600; line-height: 140%; letter-spacing: 0.08px; border: none; } button.custom-cancel:hover { background: var(--Neutral-30, #D3D6DA); } button.custom-create1 { padding: 0.7291666666666666vw 0.8333333333333334vw; background: linear-gradient(178deg, #EF4136 19.81%, #AD003C 98.88%); color: #fff; font-family: Poppins; font-size: 0.833vw; font-weight: 600; border: none; border-radius: 0.4167vw; cursor: pointer; // width: 14vw; } button.custom-create1:hover{ background: linear-gradient(178deg, #AD003C 19.81%, #EF4136 98.88%); } .custom-dashed.dragover { background-color: #eef6ff; border-color: #3399ff; } .browse-btn { background: none; color: #0043aa; border: none; font-size: 0.72917vw; font-family: Poppins, sans-serif; font-weight: 600; line-height: 1.02083vw; letter-spacing: 0.00365vw; cursor: pointer; } .spinner.small-spinner { width: 0.8333333333333334vw; height: 0.8333333333333334vw; border: 2px solid #ccc; border-top: 2px solid #007bff; border-radius: 50%; display: inline-block; animation: spin 0.8s linear infinite; margin-right: 0.4166666666666667vw; vertical-align: middle; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .file-loader { text-align: center; margin-top: 2vw; } .spinner { border: 0.2vw solid #f3f3f3; border-top: 0.2vw solid #3498db; border-radius: 50%; width: 1vw; height: 1vw; animation: spin 1s linear infinite; margin: 0 auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .no-files { text-align: center; color: #999; margin-top: 2vw; } .submit-backdrop { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.4); display: flex; justify-content: center; align-items: center; z-index: 1000; } .submit-popup { position: relative; background: white; padding: 1.25vw; border-radius: 1vw; box-shadow: 0px 0.3vw 2vw rgba(26, 28, 33, 0.05); width: 25vw; display: flex; flex-direction: column; align-items: center; max-height: 19.3vw; gap: 1.5vw; font-family: 'Poppins', sans-serif; } .submit-popup-close { position: absolute; top: 1vw; right: 1vw; font-size: 1.5vw; cursor: pointer; color: #999; transition: color 0.3s ease; } .submit-popup-close:hover { color: #000; } .submit-popup-icon-box { background: #D6F4DE; border-radius: 50%; display: flex; justify-content: center; align-items: center; } .submit-popup-check { font-size: 2.2vw; color: #34C759; font-weight: bold; } .submit-popup-content { text-align: center; display: flex; flex-direction: column; gap: 0.6vw; max-width: 90%; } .submit-popup-title { font-size: 1.0416666666666667vw; font-weight: 600; color: #273238; } .submit-popup-message { font-size: 0.8333333333333334vw; font-weight: 400; color: #667085; line-height: 1.6; } .submit-popup-actions { display: flex; width: 100%; justify-content: center; gap: 1vw; } .submit-popup-button-light { background: #E0E2E7; color: #515966; padding: 0.1vw 1.2vw; border: none; border-radius: 0.6vw; font-size: 0.8333333333333334vw; font-weight: 400; cursor: pointer; } .submit-popup-button-light:hover{ background: var(--Neutral-30, #D3D6DA); } .submit-popup-button-primary { background: linear-gradient(180deg, #EF4136 18%, #AD003C 100%); color: white; padding: 0.8vw 2vw; border: none; border-radius: 0.6vw; font-size: 0.8333333333333334vw; font-weight: 500; cursor: pointer; } .submit-popup-button-primary:hover{ background: linear-gradient(180deg, #AD003C 18%, #EF4136 100%); } .rating-badge { width: 100%; height: 100%; padding-left: 0.308vw; padding-right: 0.308vw; padding-top: 0.104vw; padding-bottom: 0.104vw; background: #FFEFC0; border-radius: 0.208vw; display: inline-flex; justify-content: flex-start; align-items: center; gap: 0.104vw; } .rating-icon { width: 0.833vw; height: 0.833vw; display: flex; align-items: center; justify-content: center; overflow: hidden; } .rating-icon-inner { font-size: 0.8vw; color: #DB8000; line-height: 1; } .rating-text { color: #DB8000; font-size: 0.729vw; font-family: 'Poppins', sans-serif; font-weight: 500; line-height: 1.02vw; letter-spacing: 0.004vw; word-wrap: break-word; } .custom-input-editor { height: 4vw; padding-left: 0.6vw; padding-top: 0.6vw; font-family: Poppins; line-height: normal; font-size: 0.833vw; } .custom-input-editor::placeholder { font-size: 0.8333333333333334vw; color: #707784; font-family: Poppins; font-weight: 400; } .upload-manuscript-description{ color: #707784; font-size: 0.729vw; font-family: Poppins; font-weight: 400; letter-spacing: 0.07px; word-wrap: break-word; padding-left: 0.625vw; text-align: justify; } .journal-subtext{ color: #707784; font-size: 0.833vw; font-family: Poppins; font-weight: 400; line-height: 1.25vw; word-wrap: break-word } .custom-label-text{ color: #232B39; font-size: 0.833vw; font-family: Poppins; font-weight: 500; word-wrap: break-word; margin-left: 0.1vw; } .custom-check-label{ color: #232B39; font-size: 14px; font-family: Poppins; font-weight: 400; line-height: 24px; word-wrap: break-word } .custom-check{ margin-right: 0.741vw; cursor: pointer; } .custom-input1.disable-input { color: #707784; font-family: 'Poppins', sans-serif; font-weight: 400; word-wrap: break-word; background-color: #f2f2f2; } .custom-input2.disable-input-two{ color: #707784; font-family: 'Poppins', sans-serif; font-weight: 400; word-wrap: break-word; background-color: #f2f2f2; } ======================================================================== TS ================================================================ import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { ToastrService } from 'ngx-toastr'; import { forkJoin, Observable } from 'rxjs'; import { ApiService } from 'src/app/core/api.service'; @Component({ selector: 'app-create-assignment', templateUrl: './create-assignment.component.html', styleUrls: ['./create-assignment.component.scss'] }) export class CreateAssignmentComponent { selectedSubmissiontype: string = ''; CreateAssignmentform!: FormGroup; selectedFiles: { file: File; name: string; previewUrl: string | null; sizeMB: string; isImage: false; }[] = []; submit: boolean = false; constructor(private fb: FormBuilder, private apiservice: ApiService, private toastr: ToastrService, private router: Router, private http: HttpClient, private apiservise: ApiService) { } ngOnInit(): void { this.CreateAssignmentform = this.fb.group({ submissionType: ['', Validators.required], EditorNote: ['',Validators.required], Publisher: ['', Validators.required], AssignmentTitle: ['', Validators.required], Journal: ['', Validators.required], ManuscriptID: ['', Validators.required], InvitedDate: ['', Validators.required], ReviewDueDate: ['', Validators.required], SpecialIssue: [''], Uploadfile: [''], articleType: [null, Validators.required], editorName: [null], Acronym: ['',Validators.required], PrintISSN: ['',Validators.required], OnlineISSN: ['',Validators.required], ReviewType: [null,Validators.required], JournalUrl: ['',Validators.required], specifyIssue:[null], isCheckPrint:[false], isCheckOnline:[false] }); } articleTypes = [ { id: 'or', name: 'Original research' }, { id: 'es', name: 'Empirical study' }, { id: 'sr', name: 'Systematic review' }, { id: 'ma', name: 'Meta-analysis/analyses' }, { id: 'cr', name: 'Case report(s)' }, { id: 'lr', name: 'Literature review' }, { id: 'rc', name: 'Research brief/Short communication' }, { id: 'ot', name: 'Other' } ]; reviewType = [ { id: 'sb', name: 'Single blind peer review' }, { id: 'db', name: 'Double blind peer review' }, { id: 'tb', name: 'Triple blind peer review' }, { id: 'or', name: 'Open peer review' }, { id: 'cr', name: 'Collaborative peer review' } ]; editorNames = [ { id: 1, name: 'Dr. Elena M. Farrow' }, { id: 2, name: 'Kevin Ward' }, { id: 3, name: 'Jihye Kim' }, { id: 4, name: 'Dr. Fiona L. Reyes' } ]; isDragOver = false; isDragging = false; isUploading = false; showTextArea:boolean=false; disableIssn:boolean=false; disableIssnTwo:boolean=false; public onDragOver(event: DragEvent) { event.preventDefault(); this.isDragOver = true; } public onDragLeave(event: DragEvent) { event.preventDefault(); this.isDragOver = false; } public onDrop(event: DragEvent, fileInput: HTMLInputElement) { event.preventDefault(); this.isDragOver = false; const files = event.dataTransfer?.files; if (files && files.length > 0) { this.onFileSelected({ target: { files } }); fileInput.files = files; } } public onRadioChange(value: string): void { this.selectedSubmissiontype = value; } public validSpecialIssue(){ this.showTextArea=true; } public inValidSpecialIssue(){ this.showTextArea=false; } public disablePrintIssn(event: any) { const checked = event.target.checked; const printIssnControl = this.CreateAssignmentform.get('PrintISSN'); if (checked) { printIssnControl?.disable(); this.disableIssn = true; } else { printIssnControl?.enable(); this.disableIssn = false; } } public disableOnlineIssn(event: any){ const checked = event.target.checked; const onlineIssnControl = this.CreateAssignmentform.get('OnlineISSN'); if (checked) { onlineIssnControl?.disable(); this.disableIssnTwo = true; } else { onlineIssnControl?.enable(); this.disableIssnTwo = false; } } public getAssetImage(fileName: string): string { const cleanName = fileName.replace(/\(\d+\)/g, '').trim(); const extension = cleanName.split('.').pop()?.toLowerCase(); switch (extension) { case 'pdf': return 'assets/file-uploaded-images/PDF_file.png'; case 'doc': case 'docx': return 'assets/file-uploaded-images/docx.png'; case 'zip': return 'assets/file-uploaded-images/zip.png'; case 'tiff': return 'assets/file-uploaded-images/tiff.png'; case 'eps': return 'assets/file-uploaded-images/eps.png'; case 'csv': return 'assets/file-uploaded-images/csv.png'; default: return 'assets/file-uploaded-images/default.png'; } } // public onFileSelected(event: any): void { // const files: FileList = event.target.files; // if (!files || files.length === 0) return; // const allowedExtensions = ['pdf', 'docx', 'zip']; // const maxFileSize = 2 * 1024 * 1024 * 1024; // 2GB // const maxTotalFiles = 6; // for (let i = 0; i < files.length; i++) { // const file = files[i]; // const fileExtension = file.name.split('.').pop()?.toLowerCase(); // // Check file count // if (this.selectedFiles.length >= maxTotalFiles) { // this.toastr.warning('Maximum 6 files allowed.'); // break; // } // // Check file type by extension // if (!fileExtension || !allowedExtensions.includes(fileExtension)) { // this.toastr.error(`${file.name} is not a supported format (.zip, .docx, .pdf only).`); // continue; // } // // Check file size // if (file.size > maxFileSize) { // this.toastr.error(`${file.name} exceeds the 2GB limit.`); // continue; // } // // Create preview and store // const reader = new FileReader(); // reader.onload = (e: any) => { // const preview = this.getAssetImage(file.name); // const fileSize = (file.size / (1024 * 1024)).toFixed(2); // this.selectedFiles.push({ // file, // name: file.name, // previewUrl: preview, // sizeMB: fileSize, // isImage: false // }); // }; // reader.readAsDataURL(file); // } // // Reset file input // event.target.value = null; // } public onFileSelected(event: any): void { const files: FileList = event.target.files; if (!files || files.length === 0) return; const allowedExtensions = ['pdf', 'docx', 'zip']; const maxFileSize = 2 * 1024 * 1024 * 1024; // 2GB const maxTotalFiles = 6; // Check total file count before adding if (this.selectedFiles.length + files.length > maxTotalFiles) { this.toastr.warning(`You can upload a maximum of ${maxTotalFiles} files.`); event.target.value = null; // reset input return; } for (let i = 0; i < files.length; i++) { const file = files[i]; const fileExtension = file.name.split('.').pop()?.toLowerCase(); // Check file type by extension if (!fileExtension || !allowedExtensions.includes(fileExtension)) { this.toastr.error(`${file.name} is not a supported format (.zip, .docx, .pdf only).`); continue; } // Check file size if (file.size > maxFileSize) { this.toastr.error(`${file.name} exceeds the 2GB limit.`); continue; } // Create preview and store const reader = new FileReader(); reader.onload = (e: any) => { const preview = this.getAssetImage(file.name); const fileSize = (file.size / (1024 * 1024)).toFixed(2); this.selectedFiles.push({ file, name: file.name, previewUrl: preview, sizeMB: fileSize, isImage: false }); }; reader.readAsDataURL(file); } // Reset file input event.target.value = null; } public removeFile(index: number): void { this.selectedFiles.splice(index, 1); } public createAssignment(): void { const userId = localStorage.getItem('basicUserId'); if (!userId) { this.toastr.error('User ID not found.'); return; } if (this.CreateAssignmentform.invalid) { this.CreateAssignmentform.markAllAsTouched(); this.toastr.error("Please fill all mandatory fields", 'Error'); return; } if (this.selectedFiles.length === 0) { this.toastr.warning('Please select at least one file.'); return; } this.isUploading = true; const manuscriptId = this.CreateAssignmentform.value.ManuscriptID; const now = new Date().toISOString(); const requestObject = [{ userId: Number(userId) || 0, title: this.CreateAssignmentform.value.AssignmentTitle, dueDate: this.formatDateOnly(this.CreateAssignmentform.value.ReviewDueDate), manuscriptId: manuscriptId, inviteDate: this.formatDateOnly(this.CreateAssignmentform.value.InvitedDate), submissionType: this.CreateAssignmentform.value.submissionType, editorName: this.CreateAssignmentform.value.editorName, journal: this.CreateAssignmentform.value.Journal, publishername: this.CreateAssignmentform.value.Publisher, url: this.CreateAssignmentform.value.JournalUrl || '', publisherLogo: "", articleImage: "string", dueLabel: "string", impactFactor: 0, acceptanceRate: "string", accessType: "string", issn: "string", predatory: "string", articleType: this.CreateAssignmentform.value.articleType || '', websiteLinkImage: "string", mailImage: "string", iproofUrl: "string", acceptedDate: now, completedDate: now, submission: now, declineDate: now, status: 'InReview', isManual: "string", isStatus: "string", acronym: this.CreateAssignmentform.value.Acronym || '', editorNote: this.CreateAssignmentform.value.EditorNote || '', printIssn: this.CreateAssignmentform.value.PrintISSN || '', onlineIssn: this.CreateAssignmentform.value.OnlineISSN || '', reviewType: this.CreateAssignmentform.value.ReviewType || '' }]; console.log('Create assignment', requestObject) // 🔹 Step 1: Create assignment first this.apiservice.addAcceptInvitations(Number(userId), requestObject).subscribe({ next: (res) => { if (res.success === true) { // this.toastr.success('Assignment created successfully.'); // 🔹 Step 2: Upload files only after assignment creation this.uploadAllFiles(userId, manuscriptId).subscribe({ next: () => { this.isUploading = false; this.toastr.success('Manuscript uploaded successfully!'); this.submit = true; }, error: (err) => { this.isUploading = false; this.toastr.error('File upload failed.', 'Error'); console.error('Upload error:', err); } }); } else { this.isUploading = false; this.toastr.error('Failed to create assignment', 'Error'); } }, error: () => { this.isUploading = false; this.toastr.error('Service not available', 'Error'); } }); } formatDateOnly(date: Date): string { if (!date) return ''; const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}T00:00:00.000Z`; } public uploadAllFiles(userId: string, manuscriptId: string): Observable { const formData = new FormData(); this.selectedFiles.forEach(fileObj => { formData.append('files', fileObj.file); // all files under "files" }); formData.append('userId', userId); formData.append('manuscriptId', manuscriptId); return this.apiservice.uploadFileCreateAssignment(formData); } startReview() { this.router.navigate(['/home/inreview']); } closePopUp() { this.submit = false; this.CreateAssignmentform.reset(); this.selectedFiles = []; } onInputManuscript() { const userId = localStorage.getItem('basicUserId'); this.apiservice.getAllManuscriptId(Number(userId)).subscribe((res: any) => { const manuscriptIds: string[] = res as string[]; if (manuscriptIds && Array.isArray(manuscriptIds)) { const manuscriptControl = this.CreateAssignmentform.get('ManuscriptID'); manuscriptControl?.addValidators([ Validators.required, (control: AbstractControl) => { if (!control.value) return null; const enteredValue = control.value.trim().toLowerCase(); const isDuplicate = manuscriptIds.some( (id: string) => id.trim().toLowerCase() === enteredValue ); return isDuplicate ? { duplicate: true } : null; } ]); manuscriptControl?.updateValueAndValidity({ emitEvent: false }); } }); } removeSpaces(event: any) { const input = event.target.value; event.target.value = input.replace(/\s+/g, ''); // removes all spaces this.CreateAssignmentform.get('ManuscriptID')?.setValue(event.target.value, { emitEvent: false }); } removeLeadingSpace(event: Event) { const input = event.target as HTMLInputElement; if (input.value.startsWith(' ')) { input.value = input.value.trimStart(); } } }