link controller mathod “undefined” chart js

I’m having trouble with Chart.js where clicking on a chart segment always redirects to an undefined value. I have a Doughnut chart and want each segment to redirect to a specific URL based on the segment clicked. However, the redirection always leads to undefined.

Here’s the relevant part of my code:

Blade Template (Laravel):

<script>
        document.addEventListener('DOMContentLoaded', function() {
            var ctx = document.getElementById('teknisiChart').getContext('2d');

            var chartData = {
                labels: ['4 Tahun', '2-3 Tahun', '1 Tahun', 'Under 1 Tahun'],
                datasets: [{
                    data: [
                        {{ $countMoreThan4Years }},
                        {{ $countBetween2and3Years }},
                        {{ $count1YearAgo }},
                        {{ $countLessThan1Year }}
                    ],
                    backgroundColor: [
                        'rgba(255, 68, 68, 0.8)',
                        'rgba(255, 209, 91, 0.8)',
                        'rgba(223, 250, 125, 0.8)',
                        'rgba(114, 247, 137, 0.8)'
                    ],
                    borderColor: [
                        'rgba(255, 99, 132, 1)'
                    ],
                    borderWidth: 3
                }]
            };

            var teknisiChart = new Chart(ctx, {
                type: 'doughnut',
                data: chartData,
                options: {
                    onClick: function(evt, item) {
                        if (item.length > 0) {
                            var index = item[0].index;
                            console.log('Index:', index);
                            var category = ['more-than-4-years', '2-3-years', '1-year', 'under-1-year'][
                                index
                            ];
                            console.log('Category:', category);
                            window.location.href = `{{ url('/hardware') }}/${category}`;
                        }
                    },
                    responsive: true,
                    plugins: {
                        tooltip: {
                            callbacks: {
                                label: function(tooltipItem) {
                                    return chartData.labels[tooltipItem.dataIndex] + ': ' + tooltipItem
                                        .formattedValue;
                                }
                            }
                        }
                    }
                }
            });
        });
    </script>

Controller Method (Laravel):

<?php

namespace AppHttpControllers;

use CarbonCarbon;
use IlluminateHttpRequest;
use AppModelsItMasterHardware;

class HardwareController extends Controller
{
    public function show($ageCategory)
    {
        dd($ageCategory); // Debugging line
        $dateNow = Carbon::now();

        switch ($ageCategory) {
            case 'more-than-4-years':
                $dateLimit = $dateNow->copy()->subYears(4);
                $hardware = ItMasterHardware::where('tgl_beli', '<=', $dateLimit)->get();
                break;

            case '2-3-years':
                $dateLimitStart = $dateNow->copy()->subYears(3);
                $dateLimitEnd = $dateNow->copy()->subYears(2);
                $hardware = ItMasterHardware::whereBetween('tgl_beli', [$dateLimitStart, $dateLimitEnd])->get();
                break;

            case '1-year':
                $dateLimitStart = $dateNow->copy()->subYear();
                $dateLimitEnd = $dateNow->copy()->subYears(2);
                $hardware = ItMasterHardware::whereBetween('tgl_beli', [$dateLimitStart, $dateLimitEnd])->get();
                break;

            case 'under-1-year':
                $dateLimit = $dateNow->copy()->subYear();
                $hardware = ItMasterHardware::where('tgl_beli', '>=', $dateLimit)->get();
                break;

            default:
                abort(404);
        }

        return view('hardware.index', compact('hardware'));
    }
}

When I click on a segment in the Doughnut chart, it redirects to a URL with undefined as part of the path. I am trying to use the segment index to determine which URL to redirect to, but the resulting URL is not correct.

What I’ve Tried:
Debugging with console.log to check the index and category values.
Ensuring that the @json directive is correctly passing PHP variables to JavaScript.
Checking for JavaScript errors in the console.

How to correctly pass the segment index from Chart.js to construct a URL.
Any issues with the provided code that might be causing undefined values.

How to Merge Headers in tanstack/react-table

I’m working with @tanstack/react-table in a React app and trying to merge headers for a specific column like the example in the screenshot I posted. I want to merge the ones I circled green.

Here’s a screenshot of my current table where I want to merge the headers:
enter image description here

