How to do Custom Authentication in Framer Website

TLDR: Can software like Auth0 be easily integrated in a Framer website?

I am new to web dev, I am making a website in Framer, which has a nice GUI and some coding elements. While I wouldn’t call this actual web dev, as I don’t know what’s going on under the hood, it is a good stepping stone.

I am trying to create a membership only site in Framer, where I can have people create accounts, and choose subscriptions. To do this, I found a third party software called Hound. This lets me create a login, signup, logout and settings component and handels all the backend for me.

The way it works is that I can block certain webpages for members that are on a certain subscription. But I want to create a master login credential, as in some login credentials which don’t need to be on a subscription but can still access all the pages on the site. What I thought of doing was making like a “free” plan an enrolling the account I wan to be the master on that plan, but when you select a subscription on Hound, this is what happens:

enter image description here

All subscriptions become visible to the user.

So essentially, my question is: is it possible to have this master login credential with any other framework that can be easily integrated with framer and is free to use? I found out about Auth0, but I can’t find any tutorials on it online on how to integrate it with framer and get it working. Any advice on this will be greatly appreciated! Thank you!

to fix an error [FirebaseError: Failed to get document because the client is offline

I am developing an app by your firebase.
I m trying to save and refer some datas from cloud firestore.
and I found the following error.
[FirebaseError: Failed to get document because the client is offline.]
i confirmed
1.network environment
2.security rules
3.firewall
and so on
Could you please help me to fix it

import { initializeApp } from 'firebase/app';
// Optionally import the services that you want to use
import { getAuth } from "firebase/auth"
import { getDatabase }from "firebase/database";
import { getFirestore } from "firebase/firestore";
// import database from '@react-native-firebase/database';
// import {...} from "firebase/firestore";
// import {...} from "firebase/functions";
// import {...} from "firebase/storage";

// Initialize Firebase(there is no data due to private information)
const firebaseConfig = {
  apiKey: 
  authDomain: 
  databaseURL: 
  projectId: 
  storageBucket: ,
  messagingSenderId: ,
  appId: ,
  measurementId:
};

const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
// Initialize Realtime Database and get a reference to the service
export const database = getDatabase(app);
// For more information on how to access Firebase in your project,
// see the Firebase documentation: https://firebase.google.com/docs/web/setup#access-firebase
export const firestore = getFirestore(app);
// https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

import React, { useState, useEffect } from "react";
import { View,ActivityIndicator, Text, ScrollView, StyleSheet, TextInput, Button ,Switch,Dimensions,Image,Alert} from "react-native";
import { useNavigation } from '@react-navigation/native'; // useNavigationを追加
import MapView, { Marker ,Polyline} from 'react-native-maps';
import {requestLocationPermission,getCurrentLocation,writeMyLocationData} from '../../sockets/googlemap'
import {findPlace,fetchRoute} from '../../sockets/googleroute'
import { ref,onChildAdded} from "firebase/database";
import { database,firestore } from '../../firebaseConfig'; // Firebaseのデータベースを正しくインポートする必要があります
import { Input} from 'react-native-elements'; // React Native Elementsからボタンをインポート

import { doc, setDoc , collection, addDoc ,getDocs,getDoc} from "firebase/firestore"; 

const Main = () => {
    const [otherRiders, setOtherRiders] = useState([]); 
    const dbref = ref(database); //取得したいデータのパスを指定
    console.log("kakunin",otherRiders)
    const [routeInfo, setRouteInfo] = useState({ origin: "", destination: "" });
    const navigation = useNavigation(); // useNavigationフックを使用してnavigationオブジェクトを取得
    const [myCurrentLocation,setMyCurrentLocation] = useState({
        latitude: 0,
        longitude: 0,
    })
    const [myDestination,setMyDestination] = useState({
        latitude: 0,
        longitude: 0,
    })
    const [myOrigin,setMyOrigin] = useState({
        latitude: 0,
        longitude: 0,
    })
    // DB を取得している
    
    const [isMapReady, setIsMapReady] = useState(false);
    const [isEnabled, setIsEnabled] = useState(false);
    const toggleSwitch = () => setIsEnabled(previousState => !previousState);
    const iconImage = require('../../assets/kurumi.jpg');
    const myDestinationIcon = require('../../assets/flag.png');
    const myOriginIcon = require('../../assets/start.png');

    // requestLocationPermission();
    useEffect(() => {
        requestLocationPermission(setMyCurrentLocation,myCurrentLocation,setIsMapReady);
        const childAddedListener = onChildAdded(dbref, function (snapshot) {
        let data = snapshot.val();
        setOtherRiders(data);
    });
    const saveUserData = async () => {
        try {
        const docRef = await addDoc(collection(firestore, "users"), {
                name: "Tokyo",
                });
                console.log("Document written with ID: ", docRef.id);
            } catch (e) {
                console.error("エラーが発生しました:", e);
            } finally {
                console.log("保存が完了しました!");
            }
    };

    const fetchUserData = async () => {
        try {
// Query a reference to a subcollection
            const docRef = doc(firestore, "users", "FHNX6msuu6rOLjRGlalw");
            const docSnap = await getDoc(docRef);
            console.log("docSnap",docSnap)
        } catch (e) {
            console.error("エラーが発生しました:", e);
        } finally {
            console.log("しゅとく");
        }
    };
    saveUserData()
    fetchUserData(); // 非同期関数を呼び出す


    // const testt = async ()=>{
    //     // Add a new document with a generated id.
    //            console.log("ssssssssss")
        
    //     const docRef = await addDoc(collection(firestore, "users"), {
    //     name: "Tokyo",
    //     });
    //     console.log("Document written with ID: ", docRef.id);
    // }
    // test()
    // testt()
    return () => {
        // コンポーネントがアンマウントされたときにイベントリスナーを解除する
        childAddedListener();
    };
        
},[]);

    return (
        isMapReady ? ( // マップが準備完了したら表示
        <ScrollView  style={styles.Wrapper}>
            
                <View style={styles.mapContainer}>
                    <MapView style={styles.map}
                        initialRegion={{
                            latitude: myCurrentLocation.latitude,
                            longitude: myCurrentLocation.longitude,
                            latitudeDelta: 0.0922,
                            longitudeDelta: 0.0421,
                        }}
                    >
                        {/* <Marker
                            coordinate={{
                                latitude: myCurrentLocation.latitude,
                                longitude: myCurrentLocation.longitude,
                            }}
                        >
                            <Image style={styles.icon} source={iconImage} />
                        </Marker> */}
                    <Marker
                            coordinate={{
                                latitude: myOrigin.latitude,
                                longitude: myOrigin.longitude,
                            }}
                        >
                            <Image style={styles.icon} source={myOriginIcon} />
                        </Marker>
                        <Marker
                            coordinate={{
                                latitude: myDestination.latitude,
                                longitude: myDestination.longitude,
                            }}
                        >
                            <Image style={styles.icon} source={myDestinationIcon} />
                        </Marker>
                            <Polyline
                            coordinates={[
                                { latitude: myOrigin.latitude, longitude: myOrigin.longitude },
                                { latitude: myDestination.latitude, longitude: myDestination.longitude },
                            ]}
                            strokeColor="#FF0000" // 線の色
                            strokeWidth={2} // 線の太さ
                        />
                        {
                            otherRiders.map((rider,index)=>{
                                console.log("rider",rider)
                                let diferLat = Math.abs(myCurrentLocation.latitude - rider.latitude) < 1 ? true:false;
                                let diferLot = Math.abs(myCurrentLocation.longitude - rider.longitude) < 1 ? true:false;
                                // if(diferLat && diferLot){
                                //     Alert.alert("手を振りましょう")
                                // }
                        return(
                        <Marker
                            key={index} // ここで一意のキーを提供する
                            coordinate={{
                                latitude: rider.latitude,
                                longitude: rider.longitude,
                            }}
                        >
                            <Image style={styles.icon} source={iconImage} />
                        </Marker>

                        ) 
                            })
                        }


                    </MapView>
                </View>                
                <Text style={styles.direction}>出発地</Text>
                <Input
                    placeholder={'出発地を入力してください'}
                    value={routeInfo.origin}
                    onChangeText={text => setRouteInfo({ ...routeInfo, origin: text })}
                />
                <Text style={styles.direction}>目的地</Text>
                <Input
                    placeholder={'到着地を入力してください'}
                    value={routeInfo.destination}
                    onChangeText={text => setRouteInfo({ ...routeInfo, destination: text })}
                />
            <View>
                <Button
                    title="ルートを検索する"
                    onPress={() => fetchRoute(setMyOrigin,setMyDestination,routeInfo)}
                />
            </View>
            <View>
                <Button
                    title="戻る"
                    onPress={() => navigation.navigate('Top')}
                />
            </View>
        </ScrollView>
        ):  <View style={styles.waitContainer}><ActivityIndicator size="large" color="#0000ff" /><Text style={styles.waitText}>少々お待ちください...</Text></View>
    )
}

export default Main;

const { height } = Dimensions.get("window");
const mapHeight = height * 0.5; // 画面の半分の高さ
const styles = StyleSheet.create({
    Wrapper:{
        flex: 1, // 画面の半分のサイズに設定
    },
    direction: {
        fontSize: 12,
        padding:10
    },
    infomation: {
        fontSize: 12,
        padding:10
    },
    subTitle: {
        fontSize: 14,
        textAlign: "center",
        padding:5
    },
    mapContainer: {
        height: mapHeight,
        justifyContent: 'center',
        alignItems: 'center',
    },
    map: {
        ...StyleSheet.absoluteFillObject,
    },
    markerContainer: {
        backgroundColor: 'blue',
        padding: 5,
        borderRadius: 5,
    },
    markerText: {
        color: 'white',
        fontWeight: 'bold',
    },
    imputWrapper: {
        alignItems: "center", // 横方向に中央揃え
        padding: 20
    },
    imputContainer:{
        width:'100%',
        marginBottom:10
    },
    imputBox: {
        height: 40,
        borderWidth: 1,
    },
    icon: {
      width: 28,
      height: 28,
    },
    waitScrollViewContent: {
    flex: 1,
    width:'100%',
  },
    center: {
    flex: 1,
        justifyContent: 'center',
        alignItems: 'center',

    },
    waitContainer: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    waitText: {
        marginTop: 10,
        fontSize: 16,
    },
});

1.network environment
2.security rules
3.firewall

How to programmatically hide a Bootstrap Offcanvas component with JavaScript and Blazor?

I have a Blazor .Net 8 webb app that uses a Bootstrap 5.3 Offcanvas component as a menu of items that can be selected from. When the user chooses the menu item, I want the Offcanvas component to close automatically.

The way I did this was to create a ButtonClicked event that calls the JavaScript like this

`await JS.InvokeVoidAsync("closeOffcanvas");`

This is called right before the OnFilterSelected EventCallback

For the Bootstrap I’m using data-bs attributes. I searched extensively for a solution to no avail. The JavaScript I came up with can be seen below closeOffcanvas.js below). I’m at best a novice java script programmer

