Show warning pop up when page reload/refresh in ios safari/crome browser

window.addEventListener('beforeunload', function (e) {
     const thankYouVisible = document.querySelector('.thank-you')?.offsetParent !== null;
        if (!thankYouVisible) {
           const confirmationMessage = "Are you sure you want to leave this page? Your 
 progress may be lost.";
          e.preventDefault();
          e.returnValue = confirmationMessage;
          return confirmationMessage;
        }
     });

Above code is working code for Desktop

Now below code is for ios safari/crome

Now issue is that first code for desktop is working fine for desktop But now case of ios/android it is not working so I have put below code

  window.addEventListener('pagehide', () => {
    const thankYouVisible = document.querySelector('.thank-you')?.offsetParent !== null;
     if (!thankYouVisible) {
       localStorage.setItem('triedToLeave', '1');
     }
   });

    window.addEventListener('DOMContentLoaded', () => {
    if (localStorage.getItem('triedToLeave') === '1') {
        localStorage.removeItem('triedToLeave');
        const shouldRefresh = confirm('It looks like you tried to leave the page. Do you want to refresh?');

      if (shouldRefresh) {
         location.reload(); // Refresh only if user clicks "OK"
      }
    }
  });

Now the code is working — the warning popup appears with Yes/No options. But the page refreshes before the popup is shown, so if I click No, it doesn’t work because the page has already reloaded.

I’m working on a quiz where the user answers questions. If the user tries to reload the page in the middle of the quiz, a warning popup appears saying: “Are you sure you want to reload the page? Your data may be lost.” This works fine on desktop browsers, but it does not work on iPhone in Chrome or Safari.

Tree structure display in React [closed]

I need to render the following on a React app . There are only two groups possible with a max 3 items in each group and the first box is creator information.

