How to fix blocked because of a disallowed MIME type (“text/html”) in ruby on rails app(Render)?

Render - Production app, Console error messages

Render dashboard log, error messages

**
I’m using hotwired/stimulus and importmap_tags for JavaScript in my Ruby on Rails app. In development, everything works fine, but after deploying to Render, my sales view and the product with variants form (which generates variants through scripts) are not functioning.
**
Here’s my folder structure for the JavaScript files:


app/
javascript/
application.js
controllers/
new_product_controller.js
edit_product_controller.js
sales_controller.js
catalog_controller.js
index.js
variant_controller.js
and more...

Additionally, I have this in my app/bin/render-build.js:

set -o errexit
bundle install
bundle exec rails assets:precompile
bundle exec rails assets:clean
# Uncomment the following line if using a Free instance:
bundle exec rails db:migrate

And in my render.yaml, the config looks like this:

databases:
  - name: inventory_management_demo
    databaseName: inventory_management_demo
    user: inventory_management_demo_user
    plan: free
    region: singapore
    ipAllowList:
      - source: 0.0.0.0/0
        description: everywhere
    postgresMajorVersion: "16"

services:
  - type: web
    name: mysite
    runtime: ruby
    plan: free
    buildCommand: "./bin/render-build.sh"
    startCommand: "bundle exec rails server"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: inventory_management_demo
          property: connectionString
      - key: RAILS_MASTER_KEY
        sync: false
      - key: WEB_CONCURRENCY
        value: 2

Everything works as expected in development, but after deploying to Render, I’m getting errors in the console and can’t figure out how to fix them. Any help would be appreciated,

Node project with mongodb never loads on specific routes

I have been making a small API for practicing purposes, but I’m encountering problems getting data for my Mongodb database collection, when I open a specific route the controller looks like that doesn’t send anything, and the API keeps loading forever with any response

The database connect when I start the node project it gives me a message that it connects however when I try a route like /authors it nevers gives me an answer not even an error so I can’t figure out what is going on and it keeps loading forever with no answer at all, I have made a similar API like this for learning purposes and it works perfectly I don’t know what is going on with this one. My environment variable has the name of the collection in the URI