Below is the relevant code, for a working example see this GitHub repo

Any help would be appreciative.

closeOffcanvas.js

window.closeOffcanvas = function () {
  var offcanvasElement = document.getElementById("offcanvasid");
  var offcanvas = new bootstrap.Offcanvas(offcanvasElement);
  offcanvas.hide();
};

Filter.razor

<button class="btn btn-primary btn-sm" data-bs-toggle="offcanvas" data-bs-target="#offcanvasid">
  Contents
  <i class="fas fa-bars"></i>
</button>

<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasid">

  <div class="offcanvas-header">
    <span class=""></span>
    <button type="button" class="btn-close"
            data-bs-dismiss="offcanvas" aria-label="Close">
    </button>
  </div>

  <div class="offcanvas-body">

    <ul class="list-group">
      @foreach (var item in Enums.MenuItem.List.OrderBy(o => o.Value))
      {
        <li class="list-group-item @ActiveFilter(item)">
          <a @onclick="@(e => ButtonClicked(item))"
             type="button"
             id="@item.ButtonId">
            @item.Value <small>@item.Title</small>
          </a>
        </li>
      }
    </ul>

  </div>
</div>

@code

  [Parameter, EditorRequired] public required Enums.MenuItem? CurrentFilter { get; set; }
  [Parameter] public EventCallback<Enums.MenuItem> OnFilterSelected { get; set; }

  protected Enums.MenuItem currentMenuItem = Enums.MenuItem.HebrewPassOverOrCrossOver;

  private async Task ButtonClicked(Enums.MenuItem filter)
  {
    currentMenuItem = filter;

    // calling this doesn't close the component 
    //   It also disables the close button
    await JS.InvokeVoidAsync("closeOffcanvas"); 

    await OnFilterSelected.InvokeAsync(filter);
  }


