Is there a way to add an image to an about:blank cloaking tool?

I am trying to make an about:blank cloaking tool. However, I am having an issue with uploading an icon to the cloak. Here is my code:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input id="link", type="text", value="Insert Link..."></input>
<input id="title", type="text", value="Insert Title..."></input>
<input type="file", id="myFile", name="filename">
<button onclick="openGame()">Open Game</button>
<script>
  function openGame() {
  var win = window.open()
  var url = document.getElementById("link").value;
  var iframe = win.document.createElement('iframe')
  iframe.style.width = "100%";
  iframe.style.height = "100%";
  iframe.style.border = "none";
  iframe.src = url;
  win.document.body.appendChild(iframe)
  win.document.title = document.getElementById("title").value;
  link = win.document.createElement('link')
  link.rel = icon
  link.type = "image/x-icon"
  link.href = document.getElementById("myFile").value;
  win.document.head.appendChild(link)
}
</script>
</body>
</html>

Also, if you have the chance, could you provide a way to add an icon that isn’t just an .ico file?

Anything is much appreciated.

I tried a few combinations using W3schools (specifically file upload and favicon pages) and messed around quite a bit with the code. What resulted was I only got the default favicon, no matter what icon I uploaded.

records are duplicated while adding two different accounts once

I want to add two accounts. For that I will make use of the account dropdown. Every time I select an account number the site and container description is populated automatically. After that I will fill the require fields and click ‘Update’.

When I click Update the entire page reloads. I should get 2 records only but I am getting four records which is not correct.

Although I did not face this issue while two similar accounts are added once.

Here’s what the UI looks like:

enter image description here

inc_detail_transactions_write.jsp:

<c:otherwise>
  <sec:authorize access="hasAuthority(T(com.repsrv.tph2.cbs.authorization.CbsPointers).INVOICE_ENTRY)">
    <jsp:include page="inc_detail_transactions_write.jsp"/>
  </sec:authorize>
</c:otherwise>

inc_detail_transactions_write.jsp