I have not filled the other two items in GroupA in the snapshot as it follows same format as item1. How do I create this structure with the lines connecting from creator to groups in JSX and render the UI? All the circles would be light grey and individual box background in light blue enter image description here

 {
     Creator : "Andy Bi",
     CreatedDate : "02/02/2025",
     CreatorInitials : "AB"
     GroupA : [
      { id: 1,
        Name : "Jam Bin",
        Initials : "JB"
        Date : "01/01/2015"
       },
       { id: 2,
        Name : "Jim Frog",
        Initials : "JF",
        Date : "03/01/2022"
       },
       {
        id : 3,
        Name : "Alex Xin",
        Initials : "AX",
        Date : 04/02/2023"
       }
      ],
      GroupB : [
      {
        id : 1,
        Name : "Zim Pin",
        Initials : "ZP",
        Date : 04/02/2023"
       },
       {
        id : 2,
        Name : "Am Bek",
        Initials : "AB",
        Date : 04/06/2022"
       },
     ]

How to inspect and locate the date picker field in the mobile application, when the application use another library (react-native-date-picker)

I am trying to handle the date picker field in android mobile application, but the application use the date picker i.e react-native-date-picker and this is the another library used in the application and I am not able to locate the date month year in the source code/DOM. so how can i handle the date picker field when the application use react-native-date-picker.

enter image description here

Userscripting and Manifest V3: Possible Solution?

I’ve been thinking about how we could reconcile userscripting with Manifest V3. In my opinion, userscripting is a really useful tool that has effectively become restricted by the new Manifest V3 rules.

An interesting idea came to my mind, and I would like to discuss it with you because I have limited experience and can’t fully judge whether it would work or not.

Here’s the idea: since we can’t legally use a single extension to run multiple scripts on different domains, why not create an extension that dynamically generates new extensions containing the user’s script?

For example:
Old way (Manifest V2): A user writes some code, specifies the target sites, and loads it New way (Manifest V3): A user writes some code and specifies the target sites inside a ‘Generator’ extension, which then creates a fully functional extension file. The user installs this generated extension themselves and gets the same functionality as before.

What do you think about this approach?

Stop automatic scroll to top when page loads

I am using the Bootstrapmade.com’s Impact web template:
https://bootstrapmade.com/demo/Impact/

The problem with this Bootstrap web template is the page is automatically being scrolled to the top every time page is refreshed/reloaded.

Steps to reproduce:

  1. Download the template
  2. Open it in a web browser
  3. Scroll down to a few thousands pixels
  4. Refresh/reload the page using the browser’s Refresh button or F5 or Ctrl+R.

Expected output:
The page should refresh/reload and scroll to the same Y position as before.

What is happening instead:
The page is always scrolled to top after a refresh/reload.

I have tried removing some unnecessary code from assets/js/main.js, and the current code is as below:

/**
* Template Name: Impact - v1.1.0
* Template URL: https://bootstrapmade.com/impact-bootstrap-business-website-template/
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
*/

document.addEventListener('DOMContentLoaded', () => {
  "use strict";

  /**
   * Sticky Header on Scroll
   */
  const selectHeader = document.querySelector('#header');

  if (selectHeader) {
    let headerOffset = selectHeader.offsetTop;
    let nextElement = selectHeader.nextElementSibling;

    const headerFixed = () => {
      if ((headerOffset - window.scrollY) <= 0) {
        selectHeader.classList.add('sticked');
       
        if (nextElement)
          nextElement.classList.add('sticked-header-offset');
      } else {
        selectHeader.classList.remove('sticked');

        if (nextElement)
          nextElement.classList.remove('sticked-header-offset');
      }
    }

    window.addEventListener('load', headerFixed);
    document.addEventListener('scroll', headerFixed);
  }

  /**
   * Navbar links active state on scroll
   */
  let navbarlinks = document.querySelectorAll('#navbar a');

  function navbarlinksActive() {
    navbarlinks.forEach(navbarlink => {
      if (!navbarlink.hash)
        return;

      let section = document.querySelector(navbarlink.hash);
      if (!section)
        return;

      let position = window.scrollY + 200;

      if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) {
        navbarlink.classList.add('active');
      } else {
        navbarlink.classList.remove('active');
      }
    })
  }

  window.addEventListener('load', navbarlinksActive);
  document.addEventListener('scroll', navbarlinksActive);

  /**
   * Mobile nav toggle
   */
  const mobileNavShow = document.querySelector('.mobile-nav-show');
  const mobileNavHide = document.querySelector('.mobile-nav-hide');

  document.querySelectorAll('.mobile-nav-toggle').forEach(el => {
    el.addEventListener('click', function(event) {
      event.preventDefault();
      mobileNavToogle();
    })
  });

  function mobileNavToogle() {
    document.querySelector('body').classList.toggle('mobile-nav-active');
    mobileNavShow.classList.toggle('d-none');
    mobileNavHide.classList.toggle('d-none');
  }

  /**
   * Hide mobile nav on same-page/hash links
   */
  document.querySelectorAll('#navbar a').forEach(navbarlink => {
    if (!navbarlink.hash)
      return;

    let section = document.querySelector(navbarlink.hash);
    if (!section)
      return;

    navbarlink.addEventListener('click', () => {
      if (document.querySelector('.mobile-nav-active')) {
        mobileNavToogle();
      }
    });
  });

  /**
   * Toggle mobile nav dropdowns
   */
  const navDropdowns = document.querySelectorAll('.navbar .dropdown > a');

  navDropdowns.forEach(el => {
    el.addEventListener('click', function(event) {
      if (document.querySelector('.mobile-nav-active')) {
        event.preventDefault();
        this.classList.toggle('active');
        this.nextElementSibling.classList.toggle('dropdown-active');

        let dropDownIndicator = this.querySelector('.dropdown-indicator');
        dropDownIndicator.classList.toggle('bi-chevron-up');
        dropDownIndicator.classList.toggle('bi-chevron-down');
      }
    })
  });

  /**
   * Scroll top button
   */
  const scrollTop = document.querySelector('.scroll-top');

  if (scrollTop) {
    const toggleScrollTop = function() {
      window.scrollY > 100 ? scrollTop.classList.add('active') : scrollTop.classList.remove('active');
    }

    window.addEventListener('load', toggleScrollTop);
    document.addEventListener('scroll', toggleScrollTop);

    scrollTop.addEventListener('click', window.scrollTo({
      top: 0,
      behavior: 'smooth'
    }));
  }
});

There doesn’t seem any code in main.js which is doing this. Can anybody tell me how to stop scroll-to-top on page refresh/reload?

TypeError: (0 , _reactDom.render) is not a function

I’m new to React, so I started with the official tutorial, a tic-tac-toe game. I made some modifications to it, including adding a timestamp to the screen. Now I want to add tests.

I created a file src/tests/Timestamp.test.js which contains this:

import React from 'react';
import {render} from 'react-dom';
import Timestamp from '../components/Timestamp'

describe('Timestamp', () => {
  render(<Timestamp />);
});