// other code

Index.razor

This is the razor page that calls Filter.razor component

@page "/"
<h1>Home</h1>

<div class="d-flex justify-content-end mx-1">
  <Filter CurrentFilter=@CurrentFilter OnFilterSelected="@ReturnedFilter" />
</div>

<!-- Do something with the chosen filter -->

@code

  public MenuItem CurrentFilter { get; set; } = MenuItem.HebrewPassOverOrCrossOver; // default item
  

  private void ReturnedFilter(MenuItem filter)
  {
    CurrentFilter = filter;
    StateHasChanged();
  }

Classes in PYTHON vs JAVASCRIPT

Am studying the difference between those two languages and i was wondering why i can’t access the variables in javascript classes without initiating an instance but i can do that in python

here is an example of what am talking about:

PYTHON CLASS

    class Car: 
       all =[]
       def __init__(self, name):
          self.name = name

          Car.all.append(self)

       def get_car_name(self):
          return self.name
 
        
        
    bmw = Car("BMW")
    mercedez = Car("MERCEDEZ")

    print(Car.all)

Running this code returns a list of all cars (which are the instance that i have created)
[<main.Car object at 0x0000022D667664E0>, <main.Car object at 0x0000022D66766510>]

JAVASCRIPT Class

    class Car {
      all = [];
      constructor(name, miles) {
      this.name = name;
      this.miles = miles;

      this.all.push(this);
      }
     }

    let ford = new Car("ford", 324);
    let tesla = new Car("tesla", 3433);

    console.log(Car.all);

if i used this code the console.log will return
undefined

in javascript if i want to get the value of all i have to use an instance like this

console.log(ford.all);