<form id="detailForm" method="post" name="detailForm" onsubmit="return doUpdate();" action="${requestScope['javax.servlet.forward.request_uri']}">
  <input type="hidden" name="headerInvoiceStatus" value="${headerRec.invoiceStatus}" />
  <table id="writeTable" aria-describedby="writeTable" class="table table-center-alltable-sm table-no-top-border table-font-md detailInputTable table-sm table-borderless vertical-align" style="border-collapse: separate; border-spacing:0 6px;">
    <thead>
      <tr class="border_bottom">
        <th scope="col">
          <input type="checkbox" class=" selectAll" id="selectAll">
        </th>
        <c:if test="${multipleAccounts }">
          <th scope="col" class="text-center">Account</th>
          <th scope="col" class="text-center">Site</th>
        </c:if>
        <th scope="col" class="text-center">Container Description</th>
        <th scope="col" class="text-center">Charge<br/>Type</th>
        <th scope="col" class="text-center">Service<br/>Date</th>
        <th scope="col" class="text-center">Service<br/>Code</th>
        <th scope="col" class="text-center">Charge Code</th>
        <th scope="col" class="text-center">Customer<br/>PO #</th>
        <th scope="col" class="text-center">Disposal<br/>Volume</th>
        <th scope="col" class="text-center">Disposal<br/>Unit of Measure</th>
        <th scope="col" class="text-center">Amt Inv<br/>from<br/>Hauler</th>
        <th scope="col" class="text-center">Amt to be<br/>Paid to<br/>Hauler</th>
        <c:if test="${multipleAccounts }">
          <th scope="col" class="text-center">Bulk<br/>Mode</th>
          <th scope="col" class="text-center">Row<br/>Identifier</th>
        </c:if>
        <th scope="col">&nbsp;</th>
      </tr>
    </thead>
    <tbody>
      <c:set var="containerChains" value="" />
      <c:set var="containerNonBillChains" value="-1+-1" />
      <c:set var="containerFullChargeChains" value="-1+-1" />
      <c:set var="urContainerTypeChains" value="-1+-1" />
      <c:forEach var="container" items="${invoiceContainers }" varStatus="loop">
        <c:set var="containerChains" value="${container.container} ${containerChains}" />
        <c:set var="containerNonBillChains" value="${container.container}+Non_Bill ${containerNonBillChains}" />
        <c:set var="containerFullChargeChains" value="${container.container}+Full_Charge ${containerFullChargeChains}" />
        <c:set var="urContainerTypeChains" value="${container.container}+-1 ${urContainerTypeChains}" />
        <c:forEach items="${container.containerDetails }" var="containerDetail" varStatus="loop">
          <c:forEach var="chargeCode" items="${containerDetail.chargeCodes }">
            <c:set var="urContainerTypeChains" value="${container.container}+${containerDetail.urNumber} ${urContainerTypeChains}" />
          </c:forEach>
        </c:forEach>
      </c:forEach>
      <c:forEach var="transaction" items="${transactions }" varStatus="iterStatus">
        <c:set var="rowClass" value="" />
        <c:choose>
          <c:when test="${transaction.uiIdentifier eq 'EDI Transaction'}">
            <c:set var="rowClass" value="table-ediRow" /></c:when>
          <c:when test="${transaction.uiIdentifier eq 'AutoPay'}">
            <c:set var="rowClass" value="table-autoPayRow" /></c:when>
          <c:when test="${transaction.uiIdentifier eq 'eInvoice Transaction'}">
            <c:set var="rowClass" value="table-eInvoiceRow" /></c:when>
        </c:choose>
        <tr class="${rowClass }" id="row${iterStatus.count -1 }">
          <td class="text-center">
            <input type="checkbox" name="invoiceEntry[${iterStatus.count -1 }].selected" data-varname="selected" value="true">
            <input type="hidden" name="invoiceEntry[${iterStatus.count -1 }].update" value="${not empty transaction.container }" data-varname="update">
            <input type="hidden" name="invoiceEntry[${iterStatus.count -1 }].ediTransaction" value="${transaction.uiIdentifier eq 'EDI Transaction'}" data-varname="ediTransaction">
            <input type="hidden" name="invoiceEntry[${iterStatus.count -1 }].transactionId" value="${transaction.transactionId}" data-varname="transactionId">
          </td>
          <c:if test="${multipleAccounts }">
            <td>
              <select class="invAccount" data-rownum="${iterStatus.count -1 }" data-varname="bulkKey.account" name="invoiceEntry[${iterStatus.count -1 }].bulkKey.account" id="invoiceEntry${iterStatus.count -1 }bulkKey.account">
                <option value="-1">&nbsp;</option>
                <c:forEach items="${acctIds }" var="item">
                  <option ${transaction.account eq item ? 'selected' : '' } value="${item }">${item }</option>
                </c:forEach>
              </select>
            </td>
            <td>
              <select class="invSite" data-rownum="${iterStatus.count -1 }" data-varname="bulkKey.site" name="invoiceEntry[${iterStatus.count -1 }].bulkKey.site" id="invoiceEntry${iterStatus.count -1 }bulkKey.site">
                <option value="-1">&nbsp;</option>
                <c:forEach var="site" items="${siteAccountMaps }">
                  <c:set var="accounts" value="${site.value}" />
                  <c:set var="acctChain" value="" />
                  <c:set var="acctSiteChain" value="" />
                  <c:forEach var="acct" items="${accounts}">
                    <c:set var="acctChain" value="${acct} ${acctChain}" />
                    <c:set var="acctSiteChain" value="${acct}+${site.key } ${acctSiteChain}" />
                  </c:forEach>
                  <option value="${site.key }" data-chained="${acctChain }" ${transaction.site eq site.key ? 'selected' : '' }>${site.key }</option>
                </c:forEach>
              </select>
            </td>
          </c:if>
          <td>
            <select class="invContainer" data-rownum="${iterStatus.count -1 }" data-varname="container" name="invoiceEntry[${iterStatus.count -1 }].container" id="invoiceEntry${iterStatus.count -1 }container">
              <option value="-1" data-chained="-1+-1 -1 ${acctSiteChain }">&nbsp;</option>
              <c:forEach var="container" items="${invoiceContainers }">
                <c:if test="${transaction.container eq container.container}">
                  <c:set var="selectedContainer" value="${container }" />
                </c:if>
                <c:set var="containerStatus" value="${container.containerCloseDate eq '0001-01-01' ? ' - Active' : ' - Inactive'}" />
                <option data-chained="${container.account }" ${transaction.container eq container.container ? 'selected' : '' } value="${container.container }" data-containertype="${container.containerType }" data-containersize="${container.containerSize }" data-compactor="${container.compactorflag }">${container.container }
                  <c:out value="${container.containerDescription } ${containerStatus }" />
                </option>
              </c:forEach>
            </select>
            <input type="hidden" value="${transaction.serviceSource }" data-varname="serviceSource" name="invoiceEntry[${iterStatus.count -1 }].serviceSource" id="invoiceEntry${iterStatus.count -1 }serviceSource" />
            <input type="hidden" value="${selectedContainer.containerType }" data-varname="containerType" name="invoiceEntry[${iterStatus.count -1 }].containerType" id="invoiceEntry${iterStatus.count -1 }containerType" />
            <input type="hidden" value="${selectedContainer.containerSize }" data-varname="containerSize" name="invoiceEntry[${iterStatus.count -1 }].containerSize" id="invoiceEntry${iterStatus.count -1 }containerSize" />
            <input type="hidden" value="${selectedContainer.compactorflag }" data-varname="compactorFlag" name="invoiceEntry[${iterStatus.count -1 }].compactorFlag" id="invoiceEntry${iterStatus.count -1 }compactorFlag" />
            <input type="hidden" value="${iterStatus.count -1 }" data-varname="uiRowNumber" name="invoiceEntry[${iterStatus.count -1}].uiRowNumber" id="invoiceEntry${iterStatus.count -1}uiRowNumber" />

          </td>
          <td>
            <select class="chargeType" autocapitalize="none" data-varname="chargeType" name="invoiceEntry[${iterStatus.count -1 }].chargeType" id="invoiceEntry${iterStatus.count -1 }chargeType">
              <option value="-1" data-chained="-1 ${containerChains }">&nbsp;</option>
              <option value="Non_Bill" ${transaction.noneUrNumberType eq 'Non Bill' ? 'selected' : '' } data-chained="-1 ${containerChains }">Non Bill</option>
              <option value="Full_Charge" ${transaction.noneUrNumberType eq 'Full Charge' ? 'selected' : '' } data-chained="-1 ${containerChains }">Full Charge</option>
              <c:set var="selectedEffDate" value="" />
              <c:set var="urFound" value="${transaction.noneUrNumberType eq 'Non Bill' or (transaction.noneUrNumberType eq 'Full Charge') }" />
              <c:forEach var="container" items="${invoiceContainers }">
                <c:forEach items="${container.containerDetails }" var="containerDetail" varStatus="loop">
                  <c:if test="${empty containerDetail.invoice or (containerDetail.invoice eq headerRec.invoiceNumber)}">
                    <option data-servicesource="${containerDetail.serviceSource}" data-customerpo="${containerDetail.scheduled }" data-servicedate="${containerDetail.serviceDate }" data-servicecode="${containerDetail.serviceCode }" ${containerDetail.urNumber eq transaction.noneUrNumberType
                      ? 'selected=selected' : '' } value="${containerDetail.urNumber }" data-chained="${container.container }">
                      <c:out value="${containerDetail.urNumber }" />
                    </option>
                    <c:set var="urFound" value="${urFound or (containerDetail.urNumber eq transaction.noneUrNumberType) }" />
                    <c:set var="urChains" value="${containerDetail.urNumber} ${urChains}" />
                  </c:if>
                </c:forEach>
              </c:forEach>
              <c:if test="${not urFound }">
                <option data-servicesource="${transaction.serviceSource}" data-customerpo="" data-servicedate="${transaction.serviceDate }" data-servicecode="${transaction.serviceCode }" selected=selected value="${transaction.noneUrNumberType }" data-chained="${transaction.container }">
                  <c:out value="${transaction.noneUrNumberType }" />
                </option>
              </c:if>
            </select>
          </td>
          <td><input class="datepicker" id="serviceDate" autocomplete="off" name="invoiceEntry[${iterStatus.count -1 }].serviceDate" type="text" value="${transaction.serviceDate }" size=10 data-varname="serviceDate" /></td>
          <td><input type="text" value="${transaction.serviceCode }" name="invoiceEntry[${iterStatus.count -1 }].serviceCode" size=12 data-varname="serviceCode" /> </td>
          <td>
            <select style="width: 100%;" class="chargeCode" data-varname="chargeCode" name="invoiceEntry[${iterStatus.count -1 }].chargeCode" id="invoiceEntry${iterStatus.count -1 }chargeCode">
              <option value="-1" data-chained="-1+-1 -1 -1+Full_Charge -1+Non_Bill ${urChains } ${ containerNonBillChains} ${urContainerTypeChains} ${containerFullChargeChains}">&nbsp;</option>
              <c:set var="selectedEffDate" value="" />
              <c:forEach var="fcCode" items="${fullchargeCodes }">
                <option data-effectivedate="${fcCode.effectiveDate}" value="${fcCode.code }" ${transaction.chargeCode eq fcCode.code ? 'selected' : '' } data-chained="${fcCode.container }+Full_Charge -1+-1">
                  <c:out value="${fcCode.description }" />
                </option>
                <c:if test="${transaction.chargeCode eq fcCode.code }">
                  <c:set var="selectedEffDate" value="${fcCode.effectiveDate }" />
                </c:if>
              </c:forEach>

              <c:set value="" var="nbType" />
              <c:forEach var="nonBillCode" items="${nonBillCodes }" varStatus="nbStatus">
                <c:if test="${nbType ne nonBillCode.type and (not empty nbType)}">
                  </optgroup>
                </c:if>
                <c:if test="${nbType ne nonBillCode.type}">
                  <optgroup label="${nonBillCode.type }" data-chained="${ containerNonBillChains}">
                </c:if>
                <c:set value="${nonBillCode.type }" var="nbType" />
                <option value="${nonBillCode.code }" ${transaction.chargeCode eq nonBillCode.code ? 'selected' : '' } data-chained="${ containerNonBillChains}">
                  <c:out value="${nonBillCode.description }" /> </option>
                <c:if test="${nbStatus.last }">
                  </optgroup>
                </c:if>
              </c:forEach>
              <c:forEach var="container" items="${invoiceContainers }">
                <c:forEach items="${container.containerDetails }" var="containerDetail" varStatus="loop">
                  <c:forEach var="chargeCode" items="${containerDetail.chargeCodes }">
                    <option ${transaction.chargeCode eq chargeCode.code ? 'selected' : '' } value="${chargeCode.code }" data-chained="${container.container}+${containerDetail.urNumber}">
                      <c:out value="${chargeCode.description }" />
                    </option>
                  </c:forEach>
                </c:forEach>
              </c:forEach>
              <c:if test="${not urFound }">
                <option selected value="${transaction.chargeCode }" data-chained="${transaction.container}+${transaction.noneUrNumberType}">
                  <c:out value="${transaction.chargeCodeDescription }" />
                </option>
              </c:if>
            </select>
            <input type="hidden" value="${selectedEffDate }" data-varname="effectiveDate" name="invoiceEntry[${iterStatus.count -1}].effectiveDate" id="invoiceEntry${iterStatus.count -1}effectiveDate" />
          </td>
          <td><input type="text" name="invoiceEntry[${iterStatus.count -1 }].customerPoNumber" size=12 data-varname="customerPoNumber" value="${transaction.customerPoNumber }" /></td>
          <td><input type="text" name="invoiceEntry[${iterStatus.count -1 }].disposalVolume" size=6 data-varname="disposalVolume" value="${transaction.disposalVolume }"></td>
          <td>
            <select data-varname="disposalUom" name="invoiceEntry[${iterStatus.count -1 }].disposalUom">
              <option value="">&nbsp;</option>
              <option ${transaction.disposalUom eq 'CA' ? 'selected' : '' } value="CA">CARTS</option>
              <option ${transaction.disposalUom eq 'EA' ? 'selected' : '' } value="EA">EACH</option>
              <option ${transaction.disposalUom eq 'GL' ? 'selected' : '' } value="GL">GALLONS</option>
              <option ${transaction.disposalUom eq 'LD' ? 'selected' : '' } value="LD">LOAD</option>
              <option ${transaction.disposalUom eq 'TN' ? 'selected' : '' } value="TN">TONS</option>
              <option ${transaction.disposalUom eq 'YD' ? 'selected' : '' } value="YD">YARDS</option>
            </select>
          </td>
          <td><input type="text" class="enterSubmittable" name="invoiceEntry[${iterStatus.count -1 }].amtInvoicedFromHauler" size=12 data-varname="amtInvoicedFromHauler" value="${transaction.amountInvoicedFromHauler }" /></td>
          <td><input type="text" class="enterSubmittable" name="invoiceEntry[${iterStatus.count -1 }].amtToBePaidToHauler" size=12 data-varname="amtToBePaidToHauler" value="${transaction.amountToBePaidToHauler }" /></td>
          <c:set value="${amountInvoicedFromHauler +  transaction.amountInvoicedFromHauler }" var="amountInvoicedFromHauler" scope="request" />
          <c:set value="${amountToBePaidToHauler +  transaction.amountToBePaidToHauler}" var="amountToBePaidToHauler" scope="request" />
          <c:if test="${multipleAccounts }">
            <td>
              <select data-varname="bulkMode" name="invoiceEntry[${iterStatus.count -1 }].bulkMode">
                <option ${transaction.bulkMode eq ' ' ? 'selected' : '' } value=" ">ADD</option>
                <option ${transaction.bulkMode eq 'UPDATE' ? 'selected' : '' } value="UPDATE">UPDATE</option>
              </select>
            </td>
            <td><input type="text" class="enterSubmittable" name="invoiceEntry[${iterStatus.count -1 }].rowIdentifier" size=12 data-varname="rowIdentifier" value="${transaction.rowIdentifier }" readonly/></td>
          </c:if>
          <td>&nbsp;</td>
        </tr>
      </c:forEach>
    </tbody>
  </table>