here’s my code

    const express = require('express');
    const mongodb = require('./db/connect');
    const app = express();
    const bodyParser = require('body-parser');

    const port = process.env.PORT || 3000;

    app.use(bodyParser.json()); 
    app.use(bodyParser.urlencoded({ extended: true }));
    app.use('/', require('./routes'));

    process.on('uncaughtException', (err, origin) => {
      console.log(
        process.stderr.fd,
        `Caught exception: ${err}n` + `Exception origin: ${origin}`
      );
    });

    mongodb.initDb((err) => {
      if (err) {
        console.log('The database connection failed');
      } else {
        app.listen(port);
        console.log(`Connected to DB and listening on ${port}`);
      }
    });

    db connect.js
    const dotenv = require('dotenv');
    dotenv.config();
    const MongoClient = require('mongodb').MongoClient;

    let _db;

    const initDb = (callback) => {
      if (_db) {
        console.log('Db is already initialized!');
        return callback(null, _db);
      }
      MongoClient.connect(process.env.MONGODB_URI)
        .then((client) => {
          _db = client;
          callback(null, _db);
        })
        .catch((err) => {
          callback(err);
        });
    };


    const getDb = () => {
      if (!_db) {
        throw Error('Db not initialized');
      }
      return _db;
    };

    module.exports = {
      initDb,
      getDb,
    };


    routes index.js
    const express = require('express');
    const router = express.Router();

    router.get('/', (req, res) => {
      res.send('Running');
    });

    router.use('/authors', require('./authors'));

    module.exports = router;


    routes authors.js
    const express = require('express');
    const router = express.Router();
    const authorsController = require('../controllers/authorsController');

    router.get('/', authorsController.getAll);
    /*router.get('/:id', authorsController.getAuthorById);
    router.get('/:id/books', authorsController.getAuthorBooks);
    router.post('/', authorsController.addNewAuthor);
    router.put('/:id', authorsController.updateAuthorInfo);
    router.delete('/:id', authorsController.deleteAuthor);*/

    module.exports = router;

    controllers authorsController
    const mongodb = require('../db/connect');
    const ObjectId = require('mongodb').ObjectId;

    const getAll = async (req, res) => {
      const result = await mongodb.getDb().db().collection('authors').find();
      result.toArray((err, lists) => {
        if (err) {
          res.status(400).json({ message: err });
        }
        res.setHeader('Content-Type', 'application/json');
        res.status(200).json(lists);
      });
    };

    const getAuthorById = async (req, res) => {
      if (!ObjectId.isValid(req.params.id)) {
        res.status(400).json('Author ID is not valid');
      }
      const userId = req.params.id;
      const result = await mongodb
        .getDb()
        .db()
        .collection('authors')
        .find({ _id: userId });
      result.toArray((err, lists) => {
        if (condition) {
          res.status(400).json({ message: err });
        }
        res.setHeader('Content-Type', 'application/json');
        res.status(200).json(lists);
      });
    };



    module.exports = {
      getAll,
      getAuthorById,
    };```


these are my package json dependencies
```      "dependencies": {
        "body-parser": "^1.20.3",
        "dotenv": "^16.4.5",
        "express": "^4.21.1",
        "mongodb": "^6.9.0",
        "nodemon": "^3.1.7"
      }```


What is the next steps to enhance my knowledge as a web developer? [closed]

I learned full-stack development in two years and did some projects, but only after watching YouTube tutorials. So, my tech stack is MERN stack and SQL. I am also doing DSA in C++, but I have not done much deep diving into this. I applied recently to many jobs, but at the end of the day, I got nothing in my hands apart from disappointment. I feel I do have not that much knowledge now, so I am here looking for any suggestion that helps to enhance my knowledge in programming and build websites on my own not from any YouTube tutorials, which tech stack I have to add to my skills, so I feel more confident?

I need a suggestion to improve my programming skills.

Unable to set value for p-dropdown in angular

> html file

<p-dropdown  name="abc"
   formControlName="abc" #abcDropdown
   (onChange)="abcOptionSelected('abc')"
   [options]='abcDropdownOptions' styleClass='ee-input' placeholder=''
   [style]="{'width': '50%'}">
</p-dropdown>

> component.ts file
abcOptions.forEach(abcd=> {
                                this.abcDropdownOptions.push({ label: abcd.toString(), value: abcd});
                            });
this.formControls.abc.setValue(3);

what am i doing wrong.
I am trying to setvalue for p-dropdown from component.ts but the value is not reflecting in UI.

wp redirect users only when logging in (1 time) if on homepage

I have the following code to redirect users which are logged in and on the homepage:

function add_login_check()
{
  if ( is_user_logged_in() && is_page(7) ) {
    ?>
    <script>window.location='/user-area/'</script>

    <?php
    exit();
  }
}
add_action('wp', 'add_login_check');

But I am trying to modify it to only redirect users as they actually login (only to redirect once (as they login)), rather than every time they visit the homepage whilst they are logged in.

I have tried using session as follows:

function add_login_check()
{
if(!isset($_SESSION['didit'])) {
  if ( is_user_logged_in() && is_page(7) ) {
    ?>
    <script>window.location='/user-area/'</script>

    <?php
    exit();
  }
    $_SESSION['didit'] = true; 
}
}
add_action('wp', 'add_login_check');

Also adding session_start(); to the beginning of my theme, but I can’t get it to work 🙁 I’d really appreciate any help, thanks so much!!!

What is the type of component’s children in React?

Until now, i was using the type any to refer the children of my components, but when I updated my deploy it says not accept any as a valid type, what type i should use on my Section component bellow?

import {  ReactElement, ReactNode } from "react"

const Section = ({children}:any): ReactElement => {
    return (
        <div className="flex flex-row relative w-screen h-136">
            {children}
        </div>
    )
}

export default Section
import { ReactElement } from "react";
import Section from "../Section";

const ContactMe = (): ReactElement => {
    return (
        <Section>
            <div className="w-full h-full bg-cyan-900">

            </div>
        </Section>
    )
}

export default ContactMe

Need advice for web based docx generation portal with python backend

My system has a HTML/js front and python flask backend. The purpose of my system is to allow users to generate a close to finished .docx report file from the web portal that follows a specific format. The purpose of this is to ensure that as much of the report that the user wants to write is generated and completed upon generation. This is to prevent less microsoft word savvy users from ignoring ms word formatting and manually typing out section numbers and captions for example that wont auto update or be included in the TOC. Currently, I am primarily using python scripts to select quick parts from my Microsoft Word template. The quick parts contain commonly used sections. While this works for just allowing the user to create the report with all the generic section types (e.g. intro, TOC, version history), I can’t think of a way for the user to add what they want to the sections in the web portal.

Currently, the two methods that I have employed are using specific context cues in my template template .docx file and using python scripts to select quickparts that contain my sections. For example, I will have context cues like ” {{ COVERPG_Block1 }} ” and ” {{ COVERPG_Block2 }} ” for parts of the generated report that is standard and when the user inputs the text in the web portal, upon report generation the inputted text will substitute the context text. On the other hand, all the other parts of the report that depends on what the user requires are basically selected from the quick parts using macros. The user can chose which macros will run by dragging and dropping cards from on box into another in the users preffered sequence. While this works for just generating the barebones report. I have not found a way to generate the sections and populate them with text that has the appropriate formatting such as when using the context cues. An except of my code is as follows.

Python:

from pywinauto import Application
import pyautogui
import time
from docxtpl import DocxTemplate
from flask import Flask, render_template, request, send_file
from datetime import datetime
from pywinauto import timings


app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

#generate Revision History    
def macro_RevisionHistory(repetitions): 
    print(f"Running macro_RevisionHistory with {repetitions} repetitions.")
    for i in range(repetitions):
        print(f"Iteration {i + 1} of macro_RevisionHistory.")
        try:
            pyautogui.hotkey('alt', 'n'  )
            time.sleep(0.1) 
            pyautogui.hotkey('q'  )
            pyautogui.press('down'  )
            pyautogui.press('down'  )
            pyautogui.press('down'  )
            pyautogui.press('down'  )
            pyautogui.press('down'  )
            pyautogui.press('down'  )
            pyautogui.press('down'  )
            pyautogui.press('enter'  )
            pyautogui.hotkey('alt', 'n'  )
            pyautogui.hotkey('b')
        except Exception as e:
            print(f"Error occurred in macro_RevisionHistory during iteration {i + 1}: {e}")
    print("macro_RevisionHistory execution completed.")

#other macros.............

#start MS word exe and focuses it for macros to run correctly
def focus_word_document(output_path):
    try:
        print(f"Opening Word document: {output_path}")
        word_exe_path = r"C:Program FilesMicrosoft OfficerootOffice16WINWORD.EXE"
        app = Application().start(f'"{word_exe_path}" "{output_path}"')

        word_window = app.window(title_re=".*Word")
        timings.wait_until_passes(1, 0.1, lambda: word_window.exists())

        word_window.set_focus()
        time.sleep(0.3)

        if word_window.is_active():
            print("Word document is in focus.")
        else:
            print("Word document is not in focus.")
    except Exception as e:
        print(f"Error focusing on Word document: {e}")

@app.route('/generate', methods=['POST'])
def generate_doc():
    # Get the form data from the request
    coverpg_block1 = request.form['COVERPG_Block1']
    coverpg_block2 = request.form['COVERPG_Block2']
    confidentiality_1 = request.form['CONFIDENTIALITY']
    ver_no = request.form['VERSION']
    date = request.form['DATE']
    output_filename = request.form['output_filename']

    # Get the number of repetitions from the form (default to 0 if no input)
    repetitions_input = request.form.get('repetitions', '0').split(',')
    repetitions = [int(rep) for rep in repetitions_input if rep.isdigit()]
    print(f"Repetitions list: {repetitions}")

    # Get the sequence of macros from the form input (e.g., "1,2,1,1")
    macro_sequence = request.form['macro_sequence']
    print(f"Macro sequence: {macro_sequence}")

    # Create the context dynamically based on the form input
    context1 = {
        'COVERPG_Block1': coverpg_block1,
        'COVERPG_Block2': coverpg_block2,
        'CONFIDENTIALITY': confidentiality_1,
        'VERSION': ver_no,
        'DATE': date
    }

    # Load the Word macro-enabled template (.docx version)
    template_path = "TEMPLATE.docx"  # Change to .docx
    print(f"Loading template from: {template_path}")
    doc = DocxTemplate(template_path)

    # Render the template with the dynamic context
    doc.render(context1)
    print("Template rendered with context.")

    # Save the generated document
    output_path = output_filename if output_filename.endswith('.docx') else output_filename + '.docx'
    doc.save(output_path)
    print(f"Document saved as: {output_path}")

    # Focus on the newly opened Word document
    focus_word_document(output_path)

    # Start the macro execution after switching focus
    start_up_macro_execution()
    """
    string.split(delimiter)
    delimiter: This is the character(s) that the string will be split by. If no delimiter is provided, 
    the default is any whitespace (spaces, tabs, or newlines).
    delimiter- a cSharacter that marks the beginning or end of a unit of data.
    
    Takes the string macro_sequence and splits it into a list of substrings based on commas ,.
    For example, if macro_sequence is '2,3,4', then after split(','), the result will be the list ['2', '3', '4'].
    """
    macro_sequence_list = macro_sequence.split(',')  # Convert the input string to a list
    print(f"Executing macro sequence: {macro_sequence_list}")
    
    """ 
    if macro is ' 2 ', without using .strip(), the condition macro == '2' would fail because the string contains spaces. By using .strip(), 
    the string becomes just '2', allowing the condition to pass correctly.
    """
    for index, macro in enumerate(macro_sequence_list):
        print(f"Running macro: {macro.strip()}")  
        if macro.strip() == '2':  # Use strip to avoid any extra spaces
            macro_TOC(repetitions[0])  
        elif macro.strip() == '3':
            macro_listoffigs(repetitions[0])  
        elif macro.strip() == '4':
            macro_listoftables(repetitions[0])
        elif macro.strip() == '5':
            macro_introsection(repetitions[0])  
        elif macro.strip() == '6':
            macro_SecWithImage(repetitions[0])  
        elif macro.strip() == '7':
            macro_SecWithTable(repetitions[0])  
        elif macro.strip() == '8':
            macro_GenericSec(repetitions[0])    
        elif macro.strip() == '9':
            macro_references(repetitions[0])   
        elif macro.strip() == '10':
            macro_DocInfo(repetitions[0])    
        elif macro.strip() == '11':
            macro_RevisionHistory(repetitions[0])     
        else:
            print(f"Unknown macro: {macro.strip()}")
        
        # Break after the last macro has been run
        if index == len(macro_sequence_list) - 1:
            print("All macros executed. Stopping the macro sequence.")
            break

    # Send the generated document to the user as a downloadable file
    return send_file(output_path, as_attachment=True)

if __name__ == '__main__':
    app.run(debug=True)

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document Generator</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

    <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
</head>
<body>
    <h1>Quick SAINS Report Template Generator</h1>
    <form action="/generate" method="post" id="docForm">
        <div class="container">
        <label for="COVERPG_Block1">Report Name:</label>
        <input type="text" id="COVERPG_Block1" name="COVERPG_Block1" required>
        </div>

        <div class="container">
        <label for="COVERPG_Block2">TYPE:</label>
        <select name="COVERPG_Block2" id="COVERPG_Block2">
            <option value="REPORT">REPORT</option>
            <option value="SOP">SOP</option>
        </select>
        </div>

        <div class="container">
            <label for="CONFIDENTIALITY">Level Of Confidentiality:</label>
            <select name="CONFIDENTIALITY" id="CONFIDENTIALITY">
                <option value="HIGHLY CONFIDENTIAL">HIGHLY CONFIDENTIAL</option>
                <option value="CONFIDENTIAL">CONFIDENTIAL</option>
                <option value="INTERNAL USE">INTERNAL USE</option>
                <option value="OPEN">OPEN</option>
            </select>
        </div>

        <div class="container">
        <label for="VERSION">Enter version number:</label>
        <input type="text" id="VERSION" name="VERSION" required>
        </div>    

        <div class="container">
        <label for="DATE">Choose the date:</label>
        <input type="date" id="DATE" name="DATE" required>
        </div>    

            <div class="container">
                <div class="report-builder-header">
                    <label>Drag cards from right to left box to form skeleton of report (top to bottom):</label>
                </div>
                <div class="boxes-wrapper">
                    <div id="left" class="box"></div> <!-- Left box for dropping items -->
                    <div id="right" class="box">
                        <div class="card" draggable="true">Document Information</div>
                        <div class="card" draggable="true">Revision History</div>
                        <div class="card" draggable="true">Table Of Contents</div>
                        <div class="card" draggable="true">List Of Figures</div>
                        <div class="card" draggable="true">List Of Tables</div>
                        <div class="card" draggable="true">Introduction W/ Abbreviation</div>
                        <div class="card" draggable="true">Section With Image</div>
                        <div class="card" draggable="true">Section With Table</div>
                        <div class="card" draggable="true">Generic Section</div>
                        <div class="card" draggable="true">References</div>
                    </div>
                </div>
            </div>
            
        
        <div class="small">
                <input type="hidden" id="macro_sequence" name="macro_sequence">
                <input type="hidden" id="repetitions" name="repetitions">
                <div class="container">
                    <label for="output_filename">Output Filename:</label>
                    <input type="text" id="output_filename" name="output_filename" required>
                </div>
                <input type="submit" value="Generate Document">

        </div>       
    </form>

    <div class="circle" id="infoCircle">
        Help
        <div class="tooltip" id="tooltipText">
            On submit, the generated document will be saved in the source directory and the 
            default downloads directory. To adjust the base template, make changes to TEMPLATE.docx.  A backup of the template docx are saved in the "templates" folder.
        </div>
    </div>

    <div id="editor-container"></div>


    <label for="macro_sequence_display">Macro Sequence (for debugging)</label>
    <input type="text" id="macro_sequence_display" name="macro_sequence_display" readonly>


    <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
    <script src="{{ url_for('static', filename='script.js') }}"></script>
    
</body>
</html>

js:

const leftContainer = document.getElementById('left');
const cards = document.querySelectorAll('.card');
const docForm = document.getElementById('docForm');
const directoryButton = document.getElementById('directoryButton');
let selectedDirectoryHandle = null; // To store the directory handle

// Create a mapping of card names to their respective values
const cardMappings = {
    "Table Of Contents": 2,
    "List Of Figures": 3, 
    "List Of Tables": 4,
    "Introduction W/ Abbreviation": 5,
    "Section With Image": 6,
    "Section With Table": 7,
    "Generic Section": 8,
    "References": 9,
    "Document Information": 10,
    "Revision History": 11
};

cards.forEach((card) => {
    card.addEventListener('dragstart', (e) => dragStart(e, card.innerText)); // Pass card name to get the mapped value
    card.addEventListener('dragend', dragEnd);
});

leftContainer.addEventListener('dragover', dragOver);
leftContainer.addEventListener('drop', drop);

let draggedElement;
let placeholder; // Placeholder element to indicate where the card will be dropped

function dragStart(e, cardName) {
    e.dataTransfer.setData('text/plain', cardName);
    draggedElement = e.target;

    // Adding 'dragging' class to the element being dragged
    draggedElement.classList.add('dragging');
}

function dragEnd(e) {
    e.target.classList.remove('dragging'); // Remove the dragging class
    if (placeholder) placeholder.remove(); // Remove the placeholder if it exists
}

function dragOver(e) {
    e.preventDefault(); // Allow dropping
    const afterElement = getDragAfterElement(leftContainer, e.clientY);

    if (!placeholder) {
        placeholder = document.createElement('div');
        placeholder.className = 'draggable-placeholder'; // Placeholder to show where the dragged element will go
    }

    if (afterElement == null) {
        leftContainer.appendChild(placeholder); // Place at the end
    } else {
        leftContainer.insertBefore(placeholder, afterElement); // Insert before the found element
    }
}

function drop(e) {
    e.preventDefault();
    const data = e.dataTransfer.getData('text/plain');

    // If the card is already in the left container, simply move it to the new position
    if (draggedElement.parentElement === leftContainer) {
        // If placeholder exists, insert dragged element before the placeholder
        if (placeholder) {
            leftContainer.insertBefore(draggedElement, placeholder);
            placeholder.remove();
            placeholder = null;
        }
    } else {
        // If the card is new (from the right side), create a new element and append
        const droppedCard = document.createElement('div');
        droppedCard.className = 'draggable';
        droppedCard.innerText = data;

        droppedCard.setAttribute('draggable', 'true');
        droppedCard.addEventListener('dragstart', (e) => dragStart(e, data));
        droppedCard.addEventListener('dragend', dragEnd);

        droppedCard.addEventListener('click', function () {
            this.remove();
            updateMacroSequence();
        });

        if (placeholder) {
            leftContainer.insertBefore(droppedCard, placeholder);
            placeholder.remove();
            placeholder = null;
        }
    }

    updateMacroSequence();
}

function updateMacroSequence() {
    const droppedItems = Array.from(leftContainer.children)
        .map((item) => {
            const itemName = item.innerText;
            // Map item name to its corresponding value using cardMappings
            return cardMappings[itemName] || '';
        })
        .join(',');

    document.getElementById('macro_sequence').value = droppedItems;
    document.getElementById('macro_sequence_display').value = droppedItems;
}

// Helper function to determine where to place the dragged card
function getDragAfterElement(container, y) {
    const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')];

    return draggableElements.reduce((closest, child) => {
        const box = child.getBoundingClientRect();
        const offset = y - box.top - box.height / 2;

        if (offset < 0 && offset > closest.offset) {
            return { offset: offset, element: child };
        } else {
            return closest;
        }
    }, { offset: Number.NEGATIVE_INFINITY }).element;
}

docForm.addEventListener('submit', function (event) {
    event.preventDefault();
    // Update the macro_sequence and repetitions fields before submission
    const macroSequenceValue = document.getElementById('macro_sequence').value;
    document.getElementById('repetitions').value = macroSequenceValue;

    this.submit();
});

function updateMacroSequence() {
    const droppedItems = Array.from(leftContainer.children)
        .map((item) => {
            const itemName = item.innerText;
            // Map item name to its corresponding value using cardMappings
            return cardMappings[itemName] || '';
        });

    // Prepend '1' to the droppedItems array, fix duplication bug
    const finalSequence = ['1', ...droppedItems].join(',');
    
    document.getElementById('macro_sequence').value = finalSequence;
    document.getElementById('macro_sequence_display').value = finalSequence;
}

docForm.addEventListener('submit', function (event) {
    event.preventDefault();

    alert("Please refrain from interacting with the computer until the process is finished");

    const macroSequenceValue = document.getElementById('macro_sequence').value;
    document.getElementById('repetitions').value = macroSequenceValue;

    this.submit();
});


document.addEventListener("DOMContentLoaded", function() {
    // Import the Quill size attribute and whitelist
    var Size = Quill.import('attributors/style/size');
    Size.whitelist = ['11px','12px', '13px', '16px'];
    Quill.register(Size, true);

    // Toolbar options
    var toolbarOptions = [
        [{ 'size': ['11px','12px', '13px', '16px'] }],  // Size options with custom labels
    ];

    // Initialize Quill editor
    var quill = new Quill('#editor-container', {
        theme: 'snow',  // 'snow' is the default theme
        modules: {
            toolbar: toolbarOptions
        }
    });
});

setInterval() function not working JavaScript

I am designing a basic digital clock.
But the code doesn’t seem to work.

I am attaching my code:

My clock.js file:

setInterval( function() {
    var currentTime= new Date().toLocaleTimeString(); // gets time from local computer
    
    var hours= currentTime.getHours();
    var minutes= currentTime.getMinutes();
    var seconds= currentTime.getSeconds();
    var period= "AM";

    if(hours >=12){
        period="PM";
    }
    if(hours >= 13){
        hours= hours-12;
    }
    if(minutes <=9){
        minutes = "0" + minutes; // so, 9:6 --> 9:06
    }
    if(seconods <=9){
        seconds= "0" + seconds; 
    }

    var clockTime= hours + ":" + minutes + ":" + seconds + " " + period;

    var clockElement = document.getElementById("clock");
    clockElement.innerHTML = clockTime; 
}, 1000); // every 1000 milli seconds, the function will run


Here is my clock.html file:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="description" content="Digital Clock using JavaScript" >
        <meta name="viewport" content="width=device-width, initial-scale=1.0" >
        <title>Digital Clock</title>
        <link rel="stylesheet" href="clock.css" />
    </head>
    <body>
        <div id="banner"><span>Your local time</span></div>
        <div id="clock">
        </div>
        <script type="text/javascript" src="clock.js"></script>
    </body>
</html>

The setInterval() function doesn’t seem to work.
Or, is there any error elsewhere?

Getting subscribed topics from Firebase

Im trying to update the code that gets the subscribed topics of a user use react-native-firebase and Google apis

async function getInscricoes() {
    fetch(`https://iid.googleapis.com/iid/info/${await messaging().getToken()}?details=true`, {
        method: 'GET',
        headers: {
            'Authorization': `MY PRIVATE KEY`,
            'access_token_auth': true
        }
    })
        .then(response => response.json())
        .then(response => {
            console.log(response)
            if (response.rel?.topics) {
                const { topics } = response?.rel;

                setTopicos([...new Set(Object.keys(topics))]);
            }
        })
        .catch(e => {
            console.error(e)
        })
}