And here is my component table header:

   <thead className="bg-[#F7F7F8]">
      {table.getHeaderGroups().map((headerGroup) => (
        <tr key={headerGroup.id}>
          {headerGroup.headers.map((header) => (
            <th
              key={header.id}
              colSpan={header.colSpan}
              className={`border border-[#F1F1F3] p-2 text-base font-semibold text-[#171719] ${header.colSpan > 1 ? 'text-center' : 'text-center'}`}
              style={{ width: header.column.columnDef.size ? `${header.getSize()}px` : 'auto' }}
            >
              {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
            </th>
          ))}
        </tr>
      ))}
    </thead>

And here is my current column configuration:

import { createColumnHelper } from '@tanstack/react-table';
import type { ColumnDef } from '@tanstack/react-table';

type Data = {
  검수: string;
  시도명: string;
  시군구명: string;
  읍면동명: string;
  합계: { 계: number; 남: number; 여: number };
  '10대': { 계: number; 남: number; 여: number };
  // Add dummy data for other groups
};

const columnHelper = createColumnHelper<Data>();

const columns: ColumnDef<Data, any>[] = [
  columnHelper.accessor('검수', {
    header: '검수',
    size: 50,
  }),
  columnHelper.accessor('시도명', {
    header: '시도명',
    size: 100,
  }),
  columnHelper.accessor('시군구명', {
    header: '시군구명',
    size: 100,
  }),
  columnHelper.accessor('읍면동명', {
    header: '읍면동명',
    size: 100,
  }),
  columnHelper.group({
    header: '합계',
    columns: [
      columnHelper.accessor('합계.계', {
        header: '계',
        size: 100,
      }),
      columnHelper.accessor('합계.남', {
        header: '남',
        size: 100,
      }),
      columnHelper.accessor('합계.여', {
        header: '여',
        size: 100,
      }),
    ],
  }),
  // Repeat for group
];

Is there a way to validate and allow only https url’s using .isUri i.e. without using Regex in JavaScript?

Is there a way to validate “https” url’s using .isUri in javascript (it should return true only for https url’s)? (any other method should be fine except regex)

https://test.com //true
test.com // false
http://test.com // false
http://test // false

code snippet (below works great but it returns true for http url’s, instead it should return false for http url’s): –

const validateUrl = (url) => {
  return !!validUrl.isUri(url);
};

Thanks

Issue with Axios POST request to Flask backend in AI model

I’m working on a React frontend and Flask backend, and I’m encountering a CORS issue when sending a POST request from the frontend to a Flask route (/predict). The GET request to the root (/) works fine, but the POST request fails with the following error: Error photo

I’ve already added CORS(app, resources={r"/*": {"origins": "*"}}) in the Flask backend, but it changes nothing.

Note: The AI model works fine with Google Colab.

react code:

import React, { useEffect, useState } from 'react';
import axios from 'axios';

function Home() {
    const [inputValue, setInputValue] = useState('');
    const [responseMessage, setResponseMessage] = useState('');
    const [message, setMessage] = useState('');
    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await axios.get('http://localhost:5000/');
                setMessage(response.data.message);
            } catch (error) {
                console.error("There was an error fetching the data!", error);
            }
        };

        fetchData();
    }, []);
    const handleSubmit = async (e) => {
        e.preventDefault();

        try {
            const response = await axios.post('http://localhost:5000/predict', { comment: inputValue }, {
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            console.log('a');
            console.log(response);
            setResponseMessage(`Prediction: ${response.data.prediction}`);
        } catch (error) {
            console.error("There was an error sending the data!", error);
        }
    };

    return (
        <div className="App">
            <div className="form-container">
                {message && <h2>{message}</h2>}
                <form onSubmit={handleSubmit}>
                    <input
                        type="text"
                        placeholder="Enter a comment"
                        value={inputValue}
                        onChange={(e) => setInputValue(e.target.value)}
                        required
                    />
                    <button type="submit">Analyze</button>
                </form>
                {responseMessage && <p className="response">{responseMessage}</p>}
            </div>
        </div>
    );
}

export default Home;

flask code:

import pandas as pd
from pandas import read_csv
import numpy as np
import sklearn
from sklearn.model_selection import cross_val_score
from sklearn.metrics import confusion_matrix
from sklearn.naive_bayes import GaussianNB, MultinomialNB
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})

@app.route('/')
def home():
    return jsonify({"message": "Comment Spam Analysis"})