</form>

method for adding the record

var doSubmit = false;

function doUpdate() {
  if (doSubmit) {
    return true;
  }
  
  $('#writeTable tr').removeClass("table-danger");
  
  //reset table errors
  $('.detailInputTable tbody tr').each(function(index) {
    $(this).removeClass("table-danger");
    $(this).find('td:last').html("&nbsp;");
  });

  $.ajax({
    type: 'POST',
    url: '${requestScope['
    javax.servlet.forward.request_uri ']}/validate',
    data: $('#detailForm').serialize(),
    async: false,
    statusCode: {
      200: function(response) {
        doSubmit = true;
        postHeader();
        $('#detailForm').submit();

      },
      412: function(xhr) {
        doSubmit = false;
        var data = xhr.responseJSON;
        $.each(data, function(index, item) {
          var rowId = item.uiRowNumber;
          var errList = "<ul>";
          $.each(item.errors, function(index2, error) {
            errList += "<li>" + error.errorMessage + "</li>";
          });
          errList += "</ul>";
          var row = $('#row' + rowId);
          row.addClass('table-danger');
          var lasttd = row.find('td:last');
          lasttd.html('<em class="fa fa-exclamation-circle detailError" data-msg="' + errList + '" aria-hidden="true" style="font-size:20px"></em>');
        });
        initDetailErrors();
      }
    }
  });

  return doSubmit;
}

chaining logic

function initChainedSelect(rowNumber) {
  $("#invoiceEntry" + rowNumber + "bulkKey\.site").chained("#invoiceEntry" + rowNumber + "bulkKey\.account");
  $("#invoiceEntry" + rowNumber + "container").chained("#invoiceEntry" + rowNumber + "bulkKey\.account");
  $("#invoiceEntry" + rowNumber + "chargeType").chained("#invoiceEntry" + rowNumber + "container");
  $("#invoiceEntry" + rowNumber + "chargeCode").chained("#invoiceEntry" + rowNumber + "container, #invoiceEntry" + rowNumber + "chargeType");
}

whenever two different accounts are used to add I want only two to be added no duplicated records should obtain

Build Robust attendances system for complex dynamic shift scenario using Express & Mongodb

Question:

I’m building a robust attendance system using Express and MongoDB with Mongoose. The system has to handle a complex multi-shift setup with dynamic shift times that vary daily. Here’s a summary of the requirements and some of the challenges I’m facing:

Requirements

Dynamic Shifts:

Each department has several shifts, e.g., shift 1: 00:00-08:00, shift 2: 08:00-16:00, shift 3: 16:00-00:00.
Attendance scans can occur close to shift boundaries, which might push them to the next day or affect the prior day.

Attendance Events:

Only certain status types, like ‘presence’ and ‘holiday_presence’, have events like check_in, check_out, break_start, and break_end.
Key events (check_in and check_out) need special handling. A check_in can occur up to 2 hours before the shift, and a check_out can happen up to 14 hours after check_in.
Time Zones:

Attendance times need to be processed in Asia/Makassar timezone using moment-timezone.

Edge Cases:

Users may scan late in one day or early the next, creating overlaps.
Handling users who forget to check_out and then attempt to check_in the next day.
Validating breaks or other events, ensuring they fall within a user’s shift time.

Current Approach

Here’s the Attendance and Department schemas:

const attendanceStatus = ['presence', 'holiday_presence', 'off', 'leave', 'skd', 'service', 'leave_special', 'transport', 'holiday', 'absent']; 

const AttendancesSchema = new Schema(
  {
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Users',
      required: true,
      index: true,
    },
    date: {
      type: Date,
      default: Date.now,
      index: true,
    },
    status: {
      type: String,
      enum: attendanceStatus,
      default: 'presence',
    },
    attendance_details: {
      shift: {
        type: Number,
      },
      work_time: {
        time_in: {
          type: Date,
          required: true,
        },
        time_out: {
          type: Date,
          required: true,
        },
      },
      biometric_details: {
        unit: {
          type: Schema.Types.ObjectId,
          ref: 'Biometrics',
        },
        pin: {
          type: Number,
        },
      },
    },
    overtime_details: {
      is_overtime: {
        type: Boolean,
        default: false,
      },
      overtime_duration: {
        type: Number,
        default: 0,
        min: 0,
      },
    },
    events: [
      {
        _id: false,
        type: {
          type: String,
          enum: ['check_in', 'check_out', 'break_start', 'break_end', 'off_start', 'off_end', 'service_start', 'service_end'],
        },
        time: {
          type: Date,
        },
        note: {
          type: String,
        },
      },
    ],
    note: {
      type: String,
    },
  },
  {
    timestamps: true,
    collection: 'attendances',
  }
);