The code above is what im currently doing. It currently returns [TypeError: Network request failed]. When tried on Insomnia, returns the Google login page.

It is needed to authenticate using react-native-firebase/iid now?

Error “User Not logged in” after putting a user on phpmyadmin and connect with vscode

I can logged in in the Login tab but when I try to book an appoinment it always says “User not logged in”

Here’s my codes:

App.jsx

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import React from 'react';
import './App.css'
import Login from './Login'
import Dashboard from './Dashboard'
import ITSO from './ITSO'
import Itsoapp from './Itsoapp'
import Itsoconpage from './Itsoconpage'

function App() {
  return (
    <Router>
        <Routes>
            <Route path="/" element={<Login />} />
            <Route path="/dashboard" element={<Dashboard />} />
            <Route path="/itso" element={<ITSO />} />
            <Route path="/itsoapp" element={<Itsoapp />} />
            <Route path="/itsoconpage" element={<Itsoconpage />} />
        </Routes>
    </Router>
);
}

export default App

Login.jsx

import React, { useState } from "react"; // Added useState here

const Login = () => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [message, setMessage] = useState('');

    const handleLogin = async (e) => {
        e.preventDefault();

        // Make a POST request to the backend with email and password
        const response = await fetch('http://localhost/asbackend/login.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: `email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`,
        });

        const result = await response.json();
        setMessage(result.message);

        if (result.status === 'success') {
            // Redirect to dashboard or handle login success
            window.location.href = '/dashboard';
        }
    };

    return (
        <div>
            <div>
                <h1>Login</h1>
                <form onSubmit={handleLogin}>
                    <label htmlFor="email">Email</label><br />
                    <input
                        type="email"
                        id="email"
                        value={email}
                        onChange={(e) => setEmail(e.target.value)}
                        required
                    /><br /><br />

                    <label htmlFor="password">Password</label><br />
                    <input
                        type="password"
                        id="password"
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        required
                    /><br /><br />
                    
                    <button type="submit">Login</button>
                </form>
                {message && <p>{message}</p>}
            </div>
        </div>
    );
};