this will return only the instance of ford that was created
[ Car { all: [Circular *1], name: 'ford', miles: 324 } ]

but otherwise in python this if i printed out an instance all it will return this

print(bmw.all)

[<__main__.Car object at 0x00000199CAF764E0>, <__main__.Car object at 0x00000199CAF76510>]

it returns the two instance that is created even if i called the all of one instance

props.OnNewTicketCreation is not a function

I’m having a problem passing a prop function. I’m following a tutorial and can’t seem to identify the issue with my prop, solutions to questions asked don’t relate to my challenge which is rather simple

The ticket control is the class based component holding state. The function of interest is handleAddingNewTicketToList. Pasted below

import React from 'react';
import NewTicketForm from './NewTicketForm';
import TicketList from './TicketList';
import TicketDetail from './TicketDetail';

class TicketControl extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            formVisibleOnPage: false,
            mainTicketList: [],
            slectedTicket: null,
        };
    }

    // handleClick = () => {
    //     this.setState(prevState => ({  // This function uses parentheses () around the object returned by the arrow function. This syntax indicates an implicit return, meaning that the object inside the parentheses is the return value of the arrow function.
    //         formVisibleOnPage: !prevState.formVisibleOnPage
    //     }))
    // }

    handleClick = () => {
        if (this.state.selectedTicket != null) {
            this.setState({
                formVisibleOnPage: false,
                selectedTicket: null,
            });
        } else {
            this.setState(prevState => ({
                formVisibleOnPage: !prevState.formVisibleOnPage,
            }));
        }
    }

    handleAddingNewTicketToList = (newTicket) => {
        const newMainTicketList = this.state.mainTicketList.concat(newTicket); // .concat creates a duplicate, .push doesnt
        this.setState({
            mainTicketList: newMainTicketList,
            formVisibleOnPage: false,
        });
    }

    handleChangingSelectedTicket = (id) => {
        const selectedTicket = this.state.mainTicketList.filter(ticket => ticket.id === id)[0];
        this.setState({ selectedTicket: selectedTicket })
    }

    handleDeletingTicket = (id) => {
        const newMainTicketList = this.state.mainTicketList.filter(ticket => ticket.id !== id);
        this.setState({
            mainTicketList: newMainTicketList,
            selectedTicket: null
        });
    }

    render() {
        let currentVisibleState = null;
        let buttonText = null;

        if (this.state.selectedTicket != null) {
            currentVisibleState = <TicketDetail ticket={this.state.selectedTicket} onClickingDelete = {this.handleDeletingTicket}/>
            buttonText = "Return to Ticket List"
        }
        else if (this.state.formVisibleOnPage) {
            currentVisibleState = <NewTicketForm
                onNewTicketCreation={this.handleAddingNewTicketToList}
            />
            buttonText = "Return to Ticket List";
        }
        else {
            currentVisibleState = <TicketList ticketList={this.state.mainTicketList} onTicketSelection={this.handleChangingSelectedTicket} />
            buttonText = "Add Ticket"
        }

        return (
            <React.Fragment>
                {currentVisibleState}
                <button onClick={this.handleClick}>{buttonText}</button>
            </React.Fragment>
        );
    }

}

export default TicketControl;

The NewticketForm handles adding a new ticket and holds a form.

import React from "react";
import PropTypes from "prop-types";
import { v4 } from "uuid";
import ReusableForm from "./ReusableForm";

function NewTicketForm(props) {


    function handleNewTicketFormSubmission(event) {
        event.preventDefault();
        props.OnNewTicketCreation({
            names: event.target.names.value,
            location: event.target.location.value,
            issue: event.target.issue.value,
            id: v4(),
            // numberOfStudents: parseInt(event.target.numberOfStudents.value) // How to parse numeric data
        });

    }


    return (
        <React.Fragment>
            <React.Fragment>
                <ReusableForm
                    formSubmissionHandler={handleNewTicketFormSubmission}
                    buttonText="Help!" />
            </React.Fragment>
        </React.Fragment>
    );
}

NewTicketForm.propTypes = {
    OnNewTicketCreation: PropTypes.func,
    // func1: PropTypes.func,
}

export default NewTicketForm;