const Departments = new Schema(
  {
    name: {
      type: String,
      required: true,
      trim: true,
    },
    work_duration: {
      type: Number,
      required: true,
      default: 8,
      min: 8,
      max: 9,
    },
    half_day_duration: {
      type: Number,
      min: 1,
      max: 9,
      default: 6,
    },
    work_times: [
      {
        _id: false,
        shift: {
          type: Number,
        },
        time_in: {
          type: Date,
          required: true,
        },
      },
    ],
  },
  {
    timestamps: true,
    collection: 'departments',
  }
);

Challenges

I’m currently facing several issues that I need guidance on:

Determining Shift for Each Scan: When a scan is received, I need to:

Identify if it should be attributed to yesterday, today, or tomorrow based on shift start and end times.
Handle edge cases, such as late-night shifts that technically fall into the next calendar day.

Event Validation and Updates:

If a check_in is recorded without a check_out, and the next scan is a check_in, should I treat this as a check_out for the previous day?
How to handle events that don’t directly relate to check_in/check_out but are other events like break_start or break_end.

Timezone-Specific Calculations:

I’m using moment-timezone to manage timestamps, but handling multiple overlapping shifts across days is getting complex. Any recommended patterns for dealing with timezone-sensitive calculations for multi-day shifts?

Algorithm Approach:

What are the best practices to ensure that each scan data point is accurately assigned to the correct date, shift, and event, especially considering overlapping shifts, late-night entries, and multi-day shifts?

Current Code

const example_webhookData =  {
  "cloud_id": "XXXXXXXXXXXXX",
  "data": { 
    "pin": "24", 
    "scan": "2024-09-22 07:29:07",  
    }
}

        const deviceTimezone = 'Asia/Makassar';
        const attendanceTimeUTC = momentTz.tz(webhookData.data.scan, deviceTimezone).utc();

        const attendanceTimeUTC = momentTz.tz(webhookData.data.scan, deviceTimezone).utc();
        const attendanceTimeWITA = momentTz.tz(webhookData.data.scan, deviceTimezone);
            const isCustomTime = users.attendance_details.work_time.is_custom_time;
        const departmentWorkTimes = dataDepartment.work_times;