export default Login;

Dashboard.jsx

import React from 'react';
import { useNavigate } from 'react-router-dom';

const Dashboard = () => {
    const navigate = useNavigate();

    const goToLogin = () => {
        navigate('/');
    };

    const goToITSO = () => {
        navigate('/itso');
    };

    return (
        <div>
            <button type="submit" onClick={goToLogin}>Login</button>
            <br /><br />
            <br /><br />
            <button type="submit">Faculty</button>
            <br /><br />
            <button type="submit">Student's Discipline Office</button>
            <br /><br />
            <button type="submit" onClick={goToITSO}>ITSO</button>
            <br /><br />
            <button type="submit">Bulldog Exchange</button>
            <br /><br />
            <button type="submit">Accounting</button>
            <br /><br />
        </div>
    );
};

export default Dashboard;

ITSO.jsx

import React from 'react';
import { useNavigate } from 'react-router-dom';

const ITSO = () => {
    const navigate = useNavigate();

    const goToDashboard = () => {
        navigate('/dashboard');
    };

    const goToItsoapp = () => {
        navigate('/itsoapp');
    };

    return (
        <div>
            <button type="submit" onClick={goToDashboard}>Dashboard</button>
            <br /><br />
            <br /><br />
            <button type="submit" onClick={goToItsoapp}>Book An Appointment</button>
            <br /><br />
        </div>
    );
};