The error arises on line 11 when running props.OnNewTicketCreation({. I’ve used breakpoints and can return the function from console.

Define a Static property of a Class (Object) with pseudoclassical inheritance javascript

I have been wrapping my head around pseudoclassical inheritance in Javascript , and continuing on this topic I wanted to set an Static property/method , for a defined Constructor function.
I want to avoid the class syntax for it.

function Food () {
    isEdible = true;
}

console.log(Food.isEdible); // undefined

I know this example is wrong

I am wondering how it has been done on the rest of the Javascript Object model, with methods so important like for instance

Array.of(element1, element2, /* …, */ elementN)

Which can be accessed without the need of Instanciating an Array

Mock Axios requests only for specific URLs, otherwise perform original request

I need to use stubs for requests to external resources, but still I need to fulfil requests for internal resources. Is it possible to mock a request from Axios only for certain URLs and otherwise continue to execute the initial requests?

export const spyOnAxios = (expectedResponse) => {
return jest.spyOn(axios, 'post')
.mockImplementation(function () {
    if (arguments[0] === 'https://external-api.com') {
        return expectedResponse
    }  
    return performOriginalRequest()
})}

Transformers.js extension is redownloading the model again and again after closing the extension tab

I am trying to build a chrome extension using transformers.js library in order to test its limits and see if onDevice ML can be a choice in some cases.
Based on the example provided in their official repo i am adding new features.
As i added the translation pipeline i saw something strange, namely that the model was downloading again and again after each opening and closing of the browser.

`class MyTranslationPipeline {
static task = "translation";
static model = "Xenova/nllb-200-distilled-600M";
static instance = null;

static async getInstance(progress_callback = null) {
    if (this.instance === null) {
        console.log("Loading translation pipeline...");
        this.instance = pipeline(this.task, this.model, {progress_callback});
    }

    return this.instance;
 }
}`

The original example showcased env.allowLocalModels = false; but i set it back to true and it didn’t work, i am expecting that when i reopen the browser the model is to be loaded from chache where it already is.

Cache entries

How to await middleware (Multer) in an Express route?

I am using Multer with a custom storage engine that ultimately uploads a file to Amazon S3. Because the file is going to Amazon S3 and then sends back some information about the file, I must await the entire Multer middleware to finish before doing anything else.

Here is an example of my Express route:

const multer  = require('multer');

  const MulterS3Storage = multerS3({
        AWSS3Client: AWSS3Client,
        Bucket: AWS_S3_BUCKETNAME,
        ACL: "public-read",
        ContentType: "video/mp4",
        Key: "123456789"           // This is a random string
    });

    const upload = multer({
        storage:  MulterS3Storage, // This is a custom storage engine which works
    });
    
    app.post('/form', upload.single('uploaded_file'), function (req, res) {
        console.log('I MUST wait for upload.single to finish');
         Result = {
                  code: 200,
                  files: req.file, // from Multer with metadata in it about the file e.g. file.location
                  }
         return res.status(Result.code).json(Result); // this runs before Multer has returned the callback
        });

Unfortunately it is not waiting for the upload.single to complete. That is, the route executes the console.log and returns the res.status BEFORE MulterS3Upload has run the callback with the correct information in req.file.

In my mind it seems I need to await the upload.single(uploaded_file) part but not sure how to do that?

This is what multerS3 does:

function AWSS3Storage(opts) {
    this.AWSS3Client = opts.AWSS3Client;
    this.Bucket = opts.Bucket;
    this.getKey = opts.Key;
    this.getContentType = opts.ContentType;
    this.ACL = opts.ACL;
    this.ServerSideEncryption = opts.serverSideEncryption;
    this.Metadata = opts.metadata;


}

AWSS3Storage.prototype._handleFile = async function _handleFile(req, file, cb) {
    const that = this;

            let Key =  that.getKey;
            let ContentType = that.getContentType;
            const FileStream = file.stream
            //console.log(`file.stream`, FileStream)
            console.log(`multer-s3-storage-engine.js key:`, Key)
            try {
                const Response = await s3Upload({
                    AWSS3Client: that.AWSS3Client,
                    Bucket: that.Bucket,
                    ACL: that.ACL,
                    ContentType: ContentType,
                    Key: Key,
                    Body: FileStream
                });

console.log(`middleware needs to wait until this callback below is returned: filename: ${path.parse(Key).base}, location ${Response.Location}`)

                cb(null, {
                    filename: path.parse(Key).base, 
                    location: Response.Location
                });

            } catch (e) {
                console.log(e);
            }

};

AWSS3Storage.prototype._removeFile = async function _removeFile(req, file, cb) {
const S3Command = new DeleteObjectCommand({Bucket: file.Bucket, Key: file.Key})
await this.AWSS3Client.send(S3Command);
cb();

}

export default async function (opts) {
    return new AWSS3Storage(opts);
}

“Tasks” array disappears when certain dispatchers are called (MERN stack)

I’m working on a MERN stack “to-do list” application which performs CRUD operations. There is Tasks list on one side of the screen and a form to add new tasks or edit existing tasks on the other side.

In order to edit a “task” from the list, I click on “Edit” button which is visible next to every single task, and the task title and description is getting fetched by the form. Then I edit those and save back to the database. There is no problem with the functionality.

However, after I click on Edit button, my Tasks list is getting completely disappeared with “No Tasks Found” and doesn’t come back until I refresh the page. This only happens while I’m editing an existing task. While I’m adding a new task, my Tasks list stays there and even new task is dynamically getting added to the bottom of the list.

This is a front-end problem that I couldn’t fix so far. I confirmed with console.logs that Tasks are getting invisible on the UI but actually still there and functions without an issue. Also there are no error logs on my console. What I’ve noticed is: in order to fetch an existing task, I’ve created two dispatchers case 'SET_EDIT_MODE': to start editing and case "CLEAR_EDIT_MODE": to end editing after clicking Save. My Tasks array gets disappeared after these two dispatchers are being called.

I’m sharing related code snippets and I hope someone provide me a little help. Your time and effort will be appreciated.

taskReducer.js file:

function taskReducer(tasks = [], action) {
    console.log("taskreducer");
    switch (action.type) {
        // eslint-disable-next-line no-lone-blocks
        case "ADD_TASK": {
            return [
                ...tasks,
                {
                    _id: action._id,
                    title: action.title,
                    description: action.description,
                    completed: false
                }
            ]
        }
        case "SET_TASK": {
            return action.payload
        }
        case "REMOVE_TASK": {
            console.log("Tasks before removal:", tasks);
            const updatedTasks = tasks.filter((task) => task._id !== action._id);
            console.log("Tasks after removal:", updatedTasks);
            return updatedTasks;
        }
        case "MARK_DONE": {
            return tasks.map((task) => {
                if (task._id === action._id) {
                    return {
                        ...task,
                        completed: !task.completed
                    }
                }
                return task
            })
        }
        case "EDIT_TASK": {
            const { taskToEdit, title, description } = action;
        
            // Ensure taskToEdit exists within tasks object
            if (tasks && tasks.taskToEdit) {
                const updatedTask = {
                    ...tasks.taskToEdit,
                    title,
                    description
                };
        
                // Return a new object maintaining the original structure
                return {
                    ...tasks,
                    taskToEdit: {
                        ...tasks.taskToEdit,
                        title,
                        description
                    },
                    [taskToEdit]: updatedTask // Update the specific task in the tasks object
                };
            }
        
            return tasks; // Return original state if tasks or taskToEdit is missing
        }
        case 'SET_EDIT_MODE': {
            console.log('Processing SET_EDIT_MODE:', action.payload);
            return {
                ...tasks,
                taskToEdit: action.payload, // Set the task for editing
                editMode: true // Set edit mode to true
            };
        }
        case "CLEAR_EDIT_MODE": {
            console.log('Processing CLEAR_EDIT_MODE');
            return {
                ...tasks,
                taskToEdit: null,
                editMode: false
            };
        }
        default: {
            throw Error("Unknown Action" + action.type)
        }
    }
}

export default taskReducer;

Task.jsx component:

import React, { useContext } from 'react';
import moment from 'moment';
import "../styles/task.css";
import axios from "../axios/axios.js"
import TaskContext from '../context/TaskContext.js';
import TokenContext from '../context/TokenContext.js';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';

function Task({ task }) {
    const { _id, title, description, completed } = task;
    const { dispatch } = useContext(TaskContext);
    const { userToken } = useContext(TokenContext);

    ... // Unrelated app logic

    // Called clicking on Edit button
    const handleEdit = () => {
        console.log('Editing task:', { task }); // Log the task details being edited
        // Dispatch an action to set the task for editing
        console.log('Dispatching SET_EDIT_MODE with task:', task);
        dispatch({
            type: 'SET_EDIT_MODE',
            payload: task // Send the entire task object for editing
        });
    };

    ... // Unrelated UI code
    
export default Task;

SaveTask.jsx component:

import React, { useState, useEffect, useContext } from 'react';
import TaskContext from '../context/TaskContext';
import TokenContext from '../context/TokenContext';
import axios from "../axios/axios";
import "../styles/saveTask.css";

function SaveTask() {
    const { tasks, dispatch } = useContext(TaskContext);
    const { userToken } = useContext(TokenContext);

    const [title, setTitle] = useState("");
    const [description, setDescription] = useState("");
    const { editMode, taskToEdit } = tasks; // Extract editMode and taskToEdit from context

    useEffect(() => {
        // Populate form fields with task details when in editMode
        if (editMode && taskToEdit) {
            setTitle(taskToEdit.title);
            setDescription(taskToEdit.description);
        } else {
            setTitle(""); // Reset title when not editing
            setDescription(""); // Reset description when not editing
        }
    }, [editMode, taskToEdit]);

    // Form logic
    const handleAddOrEdit = async (e) => {
        e.preventDefault();

        try {
            if (editMode && taskToEdit) {
                // Update existing task
                const res = await axios.post(`/task/editTask/${taskToEdit._id}`, { title, description }, {
                    headers: {
                        Authorization: `Bearer ${userToken}`
                    }
                });
                console.log("Task edited:", res.data);
                // Update task in context
                dispatch({
                    type: 'EDIT_TASK',
                    _id: taskToEdit._id,
                    title: res.data.task.title,
                    description: res.data.task.description
                });

                dispatch({ type: 'CLEAR_EDIT_MODE' }); // Clear edit mode after submission
            } else {
                // Add new task
                const res = await axios.post("/task/addTask", { title, description }, {
                    headers: {
                        Authorization: `Bearer ${userToken}`
                    }
                });
                console.log("New task added:", res.data);
                // Add new task to context
                dispatch({
                    type: "ADD_TASK",
                    _id: res.data.task._id,
                    title: res.data.task.title,
                    description: res.data.task.description,
                });
            }
            // Reset form fields
            setTitle("");
            setDescription("");

        } catch (error) {
            console.log(error);
        }
    };

    ... // Form input fields

export default SaveTask;

AllTask.jsx component:

import React, { useContext } from 'react';
import Task from './Task';
import TaskContext from '../context/TaskContext';

function AllTask() {
    const { tasks, editMode, taskToEdit } = useContext(TaskContext);
    
    console.log('Tasks:', tasks);
    console.log('EditMode:', editMode);
    console.log('TaskToEdit:', taskToEdit);
    
    // Tasks list
    return (
        <div>
            {Array.isArray(tasks) && tasks.length !== 0 ? (
                tasks.map((task, index) => (
                    <Task key={index} task={task} id={index} />
                ))
            ) : (
                <h1>No Tasks Found</h1>
            )}
        </div>
    );
}

export default AllTask;

Can’t overwrite invisible CSS rules – HTML/CSS/JS [closed]

I’m currently building my personal/portfolio website – PavloBondarenko.co and I’m facing invisible issue for me.

The issue is no text color or overwritten CSS rule for this section!

I’m a new user to Stack Overflow and not sure how to post whole website code here.

Will GitHub repo will do? – GitHub Repository

If not please correct me!

I tried !important and adding different CSS classes for that did – did not help

How to correctly use UseEffect with Nested And Paginated Fetches

Please roast my code here.

I am using UseEffect to trigger a request to fetch some data that my React Component will render. Technically, what I have is working. However, I feel like I am not using hooks correctly in this scenario. There’s multiple pieces of state I am working with and I am also hanging on to some data and checking it against state before updating it. It feels very hacky but I have had a hard time coming up with an improved solution.

For describing this I will use more of an analogous example rather than the actual data we are working with. Who doesn’t love authors and books?

The fetch queries are somewhat complex because we need to:

  1. Fetch a list of authors. The list we get back will be used to nest the secondary queries. Each record looks like: { id: integer, name: string, books: Book[]}, where Book looks like {id: integer}. This happens with an existing custom hook that handles things like pagination for us.
  2. Because the original list only contains the id of the books for each author we need to perform a fetch for a list of books based on the author’s book ids. The books we get back from the original request look like: {id: integer, author_id: integer, name: string}.
  3. The API we are using has a pagination limit of 12. When we fetch the needed books we will have some missing if we do not automatically re-fetch for each additional page. For example, given 5 authors we may have 2 authors with 11 books total, leaving only 1 book for the remaining 3 authors in the same paginated request. So, we need to loop through the pages and fetch each book from the authors we have.

Here is the existing code:

const customHook = () => { /* returns books for us */ }

const BooksByAuthorPage = () => {
  const { authors } = customHook();
  const [booksByAuthor, setBooksByAuthor] = UseState({});

  UseEffect(() => {  
    const fetchPage = async (page, bookIds) => {
      const bookUrl = `/api/books?ids=${bookIds}&page=${page}`;
      const response = await fetch(bookUrl);
    
      // The first value is the list of books for that page
      // The second value indicates if there is a next page to fetch from
      return [response.body.data, response.body.links.next];
    }

    const fetchAllPages = async (bookIds) => {
      let page = 1;
      let next = true;
      const booksByAuthorId = {};

      while (next) {
        let [books, next] = fetchPage(page, bookIds)
        next = next;
        books.forEach(book => {
          if (booksByAuthorId[book.author_id]) {
            booksByAuthorId[book.author_id].push(book);
          } else {
            booksByAuthorId[book.author_id] = [book];
          }
        });

        setBooksByAuthor((prevBooks) => {
          const newBooksByAuthor = { ...prevBooks };

          Object.keys(booksByAuthorId).forEach((authorId) => {
            const newBooks = booksByAuthorId[authorId];
            // If the author id is already added as a key
            if (newBooksByAuthor[authorId]) {
              // If the book does not yet exist on the author then add it
              newBooks.forEach((newBook) => {
                if (
                  !newBooksByAuthor[authorId].find(
                    (existingBook) => existingBook.id === newBook.id
                  )
                ) {
                  newBooksByAuthor[authorId].push(newBook);
                }
              });
            // Otherwise add the new key with the list
            } else {
              newBooksByAuthor[authorId] = [newBook];
            }
          });

          return {
            ...newBooksByAuthor,
          };
        });
      }
      
      // trigger the next paginated request if needed
      if (next) { 
        page += 1 
      }
    }

    const bookIds = authors.flat_map(a => a.books.map(b => b.id));
    fetchAllPages(bookIds);
  }, [authors]);
};

Woof that was a lot to type.

Okay so here are the reasons I think this code needs to be improved.

  1. On each paginated request I am tracking data in booksByAuthorId and comparing it to the state stored in booksByAuthor before updating it via setBooksByAuthor. (If I don’t do this I will overwrite the existing values from previous pages, which I do not want).
  2. I’m also tracking a mutable next and page value inside the UseEffect. My functional friends are gonna come after this one.
  3. My spidey senses tell me this code is going to break so easily.

So, help me out. How can I do this better. Am I not ‘thinking in hooks’ correctly? Is this actually the best way to do this? Is the real problem the structure of the API responses?

Thanks for reading and for any insight.

How can I use a ? in a URL to change JavaScript variables?

I can’t figure out how the ? URL separator works, which I need to use for a project.

I made a variable that would alert it’s content when the page was opened, opened the deployment with ?variable=”working”, and expected it to alert working, but instead it alerted what the variable was originally set to.

var variable = "Not Working";
alert(url);

How do you get rid of useSearchParams() and Suspense deployment error?

I’m getting ⨯ useSearchParams() should be wrapped in a suspense boundary at page “/PaymentPage”. Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout

The problem is I have wrapped everything in Suspense, but I’m still getting this error when trying to deploy my application.

'use client';
import React, { useEffect, useState, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import PayPalPaymentButtons from '../ui/PayPalButtons';
import ContactForm from '../ui/contact-form';

const PaymentPage: React.FC = () => {
  const router = useRouter();
  const searchParams = useSearchParams();
  const amount = searchParams ? searchParams.get('amount') : null;

  const [paypalClientId, setPaypalClientId] = useState<string | null>(null);

  useEffect(() => {/*...*/}, []);

  if (!paypalClientId) {
    return <Suspense fallback={<div>Loading...</div>}><div>Loading...</div></Suspense>;
  }

  const handleSuccess = () => {
    // Redirect to success page or perform any other action
    router.push('/');
  };

  const handleError = (error: any) => {
    // Handle error, display message, or retry payment
    console.error('Payment error:', error);
  };

  return (
    <Suspense fallback={<div>Loading...</div>}>
    {/* ... */}
    </Suspense>
  );
};

export default PaymentPage;

Use javascript to put a DIV element into an existing DIV element

I have some data that I would like to display in a specific DIV element. What currently happens is that a DIV element is created using CSS and a formula and placed at the appropriate height.

The existing DIV that is permanently inserted in the template:

<div data-hour="1" class="slot"></div>

I’m currently writing the corresponding elements into the template like this:

showIn(calendar) {
        if (
            this.date < dateString(calendar.weekStart) ||
            this.date > dateString(calendar.weekEnd)
        ) {
            $(`#${this.id}`).remove();
            return;
        }
        let eventSlot;
        if ($(`#${this.id}`).length) {
            eventSlot = $(`#${this.id}`);
        } else {
            eventSlot = $("<div></div>")
                .addClass("event")
                .attr("id", this.id)
                .click(() => this.clickIn(calendar));
        }
        const h = calendar.slotHeight;
        let linebreak = this.description;
        linebreak = linebreak.split("n").join("<br />");
        eventSlot
            .text(this.description)
            .css("top", (this.startHour) * h - (1*h) + "px")
            .css("backgroundColor", `var(--color-${this.color})`)
            .css("white-space", "pre-line")
            .css("float", "left")
            .appendTo(`.day[data-dayIndex=${this.dayIndex}] .slots`);
    }

My problem is that the formula causes all newly created elements to be at the same height and obscure each other.

My idea is to insert the new DIV into the existing DIV. In the formula I use “this.startHour” . This has the same value as data-hour=”1″ of the existing DIV. Then, if I’m not mistaken, I can display them one below the other using CSS.

I would also be open to alternative suggestions.

Edit:
When I enter the page, the following function is called, in which I read the data and pass it on to the Event class. The showIn() function is then in the Event class.

loadEvents() {
    $(".event").remove();

    if (!this.eventsLoaded) {
        //this.events = JSON.parse(this.lbtbdata.getItem("events"));
        this.events = JSON.parse(this.lbtbdata);
        console.log(this.events);
        if (this.events) {
            for (const date of Object.keys(this.events)) {
                for (const id of Object.keys(this.events[date])) {
                    const event = new Event(this.events[date][id]);
                    this.events[date][id] = event;
                }
            }
        }
        this.eventsLoaded = true;
    }
    if (this.events) {
        for (let dayIndex = 0; dayIndex < 7; dayIndex++) {
            const date = dateString(addDays(this.weekStart, dayIndex));
            if (this.events[date]) {
                for (const event of Object.values(this.events[date])) {
                    event.showIn(this);
                    //console.log(event);
                }
            }
        }
    } else {
        this.events = {};
    }
}