@app.route('/predict', methods=['POST'])
def predict():
    data=read_csv("./data/comments.csv")
    df = data[['CONTENT','CLASS']]
    df_x=df['CONTENT']
    df_y=df.CLASS
    corpus=df_x
    vectorizer=CountVectorizer()
    X=vectorizer.fit_transform(corpus)
    x_train,x_test,y_train,y_test=train_test_split(X,df_y,test_size=0.3,random_state=42)
    clf=MultinomialNB()
    clf.fit(x_train,y_train)
    clf.score(x_test,y_test)
    v=cross_val_score(clf,x_train,y_train,cv=10)
    v.mean()
    fit = clf.fit(x_train, y_train)
    predict = fit.predict(x_test)
    cmatrix = confusion_matrix(y_test, predict)
    print(cmatrix)
    from sklearn.metrics import classification_report
    print(classification_report(y_test,predict))
    import joblib as joblib
    joblib.dump(clf,'./model/comment_model.pkl')
    print("model dumped")
    clf=joblib.load('./model/comment_model.pkl')
    print("model loaded")
    
    if request.method=='POST':
        comment = request.form['comment']
        data = [comment]
        vect = vectorizer.transform(data).toarray()
        my_predection= clf.predict(vect)
    
    # return jsonify({"prediction": my_predection})
    return jsonify({"prediction": my_predection[0]})
    
if __name__ == '__main__':
    app.run(debug=True)

Can anyone help me figure out what I’m missing? Any advice on how to fix this CORS issue with the POST request or how I am using the AI model?

JS Track scroll inputs rather than scroll position

Is there any way to get the “amount” of scroll inputs rather than the scroll position?

I have a scroll variable that resets to 0 on inactivity, and then when I start scrolling I don’t want it to start at my position (for example 500), but rather 1,2,3, etc.

Hope this makes sense!

How can I proxy [[set]] on all JavaScript array objects?

I’m trying to proxy the [[set]] method on JavaScript arrays. Is it possible to proxy all arrays, and not just a specific one? My handler would check the object being set in the array and if it hasOwnProperty('xyz') then console.log it.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy says that
I would do that with something like

set(target, prop, val) { // to intercept property writing
    if (val.hasOwnProperty('xyz') {
        console.log(prop);
    };
    target[prop] = val;
    return true;
  }

However, Proxy seems to only work on single objects. Given that there is no prototype [[set]], how can I proxy this operation for every array?

Ideally, it would work something like this:

Array = new Proxy(Array, {
set(target, prop, val) { // to intercept property writing
    if (val.hasOwnProperty('xyz') {
        console.log(prop);
    };
    target[prop] = val;
    return true;
  }
});

let obj = {xyz: 1}
let list = [];
list[0] = obj; // would log 1

I tried the above code snippet, but it does not redefine the method for every array. One possible method could be to proxy Array.prototype.constructor to return an array with the [[set]] pre-proxied to have the check for the value.

Thanks!

About ethers.js,Why did contractUSDT.on only listen once before the program terminated?

const ethers = require('ethers');

const ALCHEMY_SEPOLIA_URL = 'xxxxx';//Sepolia测试网络
const provider = new ethers.JsonRpcProvider(ALCHEMY_SEPOLIA_URL);

const contractAddress = '0xbDeaD2A70Fe794D2f97b37EFDE497e68974a296d';

const abi = [
    "event Transfer(address indexed from, address indexed to, uint value)"
];

const contractUSDT = new ethers.Contract(contractAddress, abi, provider);

const main = async () => {
    try {
        console.log("n1.利用contract.once(), 监听一次Transfer事件");
        const oncePromise = new Promise((resolve) => {
            contractUSDT.once('Transfer', (from, to, value) => {
                console.log(
                    `${from} -> ${to} ${ethers.formatUnits(ethers.getBigInt(value),0)}`
                );
                resolve();
            })
        })
        await oncePromise;
        console.log("n2. 利用contract.on(),持续监听Transfer事件");
        contractUSDT.on('Transfer', (from, to, value)=>{
            console.log(
             `${from} -> ${to} ${ethers.formatUnits(ethers.getBigInt(value),0)}`
            )
        });
    }
    catch(e){
        console.log(e);
    }
}
main()

Program running results:
enter image description here
Why did contractUSDT.on only listen once before the program terminated?
Sometimes contractUSDT.on doesn’t even listen for an event once, and the program terminates.

My final goal is to achieve sequential output on the terminal:

console.log("n1.利用contract.once(), 监听一次Transfer事件");
console.log(`${from} -> ${to} ${ethers.formatUnits(ethers.getBigInt(value),0)}`);
console.log("n2. 利用contract.on(),持续监听Transfer事件");
console.log(`${from} -> ${to} ${ethers.formatUnits(ethers.getBigInt(value),0)}`)

Is this the new way to represent async/await without try-catch block

async function fetchData() {
    const [error, response] = await fetch('https://jsonplaceholder.typicode.com/todos/1')
    if (error) {
        console.log(error);
        return
    }
    
    const [e, data] = await response.json()
    if (e) {
        console.log(e);
        return
    }
    return data
}

fetchData()

I came across a LinkedIn post showing this it the new way to represents async/await without using try-catch block, is this right correct me if its wrong. its not working for me.

Interactive Data Visualization for the Web Chapter 5 question about converting strings to floats

I am following the book Interactive Data Visualization for the Web to teach myself how to use D3 (using version 5 of D3) and I am having trouble understating what I am doing wrong, this is on page 76.

There is a very simple .csv file (food.csv) that contains two columns, one titled ‘Food’ the other ‘Deliciousness’. I am loading the file into D3 using the following code:

<!DOCTYPE html>
<html lang = "en">
    <head>
            <meta charset="utf-8">
            <title>Loading csv File</title>
            <script type="text/javascript" src="d3.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            d3.csv("food.csv",function(data){
                console.log(data);
            });
        </script>
    </body>