When I run npm test I get the error:

  ● Test suite failed to run

    TypeError: (0 , _reactDom.render) is not a function

      4 |
      5 | describe('Timestamp', () => {
    > 6 |   render(<Timestamp />);
        |         ^
      7 | });
      8 |
      9 |

      at src/tests/Timestamp.test.js:6:9
      at Object.<anonymous> (src/tests/Timestamp.test.js:5:1)

Does this mean my import of the render() function is not working? Or am I applying it incorrectly? I’ve played around with other means of importing and with the rendering of other things, but so far I have not discovered a way to make a working test.

What does empty parentheses in the arrow function mean? [duplicate]

  <p><button>Click me</button>
    </p>
  <p>No handler here.</p>
  <script>
    let para = document.querySelector("p");
    let button = document.querySelector("Button");
    para.addEventListener("mousedown", () => {
      console.log("Handler for paragraph.");

I still don’t get why we used empty parentheses inside the arrow function as a parameter
, what do we use it for?

I just want to know what do we use empty parentheses for.

Worker + OffscreenCanvas synchronization problems

With Javascript, I want to render heavy vector graphics. Upon zoom, the whole content should be re-rendered. To achieve it in a visually smooth way, I tried 3 solutions with Web Workers:

Two UI canvases with transferControlToOffscreen()

The canvases are: the current (visible) and the pending (invisible) ones. When the transformation is changed, I immediately apply some CSS transformations on the current canvas (it works very fast and ensures smooth UI interaction), while the pending one is re-rendered in a worker. Once it’s rendered, I send a message from the worker that the new version is ready. Once this message is received, I swap the visible and the pending canvases and set the new positions.

The problem is that I intuitively expected the placeholder content to be really rendered before I send the “frame rendered” message to the UI. Because after drawing some lines, I can already e.g. check the new pixel color in the very same tick which, for me, means that it’s rendered. But sometimes, apparently, it’s not. The new CSS is applied and the new canvas becomes visible earlier than the actual content arrives which looks terrible for the user. I guess commit() was something to help here, but it’s for some reason deprecated and mostly not supported anymore. Skipping sending of the “frame rendered” message by 1 frame with requestAnimationFrame() doesn’t solve the issue. It’s frustrating that this intuitive approach doesn’t work because it would be very fast in practice.

This is a simplified example: with many random lines, I generate a square of random size. But with a CSS scale, visually, this square should always stay the same: https://i.imgur.com/YqFQdB2.mp4 (warning: a lot of flickering). Unless the rendering is not synchronized which indeed happens sometimes, the best way to trigger it is to start resizing the window: https://i.imgur.com/ajmnSiD.mp4 (warning: even more flickering).

I also display the current frame number on the canvas and in a <p>, and ideally, the one in the <p> should never exceed the one in the canvas, but it’s visible with a slow-mo that sometimes <p> is updated earlier than the canvas thus having a higher number inside.

<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        canvas {
            width: 400px;
            height: 400px;
            transform-origin: 0 0;
        }
        p {
            font-size: 140px;
            position: absolute;
            top: 310px;
        }
    </style>
</head>
<body>
<canvas id="canvasA" width="3200" height="3200"></canvas>
<canvas id="canvasB" width="3200" height="3200" style="display: none"></canvas>
<p id="currentFrame">0</p>

<script type="module">
    const canvasA = document.getElementById('canvasA');
    const canvasB = document.getElementById('canvasB');

    const worker = new Worker('worker.js', { type: 'module' });
    const offscreenA = canvasA.transferControlToOffscreen();
    const offscreenB = canvasB.transferControlToOffscreen();

    worker.postMessage({ type: 'init', canvases: [offscreenA, offscreenB] }, [offscreenA, offscreenB]);

    worker.onmessage = (e) => {
        document.getElementById("currentFrame").innerText = e.data.counter.toString();
        let visibleCanvas;
        if (e.data.counter % 2 === 0) {
            visibleCanvas = canvasA;
            canvasB.style.setProperty("display", "none");
        } else {
            visibleCanvas = canvasB;
            canvasA.style.setProperty("display", "none");
        }
        visibleCanvas.style.setProperty("display", "block");
        const scale = 3200 / e.data.size;
        visibleCanvas.style.transform = `scale(${scale})`;
        requestAnimationFrame(() => worker.postMessage({ type: 'renderNext' }));
    };
</script>
</body>
</html>

worker.js:

let canvases;
let ctxs;
let counter = 0;
const defaultSize = 3200;
let size = defaultSize;

onmessage = (e) => {
    if (e.data.type === 'init') {
        canvases = e.data.canvases;
        ctxs = canvases.map(c => c.getContext('2d'));
        renderNext();
    }
    if (e.data.type === 'renderNext') {
        renderNext();
    }
};

function renderNext() {
    const ctx = ctxs[counter % 2];
    ctx.strokeStyle = "#00000092";
    ctx.clearRect(0, 0, defaultSize, defaultSize);
    size = 2 + Math.random() * (defaultSize - 2);
    for (let i = 0; i < 5000; i++) {
        ctx.beginPath();
        ctx.moveTo(Math.random() * size, Math.random() * size);
        ctx.lineTo(Math.random() * size, Math.random() * size);
        ctx.stroke();
    }
    ctx.fillStyle = "white";
    ctx.font = `bold ${size / 4}px sans-serif`;
    ctx.fillText(counter.toString(), 0, size / 4);
    const cnt = counter
    requestAnimationFrame(() => {
        postMessage({
            type: 'rendered',
            counter: cnt,
            size: size,
        })
    });
    counter++;
}

One bitmaprenderer UI canvas, one OffscreenCanvas inside the worker

I render everything in the worker, apply createImageBitmap or transferToImageBitmap() on it, and send the bitmap with the “frame rendered” message to the main thread to render it on the UI canvas with transferFromImageBitmap() and apply the new styles simultaneously. It seems to draw the lines, send the bitmap and show the bitmap in UI pretty fast. But transferToImageBitmap() is not only slow, but it stops the UI thread when being called in the background. How come? This approach would also be totally fine if the UI didn’t have this strange lag caused by something happening in a separate thread. It’s okay for me to wait for 0.5-2 seconds before rerendering, I just don’t want to interrupt the UI responsiveness.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Offscreen Canvas Test</title>
    <style>
        canvas {
            width: 400px;
            height: 400px;
            transform-origin: 0 0;
            transform: translateZ(0);
        }
        p {
            font-size: 140px;
            position: absolute;
            top: 310px;
        }
        #flying-div {
            position: absolute;
            top: 600px;
            width: 10px;
            height: 10px;
            background-color: mediumaquamarine;
        }
    </style>
</head>
<body>
<canvas id="canvasA" width="3200" height="3200"></canvas>
<p id="currentFrame">0</p>
<div id="flying-div"> </div>

<script type="module">
    const canvasA = document.getElementById('canvasA');

    // Send offscreen to worker
    const worker = new Worker('worker.js', { type: 'module' });

    worker.postMessage({ type: 'renderNext' });

    const ctx = canvasA.getContext('bitmaprenderer');

    worker.onmessage = (e) => {
        if (e.data.type === 'noRender') {
            requestAnimationFrame(() => worker.postMessage({ type: 'renderNext' }));
            return;
        }
        document.getElementById("currentFrame").innerText = e.data.counter.toString();
        ctx.transferFromImageBitmap(e.data.bitmap);
        const scale = 3200 / e.data.size;
        canvasA.style.transform = `scale(${scale})`;
        requestAnimationFrame(() => worker.postMessage({ type: 'renderNext' }));
    };

    const flyingDiv = document.getElementById("flying-div");
    let pos = 0;
    setDivPos();
    function setDivPos() {
        flyingDiv.style.left = `${pos}px`;
        pos += 2;
        if (pos > 500) {
            pos = 0;
        }
        requestAnimationFrame(setDivPos);
    }
</script>
</body>
</html>

worker.js:

let counter = 0;
const defaultSize = 3200;
const canvas = new OffscreenCanvas(defaultSize, defaultSize);
const ctx = canvas.getContext('2d', {willReadFrequently: false});

let size = defaultSize;

onmessage = (e) => {
    if (e.data.type === 'renderNext') {
        queueMicrotask(renderNext)
    }
};

function renderNext() {
    ctx.strokeStyle = "#00000002";
    ctx.clearRect(0, 0, defaultSize, defaultSize);
    size = 10 + Math.random() * (defaultSize - 10);
    for (let i = 0; i < 500000; i++) {
        ctx.beginPath();
        ctx.moveTo(Math.random() * size, Math.random() * size);
        ctx.lineTo(Math.random() * size, Math.random() * size);
        ctx.stroke();
    }
    ctx.fillStyle = "white";
    ctx.font = `bold ${size / 4}px sans-serif`;
    ctx.fillText(counter.toString(), 0, size / 4);
    const cnt = counter
    createImageBitmap(canvas).then(bm => {
        postMessage({
            type: 'fullyRendered',
            counter: cnt,
            size: size,
            bitmap: bm,
        }, [bm])
    });
    counter++;
}

I added a flying div to visualize the lags in the UI thread: https://i.imgur.com/UqqbukL.mp4. It’s clearly visible that it stops frequently.

Same as above, but the worker’s canvas having willReadFrequently: true

In this scenario, the background rendering itself is significantly slower. But no UI lags occur, and the div’s flight is very smooth: https://i.imgur.com/9sx62WF.mp4.

Conclusion

Is there an option to get the rendering speed of the first two approaches, the DOM + Canvas synchronization as in the last two approaches, and the UI performance as in the approaches 1 and 3?

In the given Symfony application, there are two main routes and corresponding Twig templates

#[Route('/category', name: 'student_category')]
    public function category(EntityManagerInterface $entityManager): Response
    {
        $category = $entityManager->getRepository(Category::class)->findAll();
        return $this->render('student/category.html.twig', [
            'controller_name' => 'StudentController',
            'categories' => $category
        ]);
    }

***** twig page

   <div class="container">
    <div class="row">
{% for category in categories %}

    <div class="col-md-4">
    <div class="card " style="width: 18rem;">
        <div  class="d-flex justify-content-center">
        <img  src="{{ asset('img/' ~ category.img) }}"
             style="width: 150px; height: 150px; object-fit: cover;">
        </div>
        <div class="card-body">
            <h5 class="card-title"> {{category.name }}</h5>
            <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card’s content.</p>
            <a href="{{ path('student_product',{'id':category.id}) }}" class="btn btn-primary">Go somewhere</a>
        </div>
    </div>
    </div>
    {% endfor %}

    </div>
    </div>











    #[Route('/product/{id}', name: 'student_product')]
    public function product(EntityManagerInterface $entityManager,int $id = null): Response
    {
        $category = $entityManager->getRepository(Category::class)->find($id);

        if (!$category) {
            throw $this->createNotFoundException('Category not found.');
        }

        $products = $category->getProduct();


        return $this->render('student/product.html.twig', [
            'controller_name' => 'StudentController',
            'category' => $category,
            'products' => $products
        ]);
    }


  <h2>Categorie: {{ category.name }}</h2>

    <div class="row">
        {% for product in products %}
            <div class="col-md-4">
                <div class="card" style="width: 18rem;">
                    <div class="d-flex justify-content-center">
                        <img src="{{ asset('img/' ~ product.img) }}" style="width: 150px; height: 150px; object-fit: cover;">
                    </div>
                    <div class="card-body">
                        <h5 class="card-title">{{ product.name }}</h5>
                        <p class="card-text">Beschrijving van het product.</p>
                    </div>
                </div>
            </div>
        {% else %}
            <p>Category not found.</p>
        {% endfor %}
    </div>

In the given Symfony application, there are two main routes and corresponding Twig templates involved in displaying categories and their related products. Explain step-by-step how the application retrieves data from the database and renders it on the frontend when a user visits the /category page and then clicks on a specific category card to view its products. In your explanation, include the roles of the controller methods category() and product(), how data is passed to the Twig templates, and how the templates use this data to generate the HTML output. Additionally, describe how the relationship between categories and products is handled in this setup.

MouseMove event unpredicted behaviour when dragging cards

Hi I’m trying to imitate swiper.js effect, the drag effect where you can drag a card
and on dragging it will rotate and move according to the mouse movement
but I have a problem with my implementation what happens is this

1-I click and move my mouse on the card
2- it moves normally and rotates
3- I leave the mouse to stop the dragging effect
4- then click again the drag the card overflows it’s container and moves very fast not smoothly

<!DOCTYPE html>
 <html lang="en">
  <head>
   <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  body {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .scene {
    perspective: 1000px;
    width: 1140px;
    /* perspective-origin: center; */
  }
  .cards {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    transform-style: preserve-3d;
  }
  .card {
    position: relative;
    width: 350px;
    height: 400px;
    display: flex;
    align-items: center;
    justify-content: center;
    /* transform-style: preserve-3d; */
    /* transition: all 2s; */
    cursor: grab;
    user-select: none;
  }
  /* .card:hover {
    transform: rotateY(180deg);
  } */
  .card-side {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
  }
  .card-front {
    background-color: #339af0;
    transform: rotateY(0deg);
  }
  .card-back {
    background-color: #40c057;
    transform: rotateY(180deg);
  }
</style>
</head>
 <body>
  <div class="scene">
  <div class="cards">
    <div class="card">
      <div class="card-side card-front"><a href="#">FRONT</a></div>
      <div class="card-side card-back"><a href="#">BACK</a></div>
    </div>
      </div>
      </div>
       <script src="/script.js"></script>
    </body>
    </html>



    const cardsContainer = document.querySelector(".cards");
    const cards = document.querySelectorAll(".card");
    let isDragging = false;
    let animationId;
    let cardsRect;
    let prevClientX;
    let delta;
    const mappedValue = function (x, fromMin, fromMax, toMin, toMax) {
     const val = toMin + ((x - fromMin) * (toMax - toMin)) / (fromMax - fromMin);
     return Math.min(toMax, Math.max(toMin, val));
    };

    cardsContainer.addEventListener("mousedown", function (e) {
    cardsRect = cards[0].getBoundingClientRect();
    prevClientX = e.clientX;
    const firstClick = e.clientX - cardsRect.left;
 
  if (firstClick > cardsRect.width || firstClick < 0) return;


  const handleMouseMove = function (e) {
     isDragging = true;
     const containerRect = cardsContainer.getBoundingClientRect();
     cardsRect = cards[0].getBoundingClientRect();
     delta = e.clientX - prevClientX;
     if (e.clientX < containerRect.left || e.clientX > containerRect.right)
        return;

     cards[0].style.transition = "transform 0.5s ease-out";
     cards[0].style.transform = `translateX(${delta}px) rotateY(${mappedValue(
      delta,
      0,
      containerRect.width,
      -80,
      240
      )}deg)`;
     };
     const handleMouseUp = function (e) {
     isDragging = false;
     document.removeEventListener("mousemove", handleMouseMove);
   };
   document.addEventListener("mousemove", handleMouseMove);
  document.addEventListener("mouseup", handleMouseUp);
 });

How to make basic connections without this error?

howToSolve

General Guide

Create Project Directory inside terminal

mkdir "Project name"
cd "Project name"

mkdir backend
mkdir "subdirectory2"
mkdir "subdirectory3"

Useful Webpages

VSC Extensions:

  • EasyZoom
  • Live Server
  • Thunder Client
  • Auto Rename Tag

If XAMPP Won’t Start

  1. Navigate to: C:xamppmysqlbackup
  2. Press Ctrl + X to cut the contents
  3. Navigate to: C:xamppmysqldata
  4. Press Ctrl + A to select all, then Ctrl + P to paste

Desktop

Target finish time: ~1h 25min

Classes and Constructors

 class Person
 {
     public int id { get; set; }
     public double average { get; set; }
     public string name { get; set; }
     public DateTime date { get; set; }

     public Person(int id, double average, string name, DateTime date)
     {
         this.id = id;
         this.average = average;
         this.name = name;
         this.date = date;
     }
 }

Text manipulation

Replace(',','-');  // 2019-2-12
Trim('-');  // 2019212 
Split(',');  // {apple, banana, orange}
Contains("YES") // returns true

char[] nameArray = {'A', 'l', 'i', 'c', 'e'};
string name = new string(nameArray);

Math.Round(number, 2)); // 5.43529 -> 5.44 (Honorable mention: Floor(), Ceiling())

Reading a File

using System.IO;
List<Person> peopleList = new List<Person>();

using (StreamReader sr = new StreamReader("filename.txt"))
{
    while (!sr.EndOfStream)
    {
        string line = sr.ReadLine();
        string[] data = line.Split(';');
        int id = int.Parse(data[0]);
        data[1] = data[1].Replace(',', '.');
        double atlag = double.Parse(data[1]);
        string name = data[2];
        DateTime date = Convert.ToDateTime(data[3]);
        Person person = new Person(id, average, name, date);
        peopleList.Add(person);
    }
}

Creating a File

using (StreamWriter sw = File.CreateText("filename.txt"))
{
    sw.WriteLine("...");
}

LINQ Examples

using System.Linq;
foreach (var group in groupedByYear)
{
    Console.WriteLine($"Year: {group.Year}");
    foreach (var person in group.People)
    {
        Console.WriteLine($"- {person.Name}");
    }
}

1. Aggregation (Count, Sum, Average, Max, Min)

Calculate statistics.

int count = people.Count(); // Total people
int over30Count = people.Count(p => p.Age > 30); // People over 30
double totalSalary = people.Sum(p => p.Salary); // Total salary
double avgSalary = people.Average(p => p.Salary); // Average salary
int maxAge = people.Max(p => p.Age); // Oldest age

2. Filtering (Where)

Select people older than 25.

var olderThan25 = people.Where(p => p.Age > 25);

3. Sorting (OrderBy, ThenBy)

Sort people by age, then by name.

var sortedPeople = people.OrderBy(p => p.Age).ThenBy(p => p.Name);

4. Selecting Specific Fields (Select)

Get a list of names and salaries.

var namesAndSalaries = people.Select(p => new { p.Name, p.Salary });

5. Grouping (GroupBy)

Group people by age.

var groupedByAge = people.GroupBy(p => p.Age).Select(g => new { Age = g.Key, People = g });

6. First, Last, Single

Get specific elements.

Person firstPerson = people.First(); // First person
Person lastPerson = people.Last(); // Last person
Person singlePerson = people.Single(p => p.Id == 1); // Person with Id 1

7. Any and All

Check conditions.

bool hasYoung = people.Any(p => p.Age < 25); // True if any person is under 25
bool allHighEarners = people.All(p => p.Salary > 40000); // True if all earn > 40k

Tips for Effective LINQ

  • Performance: Avoid multiple enumerations; materialize results with .ToList() if needed.
  • Debugging: Break complex queries into smaller steps.

Backend

Target finish time: ~1h

Setup Node.js Express

Installs necessary packages inside backend folder and creates app.js/index.js file with basic content

cd backend
npm install express mysql2 cors
npm pkg set type=module
cd backend
echo "import express from 'express';" > app.js
echo "import cors from 'cors';" >> app.js
echo "import mysql from 'mysql2';" >> app.js
echo "" >> app.js
echo "const app = express();" >> app.js
echo "app.use(cors());" >> app.js
echo "app.use(express.json());" >> app.js
echo "" >> app.js
echo "const db = mysql.createConnection({" >> app.js
echo "    host: 'localhost'," >> app.js
echo "    user: 'root'," >> app.js
echo "    password: ''," >> app.js
echo "    database: '', // Database name goes here" >> app.js
echo "    port: 3306" >> app.js
echo "});" >> app.js
echo "" >> app.js
echo "// endpoints" >> app.js
echo "" >> app.js
echo "app.listen(3000, () => {" >> app.js
echo "    console.log('Server is running on http://localhost:3000');" >> app.js
echo "});" >> app.js

Endpoints

import express from "express";
import mysql from "mysql2";
import cors from "cors";

const app = express();
const port = 3000;

app.use(express.json());
app.use(cors());

const db = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "",
  database: "namedays",
});