if (!isCustomTime && departmentWorkTimes.length > 1) {

  const shiftIndex = findValidShiftIndex(attendanceTimeUTC, attendanceTimeWITA, departmentWorkTimes);

          let { shiftTimeIn, shiftTimeInMin, shiftTimeInMax } = calculateShiftTimeIn(shiftIndex, attendanceTimeUTC, attendanceTimeWITA, departmentWorkTimes, deviceTimezone);

          let shiftTimeOut = moment.utc(calculateTimeOut(shiftTimeIn.toDate(), dataDepartment.work_duration)).seconds(0).milliseconds(0);

          // Adjust shift time out if it's a holiday or a weekend scenario
          if (
            (!users?.attendance_details?.holiday?.is_dynamic &&
              users?.attendance_details?.holiday?.week_day !== 0 &&
              momentTz.utc(attendanceTimeUTC).tz(deviceTimezone).add(1, 'days').day() === users?.attendance_details?.holiday?.week_day) ||
            (momentTz.utc(attendanceTimeUTC).tz(deviceTimezone).day() === 6 && users?.attendance_details?.holiday?.week_day === 0)
          ) {
            shiftTimeOut = shiftTimeIn
              .clone()
              .add(dataDepartment?.half_day_duration || 6, 'hours')
              .utc();
          }

          let attendanceDate = determineAttendanceDate(attendanceTimeWITA, shiftTimeIn, shiftTimeOut);


          const todayShiftStart = shiftTimeIn.clone().tz(deviceTimezone).startOf('day');
          const todayShiftEnd = shiftTimeIn.clone().tz(deviceTimezone).endOf('day');
          const prevDayStart = todayShiftStart.clone().tz(deviceTimezone).endOf('day').subtract(1, 'days');
          const prevDayEnd = todayShiftEnd.clone().tz(deviceTimezone).endOf('day').subtract(1, 'days');

          const existingYesterdayAttendance = await Attendances.findOne({
            user: users._id,
            date: { $gte: prevDayStart.toDate(), $lte: prevDayEnd.toDate() },
          });

          const existingTodayAttendance = await Attendances.findOne({
            user: users._id,
            date: { $gte: todayShiftStart.toDate(), $lte: todayShiftStart.toDate() },
          });

          if (existingYesterdayAttendance && !existingYesterdayAttendance.events.find((event) => event.type === 'check_out')) {
            const isDuplicateEvent = existingYesterdayAttendance.events.some((event) => moment(event.time).isSame(attendanceTimeUTC));
            if (isDuplicateEvent) {
              console.log('Skipping duplicate event');
              return res.status(200).end();
            }
            if (moment(attendanceTimeUTC).isSameOrAfter(yesterdayTimeWorkOut) && moment(attendanceTimeUTC).isBefore(yesterdayTimeWorkOutMax)) {
              existingYesterdayAttendance.events.push({
                type: 'check_out',
                time: attendanceTimeUTC.toDate(),
              });
              await existingYesterdayAttendance.save();
              resAttendanceEmit = existingYesterdayAttendance;
            } else if (moment(attendanceTimeUTC).isBefore(yesterdayTimeWorkOut)) {
              let attendanceType = 'check_in';
              const lastEvent = existingYesterdayAttendance.events[existingYesterdayAttendance.events.length - 1];
              if (lastEvent.type === 'check_in' && existingYesterdayAttendance.events.length === 1) {
                attendanceType = 'break_start';
              } else if (lastEvent.type.endsWith('_start') || lastEvent.type.endsWith('_end')) {
                const correspondingEvent = getAfterEventType(lastEvent.type);
                if (correspondingEvent) {
                  attendanceType = correspondingEvent;
                }
              }
              existingYesterdayAttendance.events.push({
                type: attendanceType,
                time: attendanceTimeUTC.toDate(),
              });
              await existingYesterdayAttendance.save();
              resAttendanceEmit = existingYesterdayAttendance;
            } else {
              if (existingTodayAttendance) {
                const isDuplicateEvent = existingTodayAttendance.events.some((event) => moment(event.time).isSame(attendanceTimeUTC));
                if (isDuplicateEvent) {
                  console.log('Skipping duplicate event');
                  return res.status(200).end();
                }

                if (moment(attendanceTimeUTC).isSameOrAfter(todayTimeWorkOut) && moment(attendanceTimeUTC).isSameOrBefore(todayTimeWorkOutMax)) {
                  if (!existingTodayAttendance.events.find((event) => event.type === 'check_out')) {
                    existingTodayAttendance.events.push({
                      type: 'check_out',
                      time: attendanceTimeUTC.toDate(),
                    });
                    await existingTodayAttendance.save();
                    resAttendanceEmit = existingTodayAttendance;
                  } else {
                    const errorMessage = '2.1 attempted double check_out ';
                  }
                } else if (moment(attendanceTimeUTC).isBefore(todayTimeWorkOut)) {
                  let attendanceType = 'check_in';
                  const lastEvent = existingTodayAttendance.events[existingTodayAttendance.events.length - 1];
                  if (lastEvent.type === 'check_in' && existingTodayAttendance.events.length === 1) {
                    attendanceType = 'break_start';
                  } else if (lastEvent.type.endsWith('_start') || lastEvent.type.endsWith('_end')) {
                    const correspondingEvent = getAfterEventType(lastEvent.type);
                    if (correspondingEvent) {
                      attendanceType = correspondingEvent;
                    }
                  }
                  existingTodayAttendance.events.push({
                    type: attendanceType,
                    time: attendanceTimeUTC.toDate(),
                  });
                  await existingTodayAttendance.save();
                  resAttendanceEmit = existingTodayAttendance;
                } else {

                  if (
                    moment(attendanceTimeUTC).isSameOrBefore(shiftTimeInMax) &&
                    moment(attendanceTimeUTC).isSameOrAfter(shiftTimeInMin) &&
                    !shiftTimeOut.isSameOrBefore(attendanceTimeUTC.clone().endOf('day'))
                  ) {
                    const newAttendance = new Attendances({
                      user: users._id,
                      date: attendanceDate,
                      attendance_details: {
                        shift: shiftIndex + 1,
                        work_time: {
                          time_in: shiftTimeIn.toDate(),
                          time_out: shiftTimeOut.toDate(),
                        },
                        biometric_details: {
                          unit: existingBiometric?._id,
                          pin: webhookData?.data?.pin,
                        },
                      },
                      events: [
                        {
                          type: 'check_in',
                          time: attendanceTimeUTC.toDate(),
                        },
                      ],
                    });
                    await newAttendance.save();
                    resAttendanceEmit = newAttendance;
                  } else {
                    const errorMessage = '5. attempted attendance outside valid range for today';
                  }
                }
              } else {

                const newAttendance = new Attendances({
                  user: users._id,
                  date: attendanceDate.toDate(),
                  attendance_details: {
                    shift: shiftIndex + 1,
                    work_time: {
                      time_in: shiftTimeIn.toDate(),
                      time_out: shiftTimeOut.toDate(),
                    },
                    biometric_details: {
                      unit: existingBiometric?._id,
                      pin: webhookData?.data?.pin,
                    },
                  },
                  events: [
                    {
                      type: 'check_in',
                      time: attendanceTimeUTC.toDate(),
                    },
                  ],
                });
                await newAttendance.save();
                resAttendanceEmit = newAttendance;
              }
            }
          } else if (existingTodayAttendance && !existingYesterdayAttendance) {
            const isDuplicateEvent = existingTodayAttendance.events.some((event) => moment(event.time).isSame(attendanceTimeUTC));
            if (isDuplicateEvent) {
              console.log('Skipping duplicate event');
              return res.status(200).end();
            }

            if (!existingTodayAttendance.events.find((event) => event.type === 'check_out') && !moment(attendanceTimeUTC).isAfter(todayTimeWorkOutMax)) {

              if (moment(attendanceTimeUTC).isSameOrAfter(todayTimeWorkOut) && moment(attendanceTimeUTC).isSameOrBefore(todayTimeWorkOutMax)) {
                existingTodayAttendance.events.push({
                  type: 'check_out',
                  time: attendanceTimeUTC.toDate(),
                });
                await existingTodayAttendance.save();
                resAttendanceEmit = existingTodayAttendance;
              } else if (moment(attendanceTimeUTC).isBefore(todayTimeWorkOut)) {
                let attendanceType = 'check_in';
                const lastEvent = existingTodayAttendance.events[existingTodayAttendance.events.length - 1];
                if (lastEvent.type === 'check_in' && existingTodayAttendance.events.length === 1) {
                  attendanceType = 'break_start';
                } else if (lastEvent.type.endsWith('_start') || lastEvent.type.endsWith('_end')) {
                  const correspondingEvent = getAfterEventType(lastEvent.type);
                  if (correspondingEvent) {
                    attendanceType = correspondingEvent;
                  }
                }

                existingTodayAttendance.events.push({
                  type: attendanceType,
                  time: attendanceTimeUTC.toDate(),
                });
                await existingTodayAttendance.save();
                resAttendanceEmit = existingTodayAttendance;
              } else {
                const errorMessage = '4. attempted attendance outside valid range for today';
              }
            } else {
              const errorMessage = '5. attempted attendance outside valid range for today';
            }
          } else {
            if (existingTodayAttendance) {
              const isDuplicateEvent = existingTodayAttendance.events.some((event) => moment(event.time).isSame(attendanceTimeUTC));
              if (isDuplicateEvent) {
                console.log('Skipping duplicate event');
                return res.status(200).end();
              }

              if (!existingTodayAttendance.events.find((event) => event.type === 'check_out')) {
                if (moment(attendanceTimeUTC).isSameOrAfter(todayTimeWorkOut) && moment(attendanceTimeUTC).isSameOrBefore(todayTimeWorkOutMax)) {
                  existingTodayAttendance.events.push({
                    type: 'check_out',
                    time: attendanceTimeUTC.toDate(),
                  });
                  await existingTodayAttendance.save();
                  resAttendanceEmit = existingTodayAttendance;
                } else if (moment(attendanceTimeUTC).isBefore(todayTimeWorkOut)) {
                  let attendanceType = 'check_in';
                  const lastEvent = existingTodayAttendance.events[existingTodayAttendance.events.length - 1];
                  if (lastEvent.type === 'check_in' && existingTodayAttendance.events.length === 1) {
                    attendanceType = 'break_start';
                  } else if (lastEvent.type.endsWith('_start') || lastEvent.type.endsWith('_end')) {
                    const correspondingEvent = getAfterEventType(lastEvent.type);
                    if (correspondingEvent) {
                      attendanceType = correspondingEvent;
                    }
                  }

                  existingTodayAttendance.events.push({
                    type: attendanceType,
                    time: attendanceTimeUTC.toDate(),
                  });
                  await existingTodayAttendance.save();
                  resAttendanceEmit = existingTodayAttendance;
                } else {
                  const errorMessage = '4. attempted attendance outside valid range for today';
                 
                }
              } else {

                if (
                  moment(attendanceTimeUTC).isSameOrBefore(shiftTimeInMax) &&
                  moment(attendanceTimeUTC).isSameOrAfter(shiftTimeInMin) &&
                  !moment(shiftTimeIn).isSame(momentTz.utc(existingTodayAttendance.date).clone().tz(deviceTimezone, true), 'day')
                ) {
                  const newAttendance = new Attendances({
                    user: users._id,
                    date: attendanceDate,
                    attendance_details: {
                      shift: shiftIndex + 1,
                      work_time: {
                        time_in: shiftTimeIn.toDate(),
                        time_out: shiftTimeOut.toDate(),
                      },
                      biometric_details: {
                        unit: existingBiometric?._id,
                        pin: webhookData?.data?.pin,
                      },
                    },
                    events: [
                      {
                        type: 'check_in',
                        time: attendanceTimeUTC.toDate(),
                      },
                    ],
                  });
                  await newAttendance.save();
                  resAttendanceEmit = newAttendance;
                } else {
                  const errorMessage = '6. attempted attendance outside valid range for today';
                }
              }
            } else {

              if (moment(attendanceTimeUTC).isSameOrBefore(shiftTimeInMax) && moment(attendanceTimeUTC).isSameOrAfter(shiftTimeInMin)) {
                const newAttendance = new Attendances({
                  user: users._id,
                  date: attendanceDate,
                  attendance_details: {
                    shift: shiftIndex + 1,
                    work_time: {
                      time_in: shiftTimeIn.toDate(),
                      time_out: shiftTimeOut.toDate(),
                    },
                    biometric_details: {
                      unit: existingBiometric?._id,
                      pin: webhookData?.data?.pin,
                    },
                  },
                  events: [
                    {
                      type: 'check_in',
                      time: attendanceTimeUTC.toDate(),
                    },
                  ],
                });
                await newAttendance.save();
                resAttendanceEmit = newAttendance;
              } else {
                const errorMessage = 'attempted attendance outside valid range for shift';
              }
            }
          }

}

    
const getAfterEventType = (startEventType) => {
  switch (startEventType) {
    case 'break_start':
      return 'break_end';
    case 'off_start':
      return 'off_end';
    case 'service_start':
      return 'service_end';
    case 'break_end':
    case 'service_end':
    case 'off_end':
      return 'break_start';
    default:
      return 'check_in';
  }
};