export default ITSO;

Itsoapp.jsx

import React, { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom'; // Import useNavigate

axios.defaults.withCredentials = true;

const Itsoapp = () => {
    const timeSlots = [];
    for (let i = 8; i <= 15; i++) {
        const hour = i % 12 === 0 ? 12 : i % 12;
        const period = i < 12 ? 'AM' : 'PM';
        timeSlots.push(`${hour}:00 ${period}`);
    }

    const [selectedSlot, setSelectedSlot] = useState(null);
    const [message, setMessage] = useState('');
    const navigate = useNavigate(); // Use useNavigate for navigation

    const handleConfirmBooking = async () => {
        if (!selectedSlot) {
            setMessage('Please select a time slot first.');
            return;
        }
    
        const [time, period] = selectedSlot.split(' ');
        const [hour, minute] = time.split(':').map(Number);
        const hour24 = period === 'PM' && hour !== 12 ? hour + 12 : hour;
        const formattedTime = `${String(hour24).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;
    
        try {
            const response = await axios.post('http://localhost/asbackend/itsoapp.php', {
                time_slot: formattedTime  // Ensure this is sent correctly
            }, {
                withCredentials: true  // Include this to send cookies
            });
    
            setMessage(response.data.message);  // Handle success or error message
        } catch (error) {
            console.error(error);
            setMessage('An error occurred while booking the appointment.');
        }
    };    

    return (
        <div>
            <h1>Book an Appointment</h1>
            <p>Select a time slot for your appointment:</p>
            <ul>
                {timeSlots.map((slot) => (
                    <li key={slot}>
                        <button onClick={() => setSelectedSlot(slot)}>{slot}</button>
                    </li>
                ))}
            </ul>
            {selectedSlot && (
                <div>
                    <p>You selected: {selectedSlot}</p>
                    <button onClick={handleConfirmBooking}>Confirm Booking</button>
                </div>
            )}
            {message && <p>{message}</p>}
        </div>
    );
};

export default Itsoapp;

Itsoconpage.jsx

import React from 'react';

const Itsoconpage = () => {
    return (
        <div>
            <h1>Booking Confirmed!</h1>
            <p>Your appointment has been successfully booked.</p>
        </div>
    );
};

export default Itsoconpage;

login.php

<?php
header("Access-Control-Allow-Origin: http://localhost:5173"); // The port of your frontend
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Methods: POST");
header('Content-Type: application/json');
header("Access-Control-Allow-Credentials: true");

session_start(); // Start the session at the top
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Database connection setup
$host = 'localhost';
$db   = 'appointsched_db'; 
$user = 'admin_as';    
$pass = '12345'; 
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    echo json_encode(['status' => 'error', 'message' => 'Database connection failed: ' . $e->getMessage()]);
    exit;
}

// Handle login
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $email = $_POST['email']; // Assume you're submitting the email
    $enteredPassword = $_POST['password'];

    // Retrieve stored password
    $stmt = $pdo->prepare('SELECT id, password FROM users WHERE email = ?');
    $stmt->execute([$email]);
    $user = $stmt->fetch();

    if ($user && $user['password'] === $enteredPassword) {
        // Password is correct
        $_SESSION['user_id'] = $user['id'];
        echo json_encode(['status' => 'success', 'message' => 'Logged in successfully!']);
    } else {
        // Invalid password
        echo json_encode(['status' => 'error', 'message' => 'Invalid email or password.']);
    }
    exit; // Exit after handling the login
}
?>

itsoapp.php

<?php
header("Access-Control-Allow-Origin: http://localhost:5173");
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Methods: POST");
header('Content-Type: application/json');
header("Access-Control-Allow-Credentials: true");

session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Database connection setup
$host = 'localhost';
$db   = 'appointsched_db'; 
$user = 'admin_as';    
$pass = '12345'; 
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    echo json_encode(['status' => 'error', 'message' => 'Database connection failed: ' . $e->getMessage()]);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // Retrieve raw POST data
    $inputData = json_decode(file_get_contents('php://input'), true);

    if (isset($inputData['time_slot'])) {
        $time_slot = $inputData['time_slot'];
    } else {
        echo json_encode(['status' => 'error', 'message' => 'Time slot not provided.']);
        exit;
    }

    // Get user_id from session
    $user_id = $_SESSION['user_id']; 

    // Check if the slot is already booked
    $stmt = $pdo->prepare('SELECT * FROM itsoapp WHERE time_slot = ?');
    $stmt->execute([$time_slot]);
    $existingBooking = $stmt->fetch();

    if ($existingBooking) {
        echo json_encode(['status' => 'error', 'message' => 'This time slot is already booked!']);
    } else {
        // Insert the new booking into the itsoapp table
        if ($user_id !== null) { // Check if user_id is set
            $stmt = $pdo->prepare('INSERT INTO itsoapp (user_id, time_slot) VALUES (?, ?)');
            $stmt->execute([$user_id, $time_slot]);

            echo json_encode(['status' => 'success', 'message' => 'Appointment booked successfully!']);
        } else {
            echo json_encode(['status' => 'error', 'message' => 'User not logged in.']);
        }
    }
}
?>

Please help I’m so stressed out. Thank you!

What I want it to do is to save the timeslots into the database. I put a login user in my database so that I can logged in without having to register or enroll. Thank you!

Issue with Firebase SignInWithRedirect

I’m trying to authenticate a user by using Firebase SignInWithRedirect while hosting my app on Firebase. When the user successfully logs into Google and the app returns from the redirect, the getRedirectResult function detects the redirect but returns null, causing the app to think the user was never logged in.

I’ve thoroughly checked the Firebase documentation, authorized domains, and the Firebase configuration in my firebase.js authentication file. I verified that my setup works perfectly with SignInWithPopup, but for mobile compatibility, I prefer to use SignInWithRedirect. The problem seems to persist only with the redirect flow.

What I’ve tried so far:

  1. Verified that the domain is correctly added in Firebase Auth.

  2. Checked the Firebase configuration file (firebase.js), and it’s set up as per Firebase’s documentation.

  3. Ensured that my Firebase-hosted app is correctly linked to my Firebase configuration in the project settings.

  4. Tried clearing browser history, cache, and even added the domain manually to the browser’s third-party cookies settings.

  5. I also have a .env file in my project, containing sensitive information like API keys, which I don’t want to expose to the public. The .env file is correctly used for environment variables, and it’s not included in my public code.

Despite all of this, after successfully returning from Google authentication, the result from getRedirectResult remains null.

File Structure:

  • firebase.js (configuration)

  • AuthContext.js (handles context and authentication logic)

  • index.jsx (login form)

Has anyone encountered this issue or found a solution for the recent Firebase changes? Any insights would be appreciated!

firebase.js

// Import the functions you need from the SDKs
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import { getDatabase } from "firebase/database";

// Your web app's Firebase configuration using environment variables
const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

// Optional: Initialize Firebase Analytics if needed
// Uncomment if you decide to use Analytics in the future
// import { getAnalytics } from "firebase/analytics";
// const analytics = getAnalytics(app);

// Initialize Firebase services
export const auth = getAuth(app);
export const db = getFirestore(app); 
export const realtimeDb = getDatabase(app);

AuthContext.js

import React, { createContext, useContext, useState, useEffect } from "react";
import {
  onAuthStateChanged,
  GoogleAuthProvider,
  signOut,
  signInWithRedirect,
  getRedirectResult,
} from "firebase/auth";
import { auth } from "./firebase";

// Create the AuthContext
const AuthContext = createContext();

// Custom hook to use the AuthContext
export const useAuth = () => useContext(AuthContext);

// AuthProvider component that wraps the app and manages auth state
export const AuthProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState(null); // Holds the authenticated user
  const [googleData, setGoogleData] = useState(null); // Holds the user info from Google
  const [signupComplete] = useState(false); // Track if the signup process is complete
  const [loading, setLoading] = useState(true); // Manage loading state while checking auth

  const googleProvider = new GoogleAuthProvider();

  googleProvider.setCustomParameters({
    prompt: "select_account", // Always prompt user to select an account
  });

  const loginWithGoogle = async () => {
    signInWithRedirect(auth, googleProvider);
  };

  // Use getRedirectResult to handle the result of a sign-in with redirect
  useEffect(() => {
    const handleRedirectResult = async () => {
      try {
        const result = await getRedirectResult(auth);
        console.log("Result is:", result)
        if (result) {
          const user = result.user;
          setCurrentUser(user);
          setGoogleData({
            fullName: user.displayName,
            email: user.email,
            uid: user.uid,
            photoURL: user.photoURL,
          });
          console.log("Redirect sign-in successful, user:", user);
        }
      } catch (error) {
        console.error("Error handling redirect result:", error);
      }
    };

    handleRedirectResult(); // Call function to handle redirect result
  }, []);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (user) {
        setCurrentUser(user);
        setGoogleData({
          fullName: user.displayName,
          email: user.email,
          uid: user.uid, // Get user UID from Google
          photoURL: user.photoURL,
        });
        console.log("User authenticated:", user);
      } else {
        setCurrentUser(null);
        setGoogleData(null); // Clear user data on logout
      }
      setLoading(false); // Set loading to false once auth state is determined
    });

    return () => unsubscribe(); // Clean up the subscription
  }, []);

  // Logout logic, clears currentUser and googleData
  const logout = async () => {
    console.log("Signing out");
    try {
      await signOut(auth);
      setCurrentUser(null); // Clear currentUser on logout
      setGoogleData(null); // Clear googleData on logout
    } catch (error) {
      console.error("Logout Error: ", error);
    }
  };

  // The value provided to components via AuthContext
  const value = {
    currentUser,
    googleData, // Provide googleData for use in components
    signupComplete, // Track signup completion status
    loginWithGoogle,
    logout,
    loading, // Pass loading state to prevent premature renders
  };

  // Render the children inside the context provider
  return (
    <AuthContext.Provider value={value}>
      {!loading && children} {/* Ensure that content is only rendered after auth check */}
    </AuthContext.Provider>
  );
};

LoginForm/index.jsx

import React, { createContext, useContext, useState, useEffect } from "react";
import {
  onAuthStateChanged,
  GoogleAuthProvider,
  signOut,
  signInWithRedirect,
  getRedirectResult,
} from "firebase/auth";
import { auth } from "./firebase";

// Create the AuthContext
const AuthContext = createContext();

// Custom hook to use the AuthContext
export const useAuth = () => useContext(AuthContext);

// AuthProvider component that wraps the app and manages auth state
export const AuthProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState(null); // Holds the authenticated user
  const [googleData, setGoogleData] = useState(null); // Holds the user info from Google
  const [signupComplete] = useState(false); // Track if the signup process is complete
  const [loading, setLoading] = useState(true); // Manage loading state while checking auth

  const googleProvider = new GoogleAuthProvider();

  googleProvider.setCustomParameters({
    prompt: "select_account", // Always prompt user to select an account
  });

  const loginWithGoogle = async () => {
    signInWithRedirect(auth, googleProvider);
  };

  // Use getRedirectResult to handle the result of a sign-in with redirect
  useEffect(() => {
    const handleRedirectResult = async () => {
      try {
        const result = await getRedirectResult(auth);
        console.log("Result is:", result)
        if (result) {
          const user = result.user;
          setCurrentUser(user);
          setGoogleData({
            fullName: user.displayName,
            email: user.email,
            uid: user.uid,
            photoURL: user.photoURL,
          });
          console.log("Redirect sign-in successful, user:", user);
        }
      } catch (error) {
        console.error("Error handling redirect result:", error);
      }
    };

    handleRedirectResult(); // Call function to handle redirect result
  }, []);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (user) {
        setCurrentUser(user);
        setGoogleData({
          fullName: user.displayName,
          email: user.email,
          uid: user.uid, // Get user UID from Google
          photoURL: user.photoURL,
        });
        console.log("User authenticated:", user);
      } else {
        setCurrentUser(null);
        setGoogleData(null); // Clear user data on logout
      }
      setLoading(false); // Set loading to false once auth state is determined
    });

    return () => unsubscribe(); // Clean up the subscription
  }, []);

  // Logout logic, clears currentUser and googleData
  const logout = async () => {
    console.log("Signing out");
    try {
      await signOut(auth);
      setCurrentUser(null); // Clear currentUser on logout
      setGoogleData(null); // Clear googleData on logout
    } catch (error) {
      console.error("Logout Error: ", error);
    }
  };

  // The value provided to components via AuthContext
  const value = {
    currentUser,
    googleData, // Provide googleData for use in components
    signupComplete, // Track signup completion status
    loginWithGoogle,
    logout,
    loading, // Pass loading state to prevent premature renders
  };

  // Render the children inside the context provider
  return (
    <AuthContext.Provider value={value}>
      {!loading && children} {/* Ensure that content is only rendered after auth check */}
    </AuthContext.Provider>
  );
};

The flow is as follows:

  1. A user clicks the “Sign In” button, which triggers the loginWithGoogle function inside the AuthContext.js file. This function calls signInWithRedirect to initiate the Google login process.

  2. The user is redirected to the Google login page, where they enter their credentials and successfully log in.

  3. After login, the user is redirected back to my application. In the AuthContext.js file, the getRedirectResult function is expected to retrieve the authentication result and provide the logged-in user’s information.

The issue: After the user is redirected back to the app, the getRedirectResult function detects the redirect but returns null instead of the expected user authentication result. This causes the app to assume the user is not logged in, even though the login process was successful on Google’s side.

Chunking using planes in THREE.js

I’m trying to make an infinitely generating world, the same way Minecraft does it, by using chunks that disappear and reappear depending on where the player is. I’m using a plane that generates points from a combination of Perlin and Simplex noise.

Anyway, When I load the points into the world all the chunks are the same. It’s because I’m using the same geometry for everyone. I’ve tried using object.matrixAutoUpdate = false; and object.updateMatrix(); but it doesn’t do anything. I’ve tried making each chunk a different geometry but the performance drops when it loads a new set of chunks.

Here’s the full code:

function updateChunk() {
    // Clear chunks
    while(ground.children.length > 0){ 
        ground.children[0].geometry.dispose()
        ground.remove(ground.children[0]); 
    }

    let size = (game.chunk.render * 2) + 1
    let sX = (Math.floor(plane.position.x / 1000) * 1000) - Math.floor((size / 2) * 1000)
    let sY = (Math.floor(plane.position.z / 1000) * 1000) - Math.floor((size / 2) * 1000)

    ground.position.set(sX, 0, sY)

    for(let y = 0; y < size; y++) {
        for(let x = 0; x < size; x++) {
            let g = new THREE.Mesh(geometry.clone(), material);
            let startX = ((sX / 1000) + x) * 100
            let startY = ((sY / 1000) + y) * 100
            let currentChunk = createChunk(startX, startY)

            //Setup Terrain
            for(let y2 = 0; y2 < 101;y2++) {
                for(let x2 = 0; x2 < 101; x2++) {
                    g.geometry.vertices[(y2 * 101) + x2].z = currentChunk[x2 + ',' + y2]
                }
            }

            g.rotation.x = Math.PI / -2
            g.position.set(x * 1000, 0, y * 1000)
            g.matrixAutoUpdate = false;
            g.updateMatrix();
            ground.add( g );
        }
    }
}
function createChunk(startX, startY) {
    let chunk = []
    for(let y = 0; y < 101; y++) {
        for(let x = 0; x < 101; x++) {
            chunk[x + ',' + y] = Math.abs(noise.perlin2((x + startX) / 100, (y + startY) / 100)) * 200;
        }
    }
    return chunk
}

Close child window when refreshed

How do you close a child window, a window opened from window.open, when the child window is refreshed or navigates elsewhere?

I have tried the code below but it doesn’t work:

const popout = window.open('', '', 'popout');
popout.onbeforeunload = () => {
    popout.close();
};

Similar code works to close the child window when the parent is refreshed:

const popout = window.open('', '', 'popout');
window.onbeforeunload = () => {
    popout.close();
};

I have seen other sites do this but I can’t figure it out, instead left with a blank popped out window that has to be manually closed.