I’m trying to set up a Vite monorepo with HMR behind an Nginx reverse proxy — keep getting “Too Many Redirects”

I’m setting up a monorepo project that serves multiple Vite apps behind Nginx using reverse proxies. My goal is to support Hot Module Replacement (HMR) in development.

What I tried
I have two Vite apps:

One served from /

One served from /app/

When I reverse-proxy the first app to /, it works fine.
But when I try to reverse-proxy the second app to /app/, I always get a “Too Many Redirects” error in the browser.

To simplify debugging, I focused on a single Vite app and configured it to be accessible via http://localhost/app/ through Nginx. But I still get the redirect loop.

Vite config

//worko-ui-react/vite.config.ts

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import compression from "vite-plugin-compression";

import path from "path";
// https://vite.dev/config/

export default defineConfig({
  plugins: [react(), compression()],
  envDir: "./environments", // Manually specify the directory where the environment files are located
  envPrefix: "APP_", // Manually specify the prefix for the environment variables
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src"), // Add alias for `src`
      "@Assets": path.resolve(__dirname, "src/assets/assets.ts"),
      "@Components": path.resolve(__dirname, "src/components"),
      "@Context": path.resolve(__dirname, "src/context"),
      "@Enums": path.resolve(__dirname, "src/types/enums"),
      "@Hooks": path.resolve(__dirname, "src/hooks"),
      "@Interfaces": path.resolve(__dirname, "src/types/interface"),
      "@Layouts": path.resolve(__dirname, "src/layouts"),
      "@Pages": path.resolve(__dirname, "src/pages"),
      "@Styles": path.resolve(__dirname, "src/styles"),
      "@Services": path.resolve(__dirname, "src/services"),
      "@Utils": path.resolve(__dirname, "src/utils"),
      "@Views": path.resolve(__dirname, "src/views"),
      "@Routes": path.resolve(__dirname, "src/routes.ts"),
      "lib-worko-ai": path.resolve(__dirname, "../../packages/lib-worko-ai/src"),
      "@LibWorko": path.resolve(__dirname, "../../packages/lib-worko-ai/src"),
    },
  },
  optimizeDeps: {
    exclude: ["lib-worko-ai"],
  },
  server: {
    fs: {
      allow: [".."],
    },
    proxy: {
      "/cognito": {
        target: "https://cognito-idp.ap-south-1.amazonaws.com",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^/cognito/, ""),
      },
    },
    host: "0.0.0.0", // listen on all interfaces (for proxy)
    port: 3001, // ensure it runs on the expected port
    strictPort: true, // do not fallback to a different port,
    open: true, // Manually open the browser window upon starting the server
  },
  base: "/app/",
});