function calculateTimeOut(timeIn, workDurationHours) {
  return momentTz.tz(timeIn, 'Asia/Makassar').clone().add(workDurationHours, 'hours').toDate();
}

function findValidShiftIndex(attendanceTimeUTC, attendanceTimeWITA, departmentWorkTimes) {
  let shiftIndex = null;
  let closestTimeInDifference = Number.MAX_SAFE_INTEGER;

  for (let i = 0; i < departmentWorkTimes.length; i++) {
    const workTime = departmentWorkTimes[i];
    const shiftStart = moment.utc(workTime.time_in);

    const shiftToday = shiftStart.clone().set({
      year: attendanceTimeWITA.year(),
      month: attendanceTimeWITA.month(),
      date: attendanceTimeWITA.date(),
    });

    const shiftStartMin = shiftToday.clone().subtract(2, 'hours');
    const shiftStartMax = shiftToday.clone().add(7, 'hours');

    if (attendanceTimeUTC.isBefore(shiftToday) && attendanceTimeUTC.isAfter(shiftStartMin)) {
      shiftIndex = i;
      break;
    }
    if (attendanceTimeUTC.isBetween(shiftStartMin, shiftStartMax, null, '[]')) {
      const difference = Math.abs(attendanceTimeUTC.diff(shiftToday));
      if (difference < closestTimeInDifference) {
        closestTimeInDifference = difference;
        shiftIndex = i;
      }
    }
  }

  if (shiftIndex === null) {
    for (let i = 0; i < departmentWorkTimes.length; i++) {
      const workTime = departmentWorkTimes[i];
      const shiftStart = moment.utc(workTime.time_in).add(1, 'days');

      const shiftTomorrow = shiftStart.clone().set({
        year: attendanceTimeUTC.year(),
        month: attendanceTimeUTC.month(),
        date: attendanceTimeUTC.date(),
      });

      const shiftTomorrowMin = shiftTomorrow.clone().subtract(2, 'hours');
      const shiftTomorrowMax = shiftTomorrow.clone().add(7, 'hours');

      if (attendanceTimeUTC.isBetween(shiftTomorrowMin, shiftTomorrowMax, null, '[]')) {
        const difference = Math.abs(attendanceTimeUTC.diff(shiftTomorrow));
        if (difference < closestTimeInDifference) {
          closestTimeInDifference = difference;
          shiftIndex = i;
        }
      }
    }
  }

  return shiftIndex;
}

function calculateShiftTimeIn(shiftIndex, attendanceTimeUTC, attendanceTimeWITA, departmentWorkTimes, deviceTimezone) {
  const shiftTimeInUTC = moment.utc(departmentWorkTimes[shiftIndex].time_in);

  let shiftTimeIn = attendanceTimeWITA.clone();

  shiftTimeIn.hours(shiftTimeInUTC.tz(deviceTimezone).hours());
  shiftTimeIn.minutes(shiftTimeInUTC.tz(deviceTimezone).minutes());
  shiftTimeIn.seconds(0);
  shiftTimeIn.milliseconds(0);

  if (shiftTimeIn.isBefore(attendanceTimeWITA)) {
    const hoursDifference = attendanceTimeWITA.diff(shiftTimeIn, 'hours');
    if (hoursDifference >= 12) {
      shiftTimeIn.add(1, 'days');
    }
  } else {
    const hoursDifference = shiftTimeIn.diff(attendanceTimeWITA, 'hours');
    if (hoursDifference >= 12) {
      shiftTimeIn.subtract(1, 'days');
    }
  }

  const shiftTimeInMin = shiftTimeIn.clone().subtract(2, 'hours');
  const shiftTimeInMax = shiftTimeIn.clone().add(7, 'hours');

  return { shiftTimeIn, shiftTimeInMin, shiftTimeInMax };
}

function determineAttendanceDate(attendanceTimeWITA, shiftTimeInUTC, shiftTimeOutUTC) {
  let attendanceDate;
  let shiftTimeIn = momentTz.utc(shiftTimeInUTC).clone().tz('Asia/Makassar');
  let shiftTimeOut = momentTz.utc(shiftTimeOutUTC).clone().tz('Asia/Makassar');

  if (attendanceTimeWITA.isBefore(shiftTimeIn) && shiftTimeIn.isAfter(attendanceTimeWITA.clone().add(1, 'day').startOf('day'))) {
    attendanceDate = attendanceTimeWITA.clone().add(1, 'day').startOf('day');
  } else if (attendanceTimeWITA.isAfter(shiftTimeIn) && shiftTimeIn.isSame(attendanceTimeWITA.clone().startOf('day'))) {
    attendanceDate = attendanceTimeWITA.clone().startOf('day');
  } else if (
    attendanceTimeWITA.isBefore(shiftTimeIn) &&
    shiftTimeIn.isBefore(attendanceTimeWITA.clone().add(1, 'day').endOf('day')) &&
    !shiftTimeOut.isSameOrBefore(attendanceTimeWITA.clone().endOf('day'))
  ) {
    attendanceDate = attendanceTimeWITA.clone().add(1, 'day').startOf('day');
  } else if (attendanceTimeWITA.isAfter(shiftTimeIn) && shiftTimeIn.isBefore(attendanceTimeWITA.clone().subtract(1, 'day').endOf('day'))) {
    attendanceDate = attendanceTimeWITA.clone().startOf('day');
  } else if (attendanceTimeWITA.isAfter(shiftTimeIn) && shiftTimeIn.isBefore(attendanceTimeWITA.clone().endOf('day'))) {
    // attendanceDate = attendanceTimeWITA.clone().add(1, 'day').startOf('day');
    attendanceDate = attendanceTimeWITA.clone().startOf('day');
  } else {
    attendanceDate = attendanceTimeWITA.clone().startOf('day');
  }
  return attendanceDate;
}

I know my current code has issues with duplication and lacks clarity, but at least help me improve its robustness and functionality while still maintaining a working solution.

How to implement real-time updates in Editor.js using Pusher?

I am currently working on integrating real-time capabilities into an Editor.js instance in a TypeScript project. My goal is to ensure that any changes made to blocks (like adding, deleting, or updating) are reflected instantly across different devices connected to the site without requiring user authentication.

here is the source code of editorjs: https://github.com/codex-team/editor.js

I should configure the event listeners but on DOM i don’t know if there anyone for help and thanks.

“toggle” files to download as a zip folder