// API endpoint to get nameday by date
app.get("/api/nameday/", (req, res) => {
  // Extract "date" from query parameter
  const date = req.query.date; // KEY

  // Check if date is specified
  if (!date) {
    return res.status(400).json({ error: "Date parameter is required" });
  }

  // get the month and day
  const month = date.split("-")[0];
  const monthName = convertMonthNumberToName(month);
  const day = date.split("-")[1];
  const sql = SELECT name1, name2 FROM nameday WHERE month = ${month} AND day = ${day};

db.query(sql, (err, result) => {
    if (err) {
      console.log("Server error");
    }
    if (result.length === 0) {
      console.log("No nameday found");
    }
    const nameday = result[0];

// Send response with formatted date and nameday data
    res.json({ // KEY
      date: `${monthName} ${day}.`,
      name1: nameday.name1,
      name2: nameday.name2,
    });
  });
});

// Function to convert month number to month name
function convertMonthNumberToName(monthNumber) {
  switch (monthNumber) {
    case "1":
      return "January";
    case "2":
      return "February";
    ...
  }
}

// Delete data by ID
app.delete("/api/nameday/:id", async (req, res)=>{
 const id = req.params.id; // Extracts the ID from the URL parameter, e.g., /api/nameday/123
  const sql = "DELETE FROM nameday WHERE id = ?";
  const [result] = await database.execute(sql, [id]);
  res.status(200).json(result);
})

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