Routes.tsx

  const AppRoutes = createBrowserRouter([
  {
    path: "/",
    // errorElement: <ErrorFallback />,
    element: <MainLayout />,
    children: [
{
    path: "auth/*",
    element: (
      <Suspense fallback={<MainLoader />}>
        <AuthRouter />
      </Suspense>
    ),
  },
  //   {path: 'dashboard/*', element: <DashboardRedirect />},
  { path: "*", element: <PageNotFound /> },
],
{
  basename:"/app",
});

export default AppRoutes;

Nginx config

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

server {
    listen       80;
    server_name  localhost;

    location /app/ {
        proxy_pass http://127.0.0.1:3001/;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}
    
}

How can I restrict screenshots and screen recording in my React Native app (Android, iOS, macOS, Windows, Web)

I’m currently working on an Admin Portal application using React Native, and I need to prevent users from taking screenshots or recording the screen while using sensitive parts of the app.

My app is expected to run on the following platforms:

  1. Android
  2. iOS
  3. macOS
  4. Windows
  5. Web (via React Native for Web or a separate frontend)

I want to ensure that certain screens (like admin views or confidential data displays) are protected from being captured either via screenshot or screen recording. I’ve done some research but haven’t found a unified, cross-platform solution yet. I’m okay with using native modules or platform-specific implementations as needed.

My questions:

  • Android: How do I disable screenshots and screen recording for specific screens or globally in React Native?
  • iOS: Is it possible to detect or block screen recording or screenshots programmatically in iOS via React Native?
  • macOS & Windows (Desktop): What are the available APIs or techniques to restrict screen capture in Electron or React Native for Windows/macOS?
  • Web: Are there any reliable techniques (e.g., CSS, JavaScript) to discourage or prevent screen recording or screenshots on web apps?

My setup:

  • React Native version: [Please insert version here]
  • Using Expo: [Yes/No]
  • Platforms: Android (Java/Kotlin), iOS (Obj-C/Swift), Web (React), Desktop (Electron or RN-Windows/macOS)

Any help, libraries, native code suggestions, or workarounds for any of these platforms would be much appreciated.

Auto fit for Y axis doesn’t work as expected

I noticed that under some circumstances the auto fit of the Y axis doesn’t work (even when invoking fit method manually).
It seems to be related to traces not having the same amount of points (length).
Zooming in the highlighted area won’t fit the Y axis:

first image

After you select the highlighted area from the previous image, I would expect the Y axis to automatically fit to the new data, but it doesn’t:

second image

This is my code:

import {
    emptyFill,
    htmlTextRenderer,
    lightningChart,
} from '@lightningChart/lcjs'

const chart = lightningChart({
    license: '',
    licenseInformation: {
        appTitle: 'LightningChart JS Trial',
        company: 'LightningChart Ltd.',
    },
    sharedContextOptions: {
        // Shared canvas mode for mozilla
        useIndividualCanvas: false,
    },
})
    .ChartXY({
        container: document.getElementById('chart-container') as HTMLDivElement,
        textRenderer: htmlTextRenderer,
        defaultAxisX: {
            type: 'linear-highPrecision',
        },
    })
    .setTitleFillStyle(emptyFill)
    .setPadding({ right: 40 })

const s1 = [
    {
        "x": "2022-02-01T00:00:00.000Z",
        "y": 260002.5
    },
    {
        "x": "2022-03-01T00:00:00.000Z",
        "y": 485898.3
    },
    {
        "x": "2022-03-31T23:00:00.000Z",
        "y": 363026.4
    },
    {
        "x": "2022-04-30T23:00:00.000Z",
        "y": 472677.5
    },
    {
        "x": "2022-05-31T23:00:00.000Z",
        "y": 426169.9
    },
    {
        "x": "2022-06-30T23:00:00.000Z",
        "y": 325075.9
    },
    {
        "x": "2022-07-31T23:00:00.000Z",
        "y": 361082.8
    },
    {
        "x": "2022-08-31T23:00:00.000Z",
        "y": 436457.9
    },
    {
        "x": "2022-09-30T23:00:00.000Z",
        "y": 385213.5
    },
    {
        "x": "2022-11-01T00:00:00.000Z",
        "y": 314850.3
    },
    {
        "x": "2022-12-01T00:00:00.000Z",
        "y": 248065.5
    },

]
const s2 = [
    {
        "x": "2021-06-30T23:00:00.000Z",
        "y": 104446.82
    },
    {
        "x": "2021-07-31T23:00:00.000Z",
        "y": 123269.35
    },
    {
        "x": "2021-08-31T23:00:00.000Z",
        "y": 125170.53
    },
    {
        "x": "2021-09-30T23:00:00.000Z",
        "y": 120678.58
    },
    {
        "x": "2021-11-01T00:00:00.000Z",
        "y": 129243.9
    },
    {
        "x": "2021-12-01T00:00:00.000Z",
        "y": 105639.28
    },
    {
        "x": "2022-01-01T00:00:00.000Z",
        "y": 130527.04
    },
    {
        "x": "2022-02-01T00:00:00.000Z",
        "y": 134972.79
    },
    {
        "x": "2022-03-01T00:00:00.000Z",
        "y": 160231.71
    },
    {
        "x": "2022-03-31T23:00:00.000Z",
        "y": 115727.49
    },
    {
        "x": "2022-04-30T23:00:00.000Z",
        "y": 149579.34
    },
    {
        "x": "2022-05-31T23:00:00.000Z",
        "y": 132888.5
    },
    {
        "x": "2022-06-30T23:00:00.000Z",
        "y": 85069.42
    },
    {
        "x": "2022-07-31T23:00:00.000Z",
        "y": 58082.97
    },
    {
        "x": "2022-08-31T23:00:00.000Z",
        "y": 127669.92
    },
    {
        "x": "2022-09-30T23:00:00.000Z",
        "y": 112249.18
    },
    {
        "x": "2022-11-01T00:00:00.000Z",
        "y": 88587.61
    },
    {
        "x": "2022-12-01T00:00:00.000Z",
        "y": 64808.21
    },
]

const series1 = chart
    .addPointLineAreaSeries({
        dataPattern: 'ProgressiveX',
    })
    .appendJSON(s1)

const series2 = chart
    .addPointLineAreaSeries({
        dataPattern: 'ProgressiveX',
    })
    .appendJSON(s2)

Thanks.

Laravel Local Network Development – Fixing SSL and Asset Loading Issues on Ubuntu

I’m trying to run my Laravel project over the local network for development using the following command:

php artisan serve --host=192.168.1.88

The landing page loads fine, but when I try to log into the system, I encounter this error:

192.168.1.88:40062 Invalid request (Unsupported SSL request)

Additionally, assets (CSS/JS/images) are not loading properly after login.

I’m currently using Ubuntu OS, and this issue only happens after login — it seems like an SSL-related problem, even though I’m not using HTTPS explicitly.

What I suspect:

  • Laravel or the web server might be trying to redirect to HTTPS after login.
  • Some middleware (like RedirectToHttps) could be forcing HTTPS.
  • The asset URLs might be being generated as https:// instead of http:// in certain parts of the application.

What I’ve tried so far:

  • Confirmed APP_URL=http://192.168.1.88:8000 in my .env file.

  • Cleared config cache using:

    php artisan config:clear
    php artisan cache:clear
    php artisan route:clear

  • Restarted the Laravel server.

What I need:

  • A solution to disable any forced HTTPS redirection during local development.

  • A way to ensure assets load over HTTP when using php artisan serve without SSL.

  • Any config or server change required to fix the “Invalid request (Unsupported SSL request)” error.

Could you please help me identify and fix this issue?

Laravel Redirect Type Error when using livewire on middleware routes

I have fresh installed laravel application, I add Livewire on that project. After I install breeze with php artisan breeze:install then I choose livewire, I got error when I go to some routes with middleware on that route. For example, I go to /dashboard without login, I got type error like this

{closure:{closure:/project/bootstrap/app.php:33}:35}(): 
Argument #1 ($response) must be of type IlluminateHttpResponse,
 IlluminateHttpRedirectResponse given

but when I go to /dashboard after login, its run normaly.

This is my standard route for auth

Route::get('dashboard', [DashboardController::class, 'index'])
    ->middleware(['auth', 'verified'])
    ->name('dashboard');

And error is located at bootstrap/app.php on this line

$exceptions->respond(function (Response $response, Throwable $exception, Request $request) {
           

Is there any special function or code for routes using livewire in my case?

Card item not displaying cards right after getting data [closed]

When I get my data from MySQL, I need to show it as a horizontal line with two buttons, next and previous, like in a Netflix movie. But when I get the data, it shows the image above the image.
I need it to show in one line and an image next to the image, not like this image above.
whats problem here idont found any solution?

<?php
session_start();
?>

<!DOCTYPE html>
<html lang="en">

<body>

   <div class="container">

               <div class="featurd-content">
                
               </div>

<?php
            $servername = "localhost";
            $username = "root";
            $password = "";
            $dbname = "login_register";

            // Create connection
            $conn = new mysqli($servername, $username, $password, $dbname);
            // Check connection
            if ($conn->connect_error) {
              die("Connection failed: " . $conn->connect_error);
            }
            $sql = 'SELECT * FROM movies ';
            $result = $conn->query($sql);

            
            if ($result->num_rows > 0) {
              // output data of each row
              while ($row = $result->fetch_assoc()) {

                
                
           ?>
         
         <section>

         <h4> watch noww</h4>
         <i class="bi bi-chevron-left"></i>
         <i class="bi bi-chevron-right"></i>
         

         
         
         <div class="cards">
            <a href="#" class="card">
            <img src="../image/<?php echo $row['movie_image']; ?>" alt="" class="poster">
            </a>
        
         </div>


        
         
         </section>

         <?php }
            } ?>
           

              <!-- </div> -->

 


    


    </div>

</body>
</html>

let left_btn=document.getElementsByClassName('bi-chevron-left')[0];
let right_btn=document.getElementsByClassName('bi-chevron-right')[0];
let cards=document.getElementsByClassName('cards')[0];

left_btn.addEventListener('click',()=>{

    cards.scrollLeft -=140;
})

right_btn.addEventListener('click',()=>{

    cards.scrollLeft +=140;
})




const arrows=document.querySelectorAll(".arrow");
const movieLists=document.querySelectorAll(".movie-list");

arrows.forEach((arrow,i)=>{

    const itemNumber=movieLists[i].querySelectorAll("img").length;
    let clickCounter=0;

    arrow.addEventListener("click",()=>{
        const ratio=Math.floor(window.innerWidth / 300);
        clickCounter++;
        if(itemNumber - (4 + clickCounter) + (4 - ratio) >=0){

            movieLists[i].style.transform=`translateX(${
            movieLists[i].computedStyleMap().get("transform")[0].x.value - 300}px )`;
        } else{
            movieLists[i].style.transform="translateX(0)";
            clickCounter=0;

        }
        
       
    });

    console.log(Math.floor(window.innerWidth/270));
});

// for light and dark theme----- start

const ball=document.querySelector(".toggle-ball")
const items=document.querySelectorAll(".container,.movie-list-title,.navbar-container,.sidebar,.left-menu-icon,.toggle,.login-text");

ball.addEventListener("click",()=>{

    items.forEach(items=>{
        items.classList.toggle("active")
    })

    ball.classList.toggle("active")
})

// for light and dark theme----- end



const wrapper=document.querySelector('.wrapper');
const loginLink=document.querySelector('.login-link');
const registerLink=document.querySelector('.register-link');
const btnPopup=document.querySelector('.btnLogin-popup');
const iconCClose=document.querySelector('.icon-close');

registerLink.addEventListener('click',()=>{
    wrapper.classList.add('active');
});

loginLink.addEventListener('click',()=>{
    wrapper.classList.remove('active');
});

btnPopup.addEventListener('click',()=>{
    wrapper.classList.add('active-popup');
});

iconCClose.addEventListener('click',()=>{
    wrapper.classList.remove('active-popup');
});
*{
    margin: 0%;
    padding: 0%;
    box-sizing: border-box;
}

body{
    width: 100%;
    height: 100vh;
    font-family: 'roboto',sans-serif;
}

.navbar{
    position: fixed;
    width: 100%;
    height: 50px;
    background-color: black;
   
    
}

.navbar-container{
    display: flex;
    align-items: center;
    
    padding: 0 50px;
    height: 100%;
    color: white;
    font-family: 'san',sans-serif;
}

.logo-container{

    flex: 1;
    
}
.logo{
    font-family: 'san',sans-serif;
    font-size: 30px;
    color: #4dbf00;
}

.menu-container{

    flex: 6;
   
}


/*

*/


  




.menu-list{

    display: flex;
    list-style: none; /*delete point from list */
}

.menu-list-item{
    margin-right: 30px;
}

.profile-container{

    flex: 2;
    display: flex;
    align-items: center;
    justify-content: flex-end; /*push item to right corner*/
    
}

.profile-text-container{

    margin: 0 20px;
}

.btnLogin-popup{
    color: white;
    text-decoration: none;
    cursor: pointer;
}
.profile-picture{

    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
}

.toggle{
    width: 40px;
    height: 20px;
    background-color: white;
    border-radius: 30px;
    display: flex;
    align-items: center;
    justify-content: space-around;
    position: relative;
}

.toggle-icon{
    color: #4dbf00;
}

.toggle-ball{

    width: 18px;
    height: 18px;
    background-color: black;
    position: absolute;
    right: 1px;
    border-radius: 50%;
    cursor: pointer;
    transition:  0.5s ease-in-out;
}
/* .sidebar{

    width: 50px;
    height: 100%;
    background-color: black;
    position: fixed;
    top: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-top: 60px;
    
} */


/* .left-menu-icon{
    color: white;
    font-size: 20px;
    margin-bottom: 40px;
} */

.container{
    background-color: #151515;
    min-height: calc(100vh - 50px);
    color: white;
    
}

/* .content-container{
    margin-left: 50px;

} */

.featurd-content{

    height: 50vh;
    padding: 50px;
    background: linear-gradient(to bottom,rgba(0,0,0,0),#151515), url('img/1.jpg');
}




 section{


    position: absolute;
    width: 100%;
    height: auto;
    padding: 0px 50px;
    bottom: 20px;
    color: white;
}

section .cards{


   position: relative;
   width: 100%;
   height: 200px;
   border: 1px solid white;
   margin-top: 10px;
   display: flex;
   align-items: center;
   overflow-x: auto;
   scroll-behavior:smooth ;
   

}

section .bi-chevron-left , .bi-chevron-right{

    position: absolute;
    top: 50%;
    left: 3%;
    width: 25px;
    height: 25px;
    background: gray;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: 12px;
    cursor: pointer;
    transition: .3s linear;
    z-index: 999999999;
    opacity: 0;
}


section .bi-chevron-right{

   left: unset;
   right: 3%;
}

section:hover .bi-chevron-left{

    opacity: 1;
 }

 section:hover .bi-chevron-right{

    opacity: 1;
 }

section .cards::-webkit-scrollbar{


    display: none;
 }


section .cards .card{


    position: relative;
    min-width: 130px;
    height: 180px;
    /* border: 1px solid white; */
    border-radius: 8px;
    margin-right: 10px;
    background: black;
    transition: .3s linear;
    
  

 }

 section .cards .card .poster{


  width: 100%;
  height: 100%;
  border-radius: 8px;
  position: relative;

 }

 






.movie-list-container{

    
    padding:0 20px;    
}

.movie-list-wrapper{

    position: relative;
    overflow: hidden;
    /* background-color: #f5deb3; */

}

.media-scroller{

    display: grid;
    grid-auto-flow: column;
    /* gap: var(--size-3); */
    /* grid-auto-columns: 21%; */
    /* overflow-x: auto; */
}
.movie-list{

    display: flex;
    align-items: center;
    height: 300px;

    transform: translateX(0);   /*for moving slide */

    transition: all 1s ease-in-out ;
    
}


.movie-list-item{

    margin-right: 30px;
    position: relative;
    
}

.movie-list-item:hover .movie-list-item-img{

transform: scale(1.2);
margin: 0 30px;
opacity: 0.5;


}

.movie-list-item:hover .movie-list-item-title,
.movie-list-item:hover .movie-list-item-desc,
.movie-list-item:hover .movie-list-item-button{
    opacity: 1;
}



.arrow{

    font-size: 120px;
    position: absolute;
    top: 90px;
    right: 0;
    color: lightgray;
    opacity: 0.5;
    cursor: pointer;
}

.container.active{

    background-color: white;
}

.movie-list-title.active{

    color: black;
}



.navbar-container.active{
    background-color: white;
    color: black;
}

.sidebar.active{

    background-color: white;
}

.left-menu-icon.active{

    color: black;
}

.login-text.active{
    color: black;
}

.toggle.active{
    background-color: black;
}
.toggle-ball.active{
    background-color: white;
    transform:translateX(-20px) ;
    
}


.wrapper{
   position: absolute;
   top: 20%;
   left: 40%;
    /* position: relative; */
    width: 400px;
    height: 440px;
    /* background: transparent; */
    color: white;
    border: 2px solid rgba(255,255,255,.5);
    border-radius: 20px;
    /* backdrop-filter: blur(20px); */
    background-color: white;
    box-shadow: 0 0 30px rgba(0,0,0,.5);
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    transform: scale(0);
    transition: transform .5s ease, height .2s ease;
}

.wrapper.active-popup{

    transform: scale(1);
}

.wrapper.active{

    height: 520px;
    
}

.wrapper .form-box{

    width: 100%;
    padding: 40px;
}





.wrapper .form-box.login{

    transition: transform .18s ease;
    transform: translateX(0);
   

}

.wrapper.active .form-box.login{

    transition: none;
    transform: translateX(-400px);

}

.wrapper .form-box.register{

    position: absolute;
     transition: none;
    transform: translateX(400px);
}


.wrapper.active .form-box.register{

    transition: transform .18s ease;
    transform: translateX(0);

}

.wrapper .icon-close{

    position: absolute;
    top: 0;
    right: 0;
    width: 45px;
    height: 45px;
    background: #162938;
    font-size: 2em;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    border-bottom-left-radius: 20px;
    cursor: pointer;
    z-index:1;
}

.form-box h2{

    font-size:2em ;
    color: #162938;
    text-align: center;
}

.input-box{

    position: relative;
    width: 100%;
    height: 50px;
    border-bottom: 2px solid #162938;
    margin: 30px 0;
}

.input-box label{

    position: absolute;
    top: 50%;
    left: 5px;
    transform:translateY(-50%);
    font-size: 1em;
    color: #162938;
    font-weight: 500;
    pointer-events: none;
    transition:.5s;
}

.input-box input:focus~label,
.input-box input:valid~label {

    top: -5px;
}

.input-box input{

    width: 100%;
    height: 100%;
    background: transparent;
    border: none;
    outline: none;
    font-size: 1em;
    color: #162938;
    font-weight: 600;
    padding: 0 35px 0 5px;

}

.input-box .icon{

    position: absolute;
    right: 8px;
    font-size: 1.2em;
    color: #162938;
    line-height: 57px;
}

.remember-forgot{

    font-size: 0.9em;
    color: #162938;
    font-weight: 500;
    margin: -15px 0 15px;
    display: flex;
    justify-content: space-between;

}

.remember-forgot label input{

    accent-color: #162938;
    margin-right: 3px;
}

.remember-forgot a{

    color: #162938;
    text-decoration: none;

}

.remember-forgot a:hover {

    text-decoration: underline;
}

.btn{

    width: 100%;
    height: 45px;
    background: #162938;
    color: white;
    border: none;
    outline: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 1em;
    font-weight: 500;
    
}

.login-register{

    font-size: 0.9em;
    color: #163819;
    text-align: center;
    font-weight: 500;
    margin: 25px 0 10px;
}

.login-register p a{

text-decoration: underline;
}







@media only screen and (max-width:940px) {

    .menu-container{
        display: none;
    }
}
<?php
session_start();
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link
        href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&family=Sen:wght@400;700;800&display=swap"
        rel="stylesheet">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
       
        
     
    
    <link rel="stylesheet" href="styleee.css">

   
    <title> onc</title>
</head>
<body>


<?php

include 'signUp.php';
include 'login.php';

?>

   <div class="navbar">
        <div class="navbar-container">
             <div class="logo-container"><h1 class="logo">ONC</h1></div>   
             <div class="menu-container">
                <ul class="menu-list">

                   
                    <li class="menu-list-item">Home</li>
                    <li class="menu-list-item">Movies</li>
                    <li class="menu-list-item">series</li>
                    <li class="menu-list-item">popular</li>
                    <li class="menu-list-item">trends</li>
                    
                    
                </ul>
             </div> 
             
           
             <div class="profile-container">
                <!-- <img class="profile-picture" src="img/profile.jpg" alt=""> -->
                 
                <div class="profile-text-container">

                  <a class="btnLogin-popup"> Login</a>
                  
                </div>

                <div class="toggle">

                    <i class="fa-solid fa-moon toggle-icon"></i>
                    <i class="fa-solid fa-sun toggle-icon"></i>
                     <div class="toggle-ball"></div>
                </div>
             </div>  
        </div>
   </div>

   


   
   


   <div class="container">

               <div class="featurd-content">
                
               </div>



 

         <!-- <div class="movie-list-container"> -->

              
        

         

<?php
            $servername = "localhost";
            $username = "root";
            $password = "";
            $dbname = "login_register";

            // Create connection
            $conn = new mysqli($servername, $username, $password, $dbname);
            // Check connection
            if ($conn->connect_error) {
              die("Connection failed: " . $conn->connect_error);
            }
            $sql = 'SELECT * FROM movies ';
            $result = $conn->query($sql);

            
            if ($result->num_rows > 0) {
              // output data of each row
              while ($row = $result->fetch_assoc()) {

                
                
           ?>
         
         <section>

         <h4> watch noww</h4>
         <i class="bi bi-chevron-left"></i>
         <i class="bi bi-chevron-right"></i>
         

         
         
         <div class="cards">
            <a href="#" class="card">
            <img src="../image/<?php echo $row['movie_image']; ?>" alt="" class="poster">
            </a>
        
         </div>


        
         
         </section>

         <?php }
            } ?>
           

              <!-- </div> -->

        


        
           



              

           



       


    <div class="wrapper">

        <span class="icon-close">
        <ion-icon name="close"></ion-icon>
        </span>
        <div class="form-box login">
            <h2> Login </h2>
            <form action="index.php" method="post">
                <div class="input-box">
                    <span class="icon">
                    <ion-icon name="mail"></ion-icon>
                    </span>
                    <input type="email" name="email" required>
                    <label>Email</label>
                </div>

                <div class="input-box">
                    <span class="icon">
                    <ion-icon name="lock-closed"></ion-icon>
                    </span>
                    <input type="password" name="password" required>
                    <label>Password</label>
                   
                </div>

                <div class="remember-forgot">
                    <label> <input type="checkbox">Remember me</label>
                    <a href="#">Forgot Password </a>
                </div>

                <button type="submit" value="Login" name="login" class="btn">Login</button>

                <div class="login-register">
                    <p>Dont have an account? <a href="#" class="register-link">Register</a></p>
                </div>

           </form>
        </div>


<!--  -->
        <div class="form-box register">
            <h2> Register </h2>
            <form action="index.php" method="post">

            <div class="input-box">
                    <span class="icon">
                    <ion-icon name="person"></ion-icon>
                    </span>
                    <input type="text" name="fullname" class="form-control" required>
                    <label>Username</label>
                </div>

                <div class="input-box">
                    <span class="icon">
                    <ion-icon name="mail"></ion-icon>
                    </span>
                    <input type="email" name="email" class="form-control" required>
                    <label>Email</label>
                </div>

                <div class="input-box">
                    <span class="icon">
                    <ion-icon name="lock-closed"></ion-icon>
                    </span>
                    <input type="password" name="password" class="form-control" required>
                    <label>Password</label>
                   
                </div>


                <div class="input-box">
                    <span class="icon">
                    <ion-icon name="lock-closed"></ion-icon>
                    </span>
                    <input type="password" name="repeat_password" required>
                    <label>Password</label>
                   
                </div>

                <div class="remember-forgot">
                    <label> <input type="checkbox">i agree to the terms & condition</label>
                    
                </div>

                <button type="submit" value="Register" name="submit" class="btn">Register</button>

                <div class="login-register">
                    <p>Already bhave an account? <a href="#" class="login-link">Login</a></p>
                </div>

           </form>
        </div>



    </div>


   <script src="appp.js"></script>
   <script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
   <script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>

</body>
</html>

enter image description here

How to display a list of appointments with related user data in Symfony/Twig

‘m building an appointment management system in Symfony. I have an Appointment entity that relates to User entities for both student and teacher. I want to display a list of all appointments in a Twig template, showing the student’s first name, teacher’s first name, appointment time, and location. Additionally, I want to have links to edit and delete each appointment.

Here is my setup:

appointment/index.html.twig

<?php

namespace AppController;

use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
use AppEntityAppointment; 
use AppEntityClasses;
use AppEntityUser;
use DoctrineORMEntityManagerInterface; 
use AppFormAppointmentTypeForm;
use SymfonyComponentHttpFoundationRequest;


final class AppointmentController extends AbstractController
{
 
#[Route('/appointment', name: 'app_appointment')]
public function read(EntityManagerInterface $entityManager): Response
{
    //Ophalen van alle boeken
    $appointments = $entityManager->getRepository(Appointment::class)->findAll();

    //Tonen van de juiste view (renderen)
    return $this->render('appointment/index.html.twig', [
        'appointments' => $appointments,
    ]);
}

//Functie om een boek toe te voegen verder op
#[Route('/create', name: 'app_create')]
public function add(Request $request, EntityManagerInterface $entityManager): Response
{
    $form = $this->createForm(AppointmentTypeForm::class);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $appointment = $form->getData();
        $entityManager->persist($appointment);
        $entityManager->flush();

        $this->addFlash('success', 'Het appointment is toegevoegd');

        return $this->redirectToRoute('app_appointment');
    }

    return $this->render('appointment/create.html.twig', [
        'form' => $form
    ]);
}


#[Route('/appointment/edit/{id}', name: 'app_appointment_edit')]
public function edit(Request $request, EntityManagerInterface $entityManager, int $id): Response
{

     $appointment = $entityManager->getRepository(Appointment::class)->find($id);
    $form = $this->createForm(AppointmentTypeForm::class, $appointment);

    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $appointment = $form->getData();
        $entityManager->persist($appointment);
        $entityManager->flush();

        $this->addFlash('success', 'Het appointment is toegevoegd');

        return $this->redirectToRoute('app_appointment');
    }

    return $this->render('appointment/create.html.twig', [
        'form' => $form
    ]);
}

#IsGranted[("ROLE_ADMIN")]
#[Route('/appointment/delete/{id}', name: 'app_appointment_delete')]
public function delete(EntityManagerInterface $entityManager, Appointment $appointment): Response {
    //We bereiden het wissen voor in de database
    $entityManager->remove($appointment);

    //We voeren de statements uit (het wordt nog gedelete)
    $entityManager->flush();

    //Uiteraard zetten we een flash-message
    $this->addFlash('success', 'appointment is gewist');

    //We maken een redirect naar de route om het aangepaste boek te tonen
    return $this->redirectToRoute('app_appointment');
}

}

appointment/index.html.twig

{% extends 'base.html.twig' %}

{% block title %}Hello AppointmentController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background:rgb(17, 99, 153); padding: 2px 6px; }
</style>




<table class="table example-wrapper">
  <thead>
    <tr>
      <th scope="col">Student</th>
      <th scope="col">Teacher</th>
      <th scope="col">Location / Time</th>
         <th scope="col">Edit</th>
          <th scope="col">Delete</th>
    </tr>
  </thead>   
  <tbody>
      {% for appointment in appointments %}
    <tr>

      <td>  {{ appointment.student.firstName }}</td>
      <td>      {{ appointment.teacher.firstName }}</td>
  <td>   {{ appointment.time|date("F jS \a\t g:ia") }}, {{ appointment.location}}</td>

 <td><a class="nav-link" href="{{path('app_appointment_edit',  {'id': appointment.id }) }}">  Edit <span class="sr-only"></span></a></td>
  <td><a class="nav-link" href="{{path('app_appointment_delete',  {'id': appointment.id} ) }}">Delete <span class="sr-only"></span></a></td>




      </td>
    </tr>
        {% endfor %}
         <td><a class="nav-link" href="{{ path('app_create') }}"> Create   <span class="sr-only"></span></a></td>
  </tbody>
</table>


{% endblock %}

appointment/create.html.twig

{% extends 'base.html.twig' %}

{% block title %}Hello AppointmentController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

{{ form(form) }}
{% endblock %}

appointment.php

<?php

namespace AppEntity;

use AppRepositoryAppointmentRepository;
use DoctrineORMMapping as ORM;

#[ORMEntity(repositoryClass: AppointmentRepository::class)]
class Appointment
{
    #[ORMId]
    #[ORMGeneratedValue]
    #[ORMColumn]
    private ?int $id = null;

    #[ORMManyToOne(inversedBy: 'studentAppointments')]
    private ?User $student = null;

    #[ORMManyToOne(inversedBy: 'teacherAppointments')]
    private ?User $teacher = null;

    #[ORMColumn(length: 255)]
    private ?string $location = null;

    #[ORMColumn]
    private ?DateTime $time = null;

    #[ORMColumn(length: 255)]
    private ?string $topic = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getStudent(): ?User
    {
        return $this->student;
    }

    public function setStudent(?User $student): static
    {
        $this->student = $student;

        return $this;
    }

    public function getTeacher(): ?User
    {
        return $this->teacher;
    }

    public function setTeacher(?User $teacher): static
    {
        $this->teacher = $teacher;

        return $this;
    }

    public function getLocation(): ?string
    {
        return $this->location;
    }

    public function setLocation(string $location): static
    {
        $this->location = $location;

        return $this;
    }

    public function getTime(): ?DateTime
    {
        return $this->time;
    }

    public function setTime(DateTime $time): static
    {
        $this->time = $time;

        return $this;
    }

    public function getTopic(): ?string
    {
        return $this->topic;
    }

    public function setTopic(string $topic): static
    {
        $this->topic = $topic;

        return $this;
    }
}

how to fill in entity field with logged in user with a certain role

->add('instructor', EntityType::class, [
                'class' => User::class,
                'choice_label' => 'name',
                'multiple' => false,
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.roles LIKE :role')
                        ->setParameter('role', '%ROLE_INSTRUCTOR%');
                },
            ])

right now i only got a dropdown from all instructors

I want to initialize my input signal with a default class and some data manipulations

I am using this package, ang-jsoneditor, which contains the below initialization code.

@Component({ ... })
export class AppComponent {
  public editorOptions: JsonEditorOptions;
  public data: any;
  // optional
  @ViewChild(JsonEditorComponent, { static: false }) editor: JsonEditorComponent;

  constructor() {
    this.editorOptions = new JsonEditorOptions()
    this.editorOptions.modes = ['code', 'text', 'tree', 'view']; // set all allowed modes
    ...
  }

}

I want to convert this to the new signals method of handling inputs, but I cant seem to figure out how to move the initialization code inside the input signal.

@Component({ ... })
export class AppComponent {
  public editorOptions = input<JsonEditorOptions>({});
  public data: any = inpu.required();
  // optional
  editor = viewChild(JsonEditorComponent);

  constructor() {
    // how do I move this code inside the `input` default value?
    this.editorOptions = new JsonEditorOptions()
    this.editorOptions.modes = ['code', 'text', 'tree', 'view']; // set all allowed modes
    ...
  }

}

Mastercard Payment Gateway Hosted Checkout not loading—only shows loading animation in Flutter WebView (Session ID passed)

I’m integrating Mastercard’s Payment Gateway Hosted Checkout in my Flutter app using a WebView. The idea is to open the Mastercard payment portal by passing a session ID I get from the backend (API version 83, test environment).

My issue:
The payment portal loads only a loading animation—the actual payment page never appears. Console logs show some errors (see below).

My Dart/Flutter Code:

void loadPaymentPage() {
  print('Step: Starting loadPaymentPage at ${DateTime.now()}');
  if (sessionId == null) {
    print('Step: Session ID is null - Aborting loadPaymentPage at ${DateTime.now()}');
    return;
  }
  print('Step: Session ID available - $sessionId at ${DateTime.now()}');

  String htmlContent = """
<!DOCTYPE html>
<html>
<head>
  <script src="https://test-xxx.gateway.mastercard.com/static/checkout/checkout.min.js"
          data-error="errorCallback"
          data-cancel="cancelCallback"></script>
  <script type="text/javascript">
    function errorCallback(error) {
      console.log(JSON.stringify(error));
    }
    function cancelCallback() {
      console.log('Payment cancelled');
    }
    window.onload = function() {
      Checkout.configure({
        session: {
          id: '$sessionId'
        }
      });
      Checkout.showPaymentPage();
    };
  </script>
</head>
<body>
  <p>Loading payment...</p>
  <div id="embed-target"></div>
  <input type="button" value="Pay with Embedded Page" onclick="Checkout.showEmbeddedPage('#embed-target');" />
  <input type="button" value="Pay with Payment Page" onclick=";" />
</body>
</html>
""";

  _controller.loadHtmlString(htmlContent);
}

Console Log Errors

Possible Unhandled Promise Rejection: [object DOMException]
Unrecognized feature: 'payment'.
Uncaught SecurityError: Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document.

Using Flutter WebView to load the HTML.

API Reference: https://test-gateway.mastercard.com/api/documentation/apiDocumentation/checkout/version/83/api.html

Mastercard portal shows only a loading spinner, nothing else happens.

How do I fix the Mastercard payment gateway portal not loading in a Flutter WebView when passing a session ID?
Are there special WebView settings, permissions, or workarounds needed for Mastercard’s Hosted Checkout to work in Flutter?

Microservices user auth with better-auth in Expressjs

I am trying to build a software based on a microservices infrastructure and I just learned how powerful better-auth is, however I don’t know how to handle route protection in a microservices approach, so for example let’s say that there is one Expressjs app that is in charge on user authentication, and I have another Expressjs app for a service that is going to let users upload files, in the client I am using Reactjs, how would I protect the file service app routes if it doesn’t have a direct connection to the users database because is a different service connected to other DB, should I fetch the user auth service? isn’t there an easier way like JWT? does anybody have an example I can watch? I’ve tried many different solutions but most don’t work or are inefficient, help please

I tried something like this:

file service (this is just to test the user authentication system):

import express from "express";
import { fromNodeHeaders, toNodeHandler } from "better-auth/node";
import { auth, createAuthMiddleware } from "./auth";
import { isAuthenticated } from "./middleware/user";

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

// Mount express json middleware after Better Auth handler
// or only apply it to routes that don't interact with Better Auth
app.use(express.json());

app.get("/protected", createAuthMiddleware, (req, res) => {
  res.send("Hello");
  return;
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});
import { betterAuth } from "better-auth";
import { bearer } from "better-auth/plugins";
import { NextFunction, Request, Response } from "express";

// Create a singleton instance
export const auth = betterAuth({
  plugins: [
    bearer({
      requireSignature: true,
    }),
  ],
});

export const createAuthMiddleware = async (
  req: any,
  res: Response,
  next: NextFunction
) => {
  try {
    const session = await auth.api.getSession({
      headers: req.headers,
    });

    if (!session) {
      res.status(401).json({ error: "Unauthorized" });
      return;
    }

    req.session = session;
    next();
  } catch (error) {
    res.status(401).json({ error: "Invalid token" });
    return;
  }
};

user authentication service:

import express from "express";
import { fromNodeHeaders, toNodeHandler } from "better-auth/node";
import { auth } from "./auth";
import { isAuthenticated } from "./middleware/user";

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

app.all("/api/auth/*", toNodeHandler(auth)); // For ExpressJS v4
// app.all("/api/auth/*splat", toNodeHandler(auth)); For ExpressJS v5

// Mount express json middleware after Better Auth handler
// or only apply it to routes that don't interact with Better Auth
app.use(express.json());

// Add this middleware before your protected routes
app.use(async (req, res, next) => {
  const session = await auth.api.getSession({
    headers: fromNodeHeaders(req.headers),
  });

  console.log(session);

  if (!session) {
    req.user = null;
    req.session = null;
    return next();
  }

  req.user = session.user;
  req.session = session.session;
  return next();
});

app.get("/protected", isAuthenticated, (req, res) => {
  res.send("Hello");
  return;
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
// If your Prisma file is located elsewhere, you can change the path
import { PrismaClient } from "@prisma/client";
import { bearer } from "better-auth/plugins";

const prisma = new PrismaClient();
export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
  },
  database: prismaAdapter(prisma, {
    provider: "postgresql", // or "mysql", "postgresql", ...etc
  }),
  plugins: [
    bearer({
      requireSignature: true,
    }),
  ],
});

Unable to use fields in jsGrid from import

I am puzzled at how to get this working properly. Have looked at many different ways but unable to get my jsGrid to load properly.

  • Java SpringBoot 2.7.18
  • Tomcat Embedded
  • jsGrid 1.5.3
  • jQuery 3.2.1

I have a js-grid-helper.js which has static information for the columns:

export var TABLE_COLUMNS = [
    { name: 'column_1',  title: 'Column 1',  type: 'text'}
    ,{ name: 'column_2',    title: 'Column 2', type: 'text'}
    ,{ name: 'column_3', title: 'Column 3', type: 'text'}
];

I import this into my page.js and then reference it in my jsGrid initialization

import {
    TABLE_COLUMNS
} from "../components/jsgrid-helpers.js";

$('#my-table').jsGrid({
    width: '100%',
    height:'700px',

    filtering:true,
    editing:  false,
    paging:   true,
    autoload: false,
    sorting:  true,
    pageLoading: true,
    pageSize: 20,
    controller: jsGridController,
    fields: TABLE_COLUMNS,

    rowClick: function(args){
    },
    onDataLoading: function(args){
    },
    onDataLoaded: function(args){
    }
});

I get an error for the following, because TABLE_COLUMNS is undefined

jsgrid.min.js:7 Uncaught TypeError: Cannot read properties of undefined (reading 'length')
    at new d (jsgrid.min.js:7:30218)
    at jsgrid.min.js:7:3982
    at r.map (jquery-3.2.1.min.js:2:3309)
    at d._initFields (jsgrid.min.js:7:3882)
    at d._init (jsgrid.min.js:7:3131)
    at new d (jsgrid.min.js:7:200)
    at HTMLDivElement.<anonymous> (jsgrid.min.js:7:22224)
    at r.each (jquery-3.2.1.min.js:2:2715)
    at r.fn.init.each (jquery-3.2.1.min.js:2:1003)
    at b.fn.jsGrid (jsgrid.min.js:7:22040)
d   @   jsgrid.min.js:7
(anonymous) @   jsgrid.min.js:7
map @   jquery-3.2.1.min.js:2
_initFields @   jsgrid.min.js:7
_init   @   jsgrid.min.js:7
d   @   jsgrid.min.js:7
(anonymous) @   jsgrid.min.js:7
each    @   jquery-3.2.1.min.js:2
each    @   jquery-3.2.1.min.js:2
b.fn.jsGrid @   jsgrid.min.js:7
(anonymous) @   page.js:199

However, if I place the TABLE_COLUMNS in the SAME file it works absolutely fine like so:

var TABLE_COLUMNS = [
    { name: 'column_1',  title: 'Column 1',  type: 'text'}
    ,{ name: 'column_2',    title: 'Column 2', type: 'text'}
    ,{ name: 'column_3', title: 'Column 3', type: 'text'}
];

$('#my-table').jsGrid({
    width: '100%',
    height:'700px',

    filtering:true,
    editing:  false,
    paging:   true,
    autoload: false,
    sorting:  true,
    pageLoading: true,
    pageSize: 20,
    controller: jsGridController,
    fields: TABLE_COLUMNS,

    rowClick: function(args){
    },
    onDataLoading: function(args){
    },
    onDataLoaded: function(args){
    }
});

Is this a timing thing, ES Module thing, or a jsGrid library thing? Cannot figure it out. I have also tried setting it to when the document is ready and also a delay of a few seconds and neither works.

How to change the background color of an element in the most efficient way?

I have this square that I would like to change the background color of using buttons.

https://jsfiddle.net/jagupnvc/

<div id="square"></div>
<div>
  <button onclick="colorRed()">Red</button>
  <button onclick="colorYellow()">Yellow</button>
  <button onclick="colorBlue()">Blue</button>
</div>
#square {
  height: 200px;
  width: 200px;
  border: 1px solid black;
}