</html>

Since the Deliciousness values are loaded as strings, the book defines a function that converts the strings to floats, the following is code for that:

<!DOCTYPE html>
<html lang = "en">
    <head>
            <meta charset="utf-8">
            <title>Loading Data and Converting Data Type</title>
            <script type="text/javascript" src="d3.js"></script>
    </head>
    <body>
        <script type="text/javascript">

            var rowConverter = function(d){
                return {
                    Food: d.Food,
                    Deliciousness: parseFloat(d.Deliciousness)
                };
            }

            d3.csv("food.csv", rowConverter, function(data){
                console.log(data);
            });

        </script>
    </body>
</html>

When I do this, the data type of the Deliciousness value is not changing. Am I missing something very simple?

I have looked at the documentation for parseFloat and that does not seem to be the issue. I am wondering if I am just misunderstand where the rowConverter function should be defined.

I do not have a lot of experience coding in html or JavaScript so that may be the issue.

JS Google Maps API marker zoom-in same color in cluster

There are multiple clusters on the map, and multiple markers within the clusters.

When zoomed in far away, the markers appear in different colors, but when zoomed in closer, all markers, including those in other clusters, change to the same color.

zoom-out
enter image description here

zoom-in
enter image description here

async function addMarkerCluster(json) {
    const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker");

    const item = JSON.parse(json);
    
    const hexColor = "#" + item.Color;
    
    const clusterMarkers = [];

    item.Items.map(data => {
        const style = new PinElement({
            background: hexColor,
            borderColor: hexColor,
            glyph: data.glyph,
            glyphColor: "white"
        });

        const marker = new AdvancedMarkerElement({
            map: map,
            position: parseCoordinateObj(data.Location),
            content: style.element,
            gmpClickable: true
        });

        const contentString =
            '<div id = "info-header">' +
            '<h4>' + data.Title + '</h4>' +
            '</div>' +
            '<div id = "info-body">' +
            '<p>' + data.Description + '</p>' +
            '</div>';

        marker.addListener("gmp-click", () => {
            infowindow.close();
            infowindow.setContent(contentString);
            infowindow.open({
                anchor: marker,
                map
            });
        });

        clusterMarkers.push(marker);
    })

    let algorithm = new markerClusterer.SuperClusterAlgorithm({
        maxZoom: 15
    });

    const cluster = new markerClusterer.MarkerClusterer({
        map: map,
        markers: clusterMarkers,
        algorithm, algorithm,
        renderer: {
            render: ({
                count,
                position
            }, stats, map) => {
                const style = new PinElement({
                    background: hexColor,
                    borderColor: hexColor,
                });

                return new AdvancedMarkerElement({
                    map: map,
                    position: position,
                    content: style.element
                })
            }
        }
    });
}

I wanted the same color to remain the same even when zooming in.

The latest YouTube video does not load, previously it did

Recently, this same API worked for me by directing me to the most recent video on the corresponding YouTube channel. However, now when I click the button, it takes me to a video from 2 months ago instead of the latest one. I don’t understand what happened; I didn’t make any changes, and it has stopped working as it did before. I’m attaching the code to see if someone could help me.