Frontend

Target finish time: ~1h 30min

Import Bootstrap

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT" crossorigin="anonymous">

Display and submit cards dynamically using Bootstrap

<div class="container">  <!-- To make the page responsive -->
   <form id="dateForm" class="mb-4">
      <div class="row g-3 align-items-end">
        <div class="col-auto">
          <label for="dateInput" class="form-label">Select Date:</label>
          <input type="date" id="dateInput" class="form-control" required>
        </div>
        <div class="col-auto">
          <button type="submit" class="btn btn-primary">Get Nameday</button>
        </div>
      </div>
    </form>
</div>


    <div id="namedayCards" class="row row-cols-1 row-cols-md-2 g-4"></div> // Place for the cards


    <script>
    // Handle form submission
    document.getElementById('dateForm').addEventListener('submit', async (e) => {
      e.preventDefault();
      const date = document.getElementById('dateInput').value;
      if (!date) return;

      // Clear previous cards
      const cardContainer = document.getElementById('namedayCards');
      cardContainer.innerHTML = '';

      // Fetch data from API
      try {
        const response = await fetch(`http://localhost:3000/api/nameday/?date=${date}`);
        if (!response.ok) {
          throw new Error('Failed to fetch nameday data');
        }
        const data = await response.json();

        // Check for error response
        if (data.error) {
          cardContainer.innerHTML = `<div class="alert alert-warning">${data.error}</div>`;
          return;
        }

        // Create Bootstrap cards for each name
        const names = [data.name1, data.name2];
        names.forEach(name => {
          const card = document.createElement('div');
          card.className = 'col';
          card.innerHTML = `
            <div class="card h-100">
              <div class="card-body">
                <h5 class="card-title">${name}</h5>
                <p class="card-text">Nameday on ${data.date}</p>
              </div>
            </div>
          `;
          cardContainer.appendChild(card);
        });
      } catch (error) {
        console.error('Error:', error);
        cardContainer.innerHTML = `<div class="alert alert-danger">Error fetching data</div>`;
      }
    });
  </script>