There’s a website called Vanilla Tweaks (https://vanillatweaks.net/picker/resource-packs/) where you can choose features which are then put into a zip file which you can download. I was trying to recreate this feature with basic java script but can’t seem to find anything helpful.

I looked it up online but could barely find anything. The only thing that seemed to help was JSZip but i’m not quite sure if it is possible to use it with folders inside of the zip file

Image Upload to DigitalOcean Spaces is not working

I’ve been tackling this for the last 8 hours to no avail. Everything seems to be uploading to my DigitalOcean Spaces bucket just fine. However, when I copy the CDN url, I just get the “corrupted image” square (see below). The file sizes within DigitalOcean shows the correct size of the uploaded image. I’m using express, express-fileupload, and aws-sdk/client-s3.

Here is my config:

const config = {
  endpoint: "https://sfo3.digitaloceanspaces.com",
  region: "us-west-1",
  credentials: {
    accessKeyId: process.env.DIGITAL_OCEAN_ACCESS_KEY,
    secretAccessKey: process.env.DIGITAL_OCEAN_SECRET_KEY,
  },
};
const client = new S3Client(config);

Here is my upload code – I receive the file from my front end:

module.exports.testFileUpload = async (req, res, next) => {
  console.log(req.files.profilePicture.data); // Returns the buffer
  console.log(typeof req.files.profilePicture.data); // Returns object
  const input = {
    Body: req.files.profilePicture.data,
    Bucket: "my-bucket-name",
    Key: `userProfiles/${req.files.profilePicture.name}`,
    ACL: "public-read",
    ContentType: req.files.profilePicture.mimetype,
  };
  try {
    const command = new PutObjectCommand(input);
    const response = await client.send(command);
    console.log("response", response); // I receive a response with a 200 status code
  } catch (err) {
    console.log(err); // I'm not getting an error
  }
};

This is what I get when I enter the CDN url into my browser

I originally started this project with Cloudinary and it worked just fine. I want to switch to DigitalOcean because of the large storage space at a low cost. If anyone has any ideas, it would be greatly appreciated :’)

I feel like I’ve included all of the necessary bits of information, but please let me know if you feel I’m missing any key parts to help figure out what’s going on.

Invariant Violation:new NativeEventEmitter() requires a non-null argument., js engine: hermes

I am creating a mobile application for Android and ios using react-native
this app shows customers’ product
and can create accounts using Facebook and Google, I use Firebase to create accounts and save data
when running the application in an Android emulator works with no error
but when running using the simulator for ios shows me this error:-

ERROR Invariant Violation: new NativeEventEmitter() requires a
non-null argument., js engine: hermes LOG Running “ShoofMangment”
with {“rootTag”:1,”initialProps”:{“concurrentRoot”:false}} ERROR
Invariant Violation: “ShoofMangment” has not been registered. This can
happen if:

  • Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
  • A module failed to load due to an error and AppRegistry.registerComponent wasn’t called., js engine: hermes info
    Stopping server

I using to npx react-native start --reset-cache
and using to pod install
and I using this library in my project

 "@firebase/app": "^0.10.15",
"@firebase/component": "^0.6.10",
"@firebase/logger": "^0.4.3",
"@firebase/util": "^1.10.1",
"@invertase/react-native-apple-authentication": "^2.4.0",
"@react-native-async-storage/async-storage": "^2.0.0",
"@react-native-community/cli": "^15.0.0",
"@react-native-community/datetimepicker": "^8.2.0",
"@react-native-firebase/app": "^20.5.0",
"@react-native-firebase/auth": "^20.5.0",
"@react-native-firebase/database": "^20.5.0",
"@react-native-firebase/firestore": "^20.5.0",
"@react-native-firebase/storage": "^20.5.0",
"@react-native-google-signin/google-signin": "latest",
"@react-navigation/native": "^6.1.18",
"@react-navigation/stack": "^6.4.1",
"firebase": "9.6.1",
"i18next": "^23.15.1",
"react": "18.3.1",
"react-i18next": "^15.0.1",
"react-native": "^0.75.3",
"react-native-animatable": "^1.4.0",
"react-native-collapsible": "^1.6.2",
"react-native-elements": "^3.4.3",
"react-native-fbsdk-next": "^13.0.0",
"react-native-geolocation-service": "^5.3.1",
"react-native-gesture-handler": "^2.19.0",
"react-native-image-picker": "^7.1.2",
"react-native-linear-gradient": "^2.8.3",
"react-native-localize": "^3.2.1",
"react-native-maps": "^1.15.6",
"react-native-permissions": "^4.1.5",
"react-native-qrcode-scanner": "^1.5.5",
"react-native-safe-area-context": "^4.11.0",
"react-native-screens": "^3.34.0",
"react-native-share": "^11.0.4",
"react-native-swiper": "^1.6.0",
"react-native-vector-icons": "^10.2.0",
"react-native-video": "^6.6.4"

enter image description here

and this is my App.js file code

import React, {useEffect, useState} from 'react';
import {NavigationContainer} from '@react-navigation/native';
import AppNavigator from './src/navigation/AppNavigator';
import './assets/i18n';
import {Settings} from 'react-native-fbsdk-next';
import auth from '@react-native-firebase/auth';
import firebase from '@react-native-firebase/app';

import AsyncStorage from '@react-native-async-storage/async-storage';
import {ActivityIndicator, View} from 'react-native';
import {BottomNavigationProvider} from './src/navigation/BottomNavigationContext'; // 
استيراد المزود

export default function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [initialRoute, setInitialRoute] = useState('LoginScreen'); // تحديد الشاشة 
الافتراضية

 useEffect(() => {
// تهيئة Facebook SDK
Settings.initializeSDK();

// التحقق من حالة تسجيل الدخول باستخدام AsyncStorage و Firebase Auth
const checkLoginStatus = async () => {
  try {
    const userInfo = await AsyncStorage.getItem('user');
    console.log('userInfo data from AsyncStorage:', userInfo);

    if (userInfo) {
      console.log('Navigating to DashboardScreen');

      // إذا كان userInfo موجودًا في AsyncStorage، توجيه المستخدم إلى Dashboard
      setInitialRoute('DashboardScreen');
      setIsLoading(false);
    } else {
      console.log('Firebase User Logged in:');

      // استخدام Firebase Auth للتحقق من حالة المستخدم
      auth().onAuthStateChanged(user => {
        if (user) {
          // المستخدم مسجل دخول
          setInitialRoute('DashboardScreen');
        } else {
          console.log('No user logged in, navigating to SplashScreen');

          // المستخدم غير مسجل دخول
          setInitialRoute('SplashScreen');
        }
        setIsLoading(false);
      });
    }
  } catch (error) {
    console.error('Error checking login status:', error);
    setIsLoading(false);
    setInitialRoute('SplashScreen');
  }
};
checkLoginStatus();
  }, []);



 if (isLoading) {
    return (
      <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
        <ActivityIndicator size="large" color="#0000ff" />
      </View>
    );
  }
  return (
    <BottomNavigationProvider>
      {/* تغليف المزود هنا */}
      <NavigationContainer>
        <AppNavigator initialRoute={initialRoute} />
      </NavigationContainer>
    </BottomNavigationProvider>
  );
}

Should I store the access and refresh tokens in cookies?

In my application, when the user logs in successfully, I generate the access and refresh tokens using JWT and store both in cookies. This seems correct to me because cookies add more security than local storage (by using HTTP only).

The problem is that both tokens are sent with every request. Theoretically, I should only send the refresh token when the access token has expired. Am I approaching this incorrectly?

The only solution I can think of is to store the access token in local storage and the refresh token in cookies (because it needs more security) , but I’m not entirely convinced by that. I am using Express and React. Is there something I haven’t understood?

Thank you in advance.

Getting error: Uncaught TypeError: this.state.session.reject is not a function

Getting an error while trying to cancel the call but cannot cancel it as I’m getting error each time when I click the button in console. Error:

Uncaught TypeError: this.state.session.reject is not a function
    at Phone.clickEndCallButton (Phone.js:238:28)
    at onClick (Phone.js:413:35)
    at HTMLUnknownElement.callCallback (react-dom.development.js:1299:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:1338:16)
    at Object.invokeGuardedCallback (react-dom.development.js:1195:27)
    at Object.invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:1209:43)
    at executeDispatch (react-dom.development.js:1432:21)
    at Object.executeDispatchesInOrder (react-dom.development.js:1454:5)
    at executeDispatchesAndRelease (react-dom.development.js:1969:24)
    at executeDispatchesAndReleaseTopLevel (react-dom.development.js:1980:10)
clickEndCallButton @ Phone.js:238
onClick @ Phone.js:413
callCallback @ react-dom.development.js:1299
invokeGuardedCallbackDev @ react-dom.development.js:1338
invokeGuardedCallback @ react-dom.development.js:1195
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:1209
executeDispatch @ react-dom.development.js:1432
executeDispatchesInOrder @ react-dom.development.js:1454
executeDispatchesAndRelease @ react-dom.development.js:1969
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:1980
forEachAccumulated @ react-dom.development.js:1946
processEventQueue @ react-dom.development.js:2139
runEventQueueInBatch @ react-dom.development.js:2151
handleTopLevel @ react-dom.development.js:2161
handleTopLevelImpl @ react-dom.development.js:1800
batchedUpdates @ react-dom.development.js:13238
performFiberBatchedUpdates @ react-dom.development.js:1646
stackBatchedUpdates @ react-dom.development.js:1637
batchedUpdates @ react-dom.development.js:1651
batchedUpdatesWithControlledComponents @ react-dom.development.js:1664
dispatchEvent @ react-dom.development.js:1874
Show 19 more frames
Show lessUnderstand this errorAI
react-dom.development.js:1345 Uncaught Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development.
    at Object.invokeGuardedCallbackDev (react-dom.development.js:1345:19)
    at Object.invokeGuardedCallback (react-dom.development.js:1195:27)
    at Object.invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:1209:43)
    at executeDispatch (react-dom.development.js:1432:21)
    at Object.executeDispatchesInOrder (react-dom.development.js:1454:5)
    at executeDispatchesAndRelease (react-dom.development.js:1969:24)
    at executeDispatchesAndReleaseTopLevel (react-dom.development.js:1980:10)
    at Array.forEach (<anonymous>)
    at forEachAccumulated (react-dom.development.js:1946:9)
    at Object.processEventQueue (react-dom.development.js:2139:7)

I tried to log it to the console as I have seen it might be because of session is empty but it is not.

MatRadioGroupComp warning in console

I have this piece of HTML in my project of angular:

<th2-mat-radio-group
    [radioButtonList]="isOneWayRadioButtons"
    [form]="typeSettingForm"
    formControlFieldName="isOneWay"
    [required]="false"
    name="isOneWay">
</th2-mat-radio-group>

but I keep getting this warning in the console even though I’m not using the disabled attribute here. If I delete the [form] part the warning disappears but the form stops working.

Th2MatRadioGroupComponent.ngfactory.js:212
It looks like you’re using the disabled attribute with a reactive form directive. If you set disabled to true
when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
you. We recommend using this approach to avoid ‘changed after checked’ errors.
Example:

      form = new FormGroup({
        first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
        last: new FormControl('Drew', Validators.required)
      });

I have this in my settings-form.ts:

isOneWay: new FormControl({ value: false, disabled: true }, []),

How can I delete this warning and keep the buttons functional? Thank you so much.

I want to delete de warning from the console but keep having the form working correct.

How to extract link of iframe from a page after automating click

I’m trying to extract links of iframe in a webpage it has a section with class
This class a section of video source.

.list-box

After clicking the videos which are in this class it loads the video dynamically without refreshing the page. I tried to automate the click using JS and it didn’t give me links which I tried to achieve using JS. I tried clicking the element with class .list-box every 2 second but it failed giving me the links of iframe.
At first there is video 1 so video 1 has an iframe which is Current video URL, here it does give me the link of the current iframe so there is video 2 which needs to be clicked everytime in order to get the iframe src so for that I tried automating the click but it only give me the link of the Current Video but I want to get the link of every video element which are present.

Here is my JS code

const currentVideoIframe = document.querySelector('iframe');

if (currentVideoIframe) {
    console.log('Current url', currentVideoIframe.src);
} else {
    console.log('Nothing');
}

// The main element 
const videoContainer = document.querySelector(".list-box");

const clickElementEvery2Seconds = () => {
    const listBox = document.getElementsByClassName("list-box")[0];
    if (listBox) {
        listBox.click(); // Initiate click on the list box

        // Wait 2 seconds after the click to process iframes
        setTimeout(() => {
            if (videoContainer) {
                const videoIframes = videoContainer.querySelectorAll('iframe');
                videoIframes.forEach((iframe, index) => {
                    const videoUrl = iframe.src;
                    console.log(`Links ${index + 1}: ${videoUrl}`);
                });
            } else {
                console.log('Nothing');
            }
        }, 2000); // 2 seconds

    } else {
        console.log("Element not found");
    }
};

setInterval(clickElementEvery2Seconds, 5000);

Thank You for your time. I hope for a help.

TypeError: s.Connection is not a constructor Error in Production Mode in Next.js 15 with jsforce

I’m trying to connect my Next.js 15 app to Salesforce APIs using the jsforce library. This code works perfectly fine in development mode (npm run dev) and during the build process (npm run build). However, after building, when I start the server with npm start and run this code, I get an error immediately after logging creating connection:

TypeError: s.Connection is not a constructor

Here’s the whole code:

import * as jsforce from "jsforce";



const createSalesforceConnection = async () => {
  console.log("creating connection");
  const conn = new jsforce.Connection({
    loginUrl: process.env.SFDC_SANDBOX_LOGIN_URL!,
  });

  console.log("connection created");

  await conn.login(process.env.SFDC_USERNAME!, process.env.SFDC_PASSWORD!);

  console.log("conn");
  console.log(conn);

  return conn;
};

declare const globalThis: {
  salesforceGlobal: ReturnType<typeof createSalesforceConnection>;
} & typeof global;

const salesforceClient = async () => {
  console.log("sfdc global");
  console.log(globalThis.salesforceGlobal);
  return globalThis.salesforceGlobal ?? createSalesforceConnection();
};

export default salesforceClient;

I also tried importing jsforce using this approach, but the result was the same:

import jsforce from "jsforce";

I’ve double-checked that the environment variable SFDC_SANDBOX_LOGIN_URL is set correctly in production. The jsforce library also works fine during development, but in production mode, Connection is somehow no longer recognized as a constructor.

Why does this issue happen only in production mode, and how can I fix it so that the jsforce.Connection works in production?

How to hide asp combobox according to selected asp combobox by javascript in asp.net

I have two asp combobox one with the name of cmb_stocktype while second with the name of cmb_tagno. Now, my question is that when I select cmb_stocktype with the value of WithStock then cmb_tagno should be show else it should be hide by javascript.

Here is my following code,

<asp:DropDownList CssClass="form-control" id="cmb_stocktype" runat="server">
    <asp:ListItem Value="WithStock">WITH STOCK</asp:ListItem>
    <asp:ListItem Value="WithoutStock">WITHOUT STOCK</asp:ListItem>
</asp:DropDownList>                                    

<asp:DropDownList ID="cmb_tagno" runat="server" Style="width:90%;" CssClass="form-control" ClientIDMode="Static" ></asp:DropDownList>

$("#<%= cmb_stocktype.ClientID %>").change(function () {
    if ($("#<%= cmb_stocktype.ClientID %>").val() == "WithStock") {
        $("#<%=cmb_tagno.ClientID%>").show()
    }
    else {
        $("#<%=cmb_tagno.ClientID%>").hide()
    }
});

I used style.display and style.visibility still didn’t work.