async function getLastVideo() {
    const url = `https://www.googleapis.com/youtube/v3/search?key=${apiKey}&channelId=${channelId}&order=date&part=snippet&type=video&maxResults=1`;

    try {
        const response = await fetch(url);
        const data = await response.json();
        if (data.items.length > 0) {
            const lastVideoId = data.items[0].id.videoId;
            const lastVideoUrl = `https://www.youtube.com/watch?v=${lastVideoId}`;

            // Actualiza los enlaces con los IDs únicos
            document.getElementById('youtube-last-video-1').href = lastVideoUrl;
            document.getElementById('youtube-last-video-2').href = lastVideoUrl;
            document.getElementById('youtube-last-video-3').href = lastVideoUrl;
        } else {
            console.error('No se encontraron videos.');
        }
    } catch (error) {
        console.error('Error al obtener el último video:', error);
    }
}

// Llama a la función cuando la página cargue
window.onload = getLastVideo;

I tried a few different approaches to fix the issue, though I don’t recall all the details. I attempted to:

  • Check the API documentation to ensure I was using it correctly.
  • Verify the API key and endpoint for any potential issues.
  • Clear the cache and refresh the page to rule out any caching problems.
  • Review recent changes in my code or environment that might have affected the API’s behavior.

I was expecting the button to direct me to the most recent video on the YouTube channel, as it did before. Despite these attempts, the issue persists.

Firebase delay in fetching user

I have an app and want to make it so, when the app boots up, it checks if the user has set a state that indicates they want to stay signed in. If they did it brings them to home screen, if they didnt it brings them to the normal launch page. I have this:

const app = initializeApp(firebaseConfig);
const auth = initializeAuth(app, {
  persistence: getReactNativePersistence(AsyncStorage),
});

  useEffect(() => {
    const checkAuthStatus = async () => {
      try {
        const staySignedIn = await AsyncStorage.getItem("staySignedIn");
        const authInstance = getAuth();
        const user = authInstance.currentUser;

        const lastLoginTime = await AsyncStorage.getItem("lastLoginTime");

        if (lastLoginTime) {
          const currentTime = new Date();
          const lastLoginDate = new Date(lastLoginTime);

          const diffInTime = currentTime - lastLoginDate;
          const diffInDays = diffInTime / (1000 * 3600 * 24);

          if (diffInDays > 90) {
            await signOut(authInstance);
            await AsyncStorage.removeItem("lastLoginTime");
            await AsyncStorage.removeItem("staySignedIn");
            setLoading(false);
            return;
          }
        }

        if (staySignedIn === "true" && user) {
          router.push("/(tabs)/shared/Home");
        } else {
          setLoading(false);
        }
      } catch (error) {
        console.error("Error checking authentication status:", error);
        setLoading(false);
      }
    };

    checkAuthStatus();
  }, []);