Unable to add an OAUTH provider in AWS Amplify Sandbox

I’ve been using Amplify since days now and I would like to implement custom OAUTH providers in my sandbox. Currently, I’ve set up LinkedIn and my sandbox start with the Cognito user pool (my LinkedIn provider is showing on my Cognito pool) but my amplify_outputs.json configuration is missing this OIDC

Here is my config: (resource.ts)

export const auth = defineAuth({
  loginWith: {
    email: true,
    externalProviders: {
      oidc: [
        {
          name: 'LinkedIn',
          clientId: secret('linkedinClientId'),
          clientSecret: secret('linkedinClientSecret'),
          issuerUrl: 'https://www.linkedin.com/developers/tools/oauth/redirect',
        },
      ],
      logoutUrls: ['http://localhost:3000/'],
      callbackUrls: [
        'http://localhost:3000/dashboard',
      ],
    }
  },
})

And a part of my amplify_outputs.json:

"oauth": {
      "identity_providers": [],
      "redirect_sign_in_uri": [
        "http://localhost:3000/dashboard"
      ],
      "redirect_sign_out_uri": [
        "http://localhost:3000/"
      ],
      "response_type": "code",
      "scopes": [
        "phone",
        "email",
        "openid",
        "profile",
        "aws.cognito.signin.user.admin"
      ],
      "domain": "REDACTED.auth.eu-west-3.amazoncognito.com"
    },

What I’ve missed here?

As an experienced JavaScript developer looking to expand my skill set, which language would be most beneficial to learn next: Go, Python, or Java? [closed]

I’m an experienced JavaScript developer looking to expand my skill set by learning a new programming language. My goal is to future-proof my career and position myself for higher-paying job opportunities. I’m not targeting any specific domain at the moment, but I want to choose a language that is in high demand, offers strong career prospects, and will continue to be relevant and in demand in the future.

I’m currently considering Go, Python, or Java. I’d really appreciate any suggestions, thoughts, or insights that could help me make an informed decision.

Is possible scroll div when mouse over button which placed in right bottom corner and emitting wheel event

I have two blocks that are in the parent.
The first is a block with a button inside, which is absolutely positioned and is located in the lower right corner of the second block and when pressed, it scrolls to the very bottom. The second block is scrollable content.

<div class="parent">
  <div class="btn-to-bottom">
  </div>
  <div class="scrollable-content">
  </div>
</div>

If the user hovers the mouse over the button and turns the wheel, then the second block does not scroll, can this be fixed?
And preferably without adding to the second deltaY block