I’ve had a few thoughts on how I could do this, but I’d love some input on what would/wouldn’t work and how/why.

I do NOT want to implement a “Next” button that uses a loop to cycle through the colors, I would like a button for each color.

The first idea I had would be to make a separate function to change the color for each and every button. Keeping in mind that I’d like to do a dress-up game someday with a ton of different layers/outfit options, this doesn’t seem ideal or efficient and I really hope this is not the solution.

The second idea I had would be to somehow make an array of html buttons, an array of css colors classes, and somehow make a function that would link the two somehow? For example, if button1 gets pressed, show .color1, if button2 gets pressed, show .color2, etc.

Can’t style Google Maps autocomplete inputs – Shadow DOM issue

I’m struggling with Google’s new <gmp-place-autocomplete> web components. My dark-themed site looks terrible with these WHITE input boxes that can’t be styled.

The issue: Shadow DOM encapsulation prevents styling the actual input field (only dropdown parts are stylable via ::part() selectors).

I’ve tried:

  • High specificity CSS
  • !important flags
  • CSS variables
  • Custom overlays

Has anyone:
enter image description here

  1. Discovered any decent workaround to keep having the auto complete funtionality and find places by name in the search results?

enter image description here– any help appreciated!

What’s the mime type for photoshop in windows?

I have an upload text field that accepts the following mime types. Unfortunately, it doesn’t accept PSD and AI files on Windows computer but does on Mac. Does PSD and AI files have a different mime type on Windows computers?

".jpg",
".jpeg",
".png",
"image/jpeg",
"image/png",
"image/svg+xml",
"image/x-photoshop",
"image/vnd.adobe.photoshop",
".ai",
"application/vnd.adobe.illustrator",
"application/postscript",
"application/vnd.adobe.photoshop",
"application/x-photoshop"

How can I check for PSD and AI files on Windows in a safe way?