`

It seems as though it takes around .03 seconds for firebase to fetch the user… longer than it takes for my component to mount. This means that even if there is a user, it returns null for them. I thought about listening for a state change in auth, but the problem is that if the user is actually null, the state doesn’t change, and then the next time the state changes (say they hit the sign up button where it is supposed to bring them to an otp screen) it will behave as if they had been a logged in user and bring them to the home screen. Is there anything I can do aside from adding a delay?

I was attempting to have a user that chooses to stay logged in be logged in, without changing any other functionality of my application.

Clarifai – Getting 400 error when running face-detection

When I put in a URL and run the API call, I get a 400 error specifically pointing out the fetch() function. I am unsure what I am doing wrong or if my code is wrong. My current code:

import { useState } from 'react'
import './App.css'
import FaceRecognition from './components/FaceRecognition'
import ImageLinkForm from './components/ImageLinkForm'
import Logo from './components/Logo'
import Navigation from './components/Navigation'
import Rank from './components/Rank'

function App() {
  const [imageInput, setImageInput] = useState('');
  const [imageURL, setImageURL] = useState('');

  const returnClarifyRequestOptions = (imageURL) => {
    const PAT = '123456778956332';
    const USER_ID = 'username';
    const APP_ID = 'appname';
    const IMAGE_URL = imageURL;

    const raw = JSON.stringify({
      "user_app_id": {
        "user_id": USER_ID,
        "app_id": APP_ID
      },
      "inputs": [
        {
          "data": {
            "image": {
              "url": IMAGE_URL
            }
          }
        }
      ]
    });

    const requestOptions = {
      method: 'POST',
      mode: 'no-cors',
      headers: {
        'Accept': 'application/json',
        'Authorization': 'Key ' + PAT
      },
      body: raw
    };

    return requestOptions;
  }

  const handleChange = (event) => {
    setImageInput(event.target.value);
  }

  const onButtonSubmit = () => {
    setImageURL(imageInput);
    fetch("https://api.clarifai.com/v2/models/" + 'face-detection' + "/outputs", returnClarifyRequestOptions(imageInput))
      .then(response => response.json())
      .then(result => console.log(result))
      .catch(error => console.log('error', error));
  }

  return (
    <>
      <Navigation />
      <Logo />
      <Rank />
      <ImageLinkForm
        handleChange={handleChange}
        onButtonSubmit={onButtonSubmit}
      />
      <FaceRecognition imageUrl={imageURL} />
    </>
  )
}

export default App

I have tried changing my PAT, my App ID, and changing the setting on my clarifai app but I have not had any luck on figuring out the issue at hand. I also tried hard coding some URL value to see if it works, but I am not sure what to change.

Struggling with javascript game logic: Word guessing challenge

I’m studying JavaScript, and as an exercise, I decided to copy a little game I like to help me learn, but I’m struggling and would like to know if someone can explain how to solve this.

I don’t like asking for help, but after two days of struggling and asking AI, I decided to come here.

The game consists of guessing the word of the day, and it has the following behavior:

  1. If the letter exists in the word of the day, mark it as isPresent true;
  2. If the letter exists in the exact same position as in the word of the day, mark it as isCorrect true;
  3. If the first letter matches the first letter in the word of the day, mark it as isFirst true;
  4. If the last letter matches the last letter in the word of the day, mark it as isLast true.

I’m having a lot of difficulty with this part:

  1. If there are letters in the same sequence as in the word of the day, mark them as isNeighbor. For example, if the word of the day is “example” and the guess is “imply”, “mpl” should get isNeighbor true. I wrote this part, but it doesn’t work in all cases;
  2. If the letters are not in the exact same position in the guess and in the word of the day, but they are in the same order, they should be marked as isCorrect true. If the word of the day is “example” and the guess is “permit”, “p” and “e” would be isCorrect, but “m” wouldn’t, as in “example”, it appears before “p”. I simply don’t know what to do, and I’ve been stuck here for two days.

Here’s a screenshot of the game instructions I’m copying, so you can understand better.

My code looks like this:

// Word of the day
const WORD_OF_THE_DAY = "example";

// Main function
const guessWord = (inputValue) => {
  let originalLetterUsed = Array(WORD_OF_THE_DAY.length).fill(false);

  /**
   * Finds the index of the first occurrence of an unused letter from the word of the day.
   * @param {string} letter - Letter to find in the word of the day.
   * @returns {number} - The index of the letter, or -1 if not found.
   */
  const findAvailableLetterIndex = (letter) => WORD_OF_THE_DAY.split('').findIndex((char, charIdx) => {
    return char === letter && !originalLetterUsed[charIdx];
  });

  const word = [...inputValue].map((letter, letterIdx) => {
    const availableIndex = findAvailableLetterIndex(letter);
    let currentLetter = {
      letter,
      isCorrect: false,
      isPresent: false,
      isNeighbor: false,
      isFirst: false,
      isLast: false
    }

    // If the letter exists in the word of the day
    if (availableIndex > -1) {
      originalLetterUsed[availableIndex] = true;
      currentLetter.isPresent = true;

      // Checks if the next letter in the typed word matches the next letter of the word of the day,
      // or if the previous letter in the typed word matches the previous letter of the word of the day
      if (
        inputValue[letterIdx + 1] === WORD_OF_THE_DAY[availableIndex + 1] ||
        inputValue[letterIdx - 1] === WORD_OF_THE_DAY[availableIndex - 1]
      ) {
        currentLetter.isNeighbor = true;
      }

      // Check if the current letter mathes with the letter of the word of the day in the same position
      if (letter === WORD_OF_THE_DAY[availableIndex]) {
        currentLetter.isCorrect = true;
      }

      // Check if the letter is in the correct order
      /* if (???) {
        currentLetter.isCorrect = true;
      } */

      // Check if the first letter matches
      if (letterIdx === 0 && letter === WORD_OF_THE_DAY[0]) {
        currentLetter.isFirst = true;
      }

      // Check if the last letter matches
      if (letterIdx === inputValue.length - 1 && letter === WORD_OF_THE_DAY[WORD_OF_THE_DAY.length - 1]) {
        currentLetter.isLast = true;
      }
    }

    return currentLetter;
  });

  return word;
}

console.log("permit", guessWord("permit"));
console.log("imply", guessWord("imply"));
console.log("excuse", guessWord("excuse"));
console.log("example", guessWord("example"));