let userInput = prompt('Enter an integer');
console.log(Number(userInput));
I entered ’10’ and it is logging out NaN.
I thought Number() converted a string to a number value.
Blancer.com Tutorials and projects
Freelance Projects, Design and Programming Tutorials
Category Added in a WPeMatico Campaign
let userInput = prompt('Enter an integer');
console.log(Number(userInput));
I entered ’10’ and it is logging out NaN.
I thought Number() converted a string to a number value.
const functions = require('firebase-functions');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const OpenAI = require('openai');
const app = express();
// CORS 설정
const corsOptions = {
origin: 'https://nulligpt.web.app',
methods: ['GET', 'POST', 'OPTIONS'],
allowedHeaders: ['Content-Type'],
credentials: true,
};
// CORS 미들웨어 사용
app.use(cors(corsOptions));
app.use(bodyParser.json());
// OpenAI API 키
const OPENAI_API_KEY = 'sk-';
const client = new OpenAI({
apiKey: OPENAI_API_KEY,
});
// CORS preflight 요청에 대한 핸들링
app.options('*', cors(corsOptions));
// 이름 번역 API 엔드포인트
app.post('/api', async (req, res) => {
const { name } = req.body;
if (!name) {
console.log('Name is missing in the request.');
return res.status(400).json({ error: 'Name is required' });
}
try {
const response = await client.chat.completions.create({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: `Translate this name to Korean: ${name}` }],
});
if (response.choices && response.choices.length > 0) {
const translatedName = response.choices[0].message.content;
console.log('Successfully received response from OpenAI:', translatedName);
return res.json({ translatedName });
} else {
return res.status(500).json({ error });
}
} catch (error) {
console.log( error);
}
});
exports.api = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
} else {
try {
await app(req, res);
} catch (err) {
console.log( err);
}
}
});
});
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="nulli.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="allcon">
<div class="toplogo"></div>
<form id="nameForm" class="form">
<input class="input" type="text" id="nameInput" placeholder="Enter your name" required>
<button type="submit">Translate</button>
</form>
<div class="word">
<p class="firstword">Enter your name</p>
<p class="firstword">you can get korean name</p>
</div>
<div id="translated-name" class="output"></div>
</div>
<script>
document.getElementById('nameForm').addEventListener('submit', async function(event) {
event.preventDefault();
const name = document.getElementById('nameInput').value;
try {
const response = await fetch('https://us-central1-nulligpt.cloudfunctions.net/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
body: JSON.stringify({ name: name }),
});
if (response.ok) {
const data = await response.json();
document.getElementById('translated-name').innerText = `${data.translatedName}`;
} else {
document.getElementById('translated-name').innerText = 'Error: Failed to translate name';
}
} catch (error) {
console.error('Error:', error);
document.getElementById('translated-name').innerText = 'Error: Failed to fetch the translation';
}
});
</script>
</body>
</html>
I created a feature that translates the text I input into Korean.
It worked well during local testing, so I deployed it using
Firebase Hosting and created a function. My Firebase project name is ‘nulligpt’
so the URL is https://nulligpt.web.app/ When sending POST requests from the client,
I use https://us-central1-nulligpt.cloudfunctions.net/api (where ‘api’ is the Firebase function name).
Initially, a CORS error appeared, which seemed correctly resolved, but now, no matter how many times I send a POST request, I receive either a 404 or 500 error.
Below is the network request log.
Request URL:
https://us-central1-nulligpt.cloudfunctions.net/api
Request Method:
OPTIONS
Status Code:
408 Request Timeout
Remote Address:
216.239.36.54:443
Referrer Policy:
strict-origin-when-cross-origin
:authority:
us-central1-nulligpt.cloudfunctions.net
:method:
OPTIONS
:path:
/api
:scheme:
https
accept:
/
accept-encoding:
gzip, deflate, br, zstd
accept-language:
ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
access-control-request-headers:
content-type
access-control-request-method:
POST
origin:
https://nulligpt.web.app
priority:
u=1, i
referer:
https://nulligpt.web.app/
sec-fetch-dest:
empty
sec-fetch-mode:
cors
sec-fetch-site:
cross-site
user-agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36
I have a simple Mr Potato Head game with a big Mr Potato Head and a side bar filled with parts. I would like to make the parts, which are images, both draggable and resizable.
The following is the website code, with the dragAndResizeElement function responsible to add event listeners for both the dragging and resizing functionality. I call this function on every image when it is dynamically appended to the parent container of all the Mr. Potato Head parts. The dragging functionality works perfectly, however the resizing functionality does not work at all. I would love help in figuring out the best way to make these images dynamically resizable by the user. I have attached a picture of how the website looks on the screen since the code does not run properly without the folder of images in the directory.
<head>
<style>
body {
/*background-image: url(images/background3.jpg);*/
display: grid;
grid-template-columns: 25% 75%;
column-gap: 5em;
}
#mrPotatoHead {
width: 75%;
}
#bodyPartDiv {
border: 2px solid black;
}
.part {
max-width: 100%;
height: auto;
}
</style>
</head>
<body>
<audio xautoplay loop src="media/Children's Music - Kids Game.mp3"></audio>
<div id="bodyPartDiv"></div>
<img id="mrPotatoHead" src="images/mr-potato-head/body.png">
<script src="game.js"></script>
</body>
async function loadParts() {
try {
const response = await fetch('parts.json');
if (!response.ok) {
throw new Error(`${response.status} - ${response.statusText}`);
}
const json = await response.json();
return json.images;
} catch (e) {
console.error(e);
}
}
const parts = await loadParts();
parts.forEach(part => {
const img = document.createElement('img');
img.src = part;
img.className = 'part';
partDiv.append(img);
dragAndResizeElement(img);
});
function dragAndResizeElement(element) {
let dragging;
let resizing;
let translate = { x: 0, y: 0 };
let client = { x: 0, y: 0 };
let originalWidth, originalHeight;
element.addEventListener('mousedown', e => {
e.preventDefault();
if (e.offsetX > (element.offsetWidth - 20) && e.offsetY > (element.offsetHeight - 20)) {
element.style.cursor = 'nw-resize';
resizing = true;
originalWidth = element.offsetWidth;
originalHeight = element.offsetHeight;
}
else {
element.style.cursor = 'grabbing';
dragging = true;
}
client.x = e.clientX;
client.y = e.clientY;
});
document.addEventListener('mousemove', e => {
e.preventDefault();
if (dragging) {
translate.x = translate.x - (client.x - e.clientX);
translate.y = translate.y - (client.y - e.clientY);
element.style.transform = `translate(${translate.x}px, ${translate.y}px)`;
}
else if (resizing) {
const newWidth = originalWidth + (e.clientX - client.x);
const newHeight = originalHeight + (e.clientY - client.y);
element.style.width = `${newWidth}px`;
element.style.height = `${newHeight}px`;
}
client.x = e.clientX;
client.y = e.clientY;
});
document.addEventListener('mouseup', () => {
element.style.cursor = 'grab';
dragging = false;
resizing = false;
});
}
I am attempting to call the Google Drive REST API to upload a file from a browser context using the fetch api, but am not able to progress past a weird error.
TypeError: Failed to fetch
Looking at other posts on the topic, some point to a CORS failure, but it’s pretty difficult to determine exactly what the error is from this message. The strange thing is, looking at the Network tab of the Chrome devtools tells a different story:
Now I’ll be the first to admit that there’s a (high?) chance I’m sending a malformed request, but it’s also pretty difficult to determine what about the request is malformed without any error message.
What I’m doubly confused by, is why the fetch call is rejecting (throws error with await), rather than resolving with a 400 response.
The code to make the call is about as basic as it gets:
await fetch(`https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart`, options);
The options object is pretty boiler-plate, and just sets things like an Authorization header, Content-Type, Content-Length, as well as the body which (in this case) is multipart/related
So I neither get a graceful resolve response with a message, nor do I get useful reject outcome, rather just TypeError: Failed to fetch
If I were to rely on the rejection alone, I would have no idea this was actually a 400. It was only the Network tools that revealed this.
Anyone have a clue why this 400 error would be “swallowed”, and what I need to do to capture it?
Further detail in response to comments. The code around the fetch looks like this:
async send() {
this._build();
return await fetch(this._parameterizedUrl, this._options);
}
This is contained in an object which just encapsulates the process of creating a request (called a Request). So the this pointer refers to the encapsulating object. this._parameterizedUrl is just the value of the URL string already posted, and this._options is the options object already mentioned. The call to build() just assembles the values of the Request object, mostly into the options argument (but also supports URL parameters, not used in this case)
The code calling this looks like:
const request = Request.post(uploadUrl);
request.setContentType(contentType);
request.setBody(body);
request.setAccessToken(accessToken);
request.addHeader('Content-Length', contentLength);
const response = await request.send();
The Request.post(uploadUrl) call is a shorthand to create my Request object (this is my own encapsulation as mentioned)
This call will throw an error, which is caught at an earlier point in the stack. The next line of the trace from the Failed to fetch error looks like this:
TypeError: Failed to fetch
at Request.send (api.js:240:1)
document.addEventListener('DOMContentLoaded', async () => {
const url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart';
const options = {};
const authToken = '<Add Auth Token>';
const boundary = 'boundary-' + Math.random().toString(36).substring(2);
const contentType = `multipart/related; boundary=${boundary}`;
// Body part meta data for the filename
const meta = {
name: 'test.json'
};
// Body part for media (the file)
const data = {
foo: "bar",
bar: "baz"
}
const metaBlob = new Blob([JSON.stringify(meta)], {
type: 'application/json',
});
const mediaBlob = new Blob([JSON.stringify(data)], {
type: 'application/json',
});
const body = new FormData();
body.append('metadata', metaBlob, "metadata");
body.append('media', mediaBlob, name);
let contentLength = metaBlob.size + mediaBlob.size;
const headers = new Headers();
headers.append('Authorization', `Bearer ${authToken}`);
headers.append('Content-Type', contentType);
headers.append('Content-Length', contentLength);
options['method'] = 'POST';
options['headers'] = headers;
options['body'] = body;
try {
const response = await fetch(url, options);
console.log(response);
} catch (err) {
console.error(err);
}
});
I see the iframe gets inserted into DOM after I click on some icon. So DOM gets updated dynamically. Once I am able to get this iframe element, I need to operate on some elements within it. There are also some shadow host elements within this iframe.
I tried following:
Attempt1:
const iframe = page.waitForSelector("#iframeId")
Attempt2:
const iFrameHandle = page.waitForSelector("#parentelement")
const iframe = iFrameHandle.contentFrame()
Attempt3:
page.mainFrame(), page.frames()
Last resort:
const iframeHandle = await page.waitForSelector(“#iframeId”, { state: ‘attached’, timeout: 10000 });
const iframe = await iframeHandle.contentFrame();
console.log("IFRAME: "+iframe);
console.log(“Iframe handle stringify:”, JSON.stringify(iframeHandle, null, 2));
Is there anything I need to add to the code after I click on the icon which loads the iframe and before I try to locate elements within the iframe ?
Is there any equivalent in k6 for switch to iframe in Selenium ?
Similar to this question, but I couldn’t make the answers work with my existing code. I have a custom cursor which is an inline svg, it works great everywhere (and scrolls with the page) but gets stuck at the edge of the iframe from a Vimeo embed. I’d like to hide it when the mouse enters the iframe and bring it back when it exits. How can I adjust my code below to make the last part of the JS work correctly?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
let lastX, lastY, lastScrolled = 0;;
$(document).on('mousemove', function(e) {
lastX = e.pageX - 1;
lastY = e.pageY - 1;
$('#cursor').css({
left: e.pageX - 1,
top: e.pageY - 1,
pointerEvents: 'none'
});
});
$(window).scroll(function(event) {
if (lastScrolled != $(window)
.scrollTop()) {
lastY -= lastScrolled;
lastScrolled = $(window)
.scrollTop();
lastY += lastScrolled;
}
$('#cursor').css({
left: lastX,
top: lastY,
pointerEvents: 'none'
});
});
var iframe = document.querySelector("iframe");
iframe.addEventListener("mouseover", function() {
cursor.style.display = 'none';
})
iframe.addEventListener("mouseleave", function() {
cursor.style.display = 'block';
})
</script>
body,html { cursor: none !important; }
#cursor {display: block; position: absolute; z-index: 9999; pointer-events:none;
width: 1.2rem; height: auto; }
/* width: 6.666rem; */
@media only screen and (max-width: 960px) {
* { cursor: default !important; }
#cursor{display: none;}
}
#cursor .cursorshape {fill: #d9e021;}
.embedvid {position: relative; height: 0; overflow: hidden; max-width: 100%;}
.embedvid iframe, .embedvid object, .embedvid embed {position: absolute; top: 0; left: 0; width: 100%; height: 100%;}
.ratio-16-9 {padding-bottom: 56.25%;}
<svg version="1.1" id="cursor" style="width:1.2rem;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 30 38" enable-background="new 0 0 30 38" xml:space="preserve">
<polygon class="cursorshape" points="29.397,31.059 29.397,28.54 29.397,24.939 29.397,22.42 29.397,18.819 29.397,16.3 29.397,10.18
0.603,0.822 0.603,6.942 0.603,9.46 0.603,13.062 0.603,15.581 0.603,19.181 0.603,21.701 0.603,27.82 29.397,37.178 "/>
</svg>
<div style="width:50%">
<div class="embedvid ratio-16-9">
<iframe src='https://player.vimeo.com/video/766323945' frameborder='0' webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
</div>
</div>
When getting a ReadableStreamDefaultReader from a ReadableStream do you need to call releaseLock at the end of the stream, when done equals true, for everything to clean up and not cause a memory leak? Or would letting everything just drop out of scope still allow it to also clean up?
Hello im working on a small website and i have a small problem i have a theme switch button that turn the page to dark mode but if i am in the home page and change to contact page the theme switch stops working but this happens only on the other pages exept the main one and i dont know how to fix it i have tried to mess around with the js code but nothing
Here is my JavaScript code:
// DarkMode
let darkmode = localStorage.getItem("darkmode")
const themeSwitch = document.getElementById("theme-switch")
const enableDarkmode = () => {
document.body.classList.add("darkmode")
localStorage.setItem("darkmode", "active")
document.getElementById("logo").src="../Imgs/logo-white.png"
}
const disableDarkmode = () => {
document.body.classList.remove("darkmode")
localStorage.setItem("darkmode", null)
document.getElementById("logo").src="../Imgs/logo-blue.png";
}
if (darkmode ==="active") enableDarkmode()
themeSwitch.addEventListener("click", () => {
darkmode = localStorage.getItem("darkmode")
darkmode !== "active" ? enableDarkmode() : disableDarkmode()
})
I am trying to learn React by following the below video.
For some reason nothing printing inside div tag.
can you let me know how to fix it.
Providing the code and sandbox below.
I debugged by putting console but still no luck
https://www.youtube.com/watch?v=pFXYym4Wbkc&list=PL3lfepputJuGAaI3S7FvcBIutzHNtZ_pb&index=1
https://codesandbox.io/p/sandbox/l4q4pz?file=%2Fsrc%2FsortingVisualizer%2FsortingVisualizer.jsx%3A1%2C1-37%2C1
import React from "react";
const number_of_array_bars = 310;
const sortingVisualizer = () => {
const [array, setArray] = useState([]);
useEffect(() => {}, []);
const resetArray = () => {
const newArray = [];
for (let i = 0; i < number_of_array_bars; i++) {
newArray.push(randomIntFromInterval(5, 730));
}
console.log("newArray", newArray);
setArray(newArray);
};
const render = () => {
return (
<>
{console.log("array", array)}
{array.map((value, index) => {
<div key={index} style={{ height: "${value}px" }}>
test
</div>;
})}
</>
);
};
return render();
};
export default sortingVisualizer;
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
I have a web application in Vue.js using nuxt and vuetify.
I have installed the library vuewordcloud to make a word cloud : https://www.npmjs.com/package/vuewordcloud
And now, when I start the project, it indicates an error : `500 Unexpected token ‘:’`.
Here is the full error message :
500
Unexpected token ':'
at new Script (node:vm:99:7)
at createScript (node:vm:255:10)
at Object.runInThisContext (node:vm:303:10)
at ViteNodeRunner.runModule (./node_modules/vite-node/dist/client.mjs:398:19)
at ViteNodeRunner.directRequest (./node_modules/vite-node/dist/client.mjs:381:16)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async ViteNodeRunner.cachedRequest (./node_modules/vite-node/dist/client.mjs:206:14)
at async ViteNodeRunner.dependencyRequest (./node_modules/vite-node/dist/client.mjs:259:12)
at async ./plugins/wordcloud.ts:2:31
at async ViteNodeRunner.runModule (./node_modules/vite-node/dist/client.mjs:399:5)
Here is my plugins/wordcloud.ts configuration :
import { defineNuxtPlugin } from '#app';
import VueWordCloud from 'vuewordcloud';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('VueWordCloud', VueWordCloud);
});
I’ve tried to use the same configuration but in Javascript.
But when I try to do that, the same error appears.
Is there any other way to make a wordcloud in Vue.js or any way to solve this problem ?
In my Next js public folder i have a file let’s call it script.js and my intention is to be able to call a react component from my components folder inside of the script.js file. so i came across the createElement from the react docs which i’m using to try and achieve this but i continue to encounter this error ReferenceError: Greeting is not defined and By Name, “Greeting” from the ReferenceError is the name of the component i’m trying to use. Now below is my sample public/script.js file
(function () {
const container= document.createElement('div');
container.id = 'chatbot-root';
document.body.appendChild(chatbotContainer);
// CDN REACT 18
function loadReact() {
return Promise.all([
loadScript('https://unpkg.com/react@18/umd/react.production.min.js'),
loadScript('https://unpkg.com/react-dom@18/umd/react-dom.production.min.js')
]);
}
function loadScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
fetch(`http:exampl.com`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
return loadReact().then(() => {
renderReactApp(data);
});
})
.catch(error => console.error('Error loading chatbot:', error));
function renderReactApp(data) {
const root = document.getElementById('chatbot-root');
if (root) {
const root = ReactDOM.createRoot(root);
// The Greetings you see here is the name of the component
return root.render(React.createElement( Greeting, { name: 'Taylor' }
));
} else {
console.error('container not found');
}
}
})();
And here is the code for the Greetings Component
export function Greeting({ name }:{name:string}) {
return (
<h1 className="greeting">
Hello <i>{name}</i>. Welcome!
</h1>
);
}
declare global {
interface Window {
Greeting: typeof Greeting;
}
}
if (typeof window !== 'undefined') {
window.Greeting = Greeting;
}
As you can see on the Greetings component, one thing i’ve been trying to do is make the component global so hopefully, it can be assessed in the public/script.js all to no avail.And also i created a @types folder in the root of the project and added the file global.d.ts which contain the following below just to make sure it’s global
declare global {
interface Window {
Greeting: Greeting;
}
}
Descpite all that i still ge the error ReferenceError: Greeting is not defined to the best of my understanding of the docs with regards to the createElement, what i’ve done so far should work just fine but it isn’t. Thanks
I’ve got a bunch of Api calls running with Axios but when my app starts I run this function to get authentication token stored in Axios as a default header:
export const myAuth = async () => {
return new Promise(async (resolve, reject) => {
try {
const loginOptions = {
email: import.meta.env.VITE_USER,
password: import.meta.env.VITE_PASSWORD
}
const login = await axios.post(myUrl + '/auth/login', loginOptions)
axios.defaults.headers.common['Authorization'] = 'Bearer ' + login.data.data.access_token
resolve(login)
} catch (error) {
reject(error)
}
})
}
When I attempt to run any api calls in Vitest in order to test them, I’m getting a 403 error, even though my axios instance shows the auth token is there. Any ideas of what I’m getting wrong?
Here is an example of a test that is failing:
import { describe, test, expect } from 'vitest'
import { myAuth, getUserItems } from '@/apiCalls.js'
await myAuth()
describe('api calls', () => {
test('get user items', async () => {
const data = await getUserItems()
expect(data).toBeDefined()
})
})
When I run this test, getUserItems() fails with a 403 error, when I’ve already gotten the auth token added as a default header in myAuth().
I tried to create a navigation bar for a site.
And then I try to add some content from a known set of ready-made styles.
I try to add several elements
but they overlap or remove each other’s style or elements.
How can I make the navigation bar separately independent and be able to add content elements from a known set of ready-made styles without damaging the navigation bar and themselves?
How can I separate the navigation bar and the content from a set of ready-made styles without damaging it?
index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sidebar Menu | Side Navigation Bar</title>
<!-- CSS -->
<link rel="stylesheet" href="{% static "css/style.css" %}" />
<!-- Boxicons CSS -->
<link
href="https://unpkg.com/[email protected]/css/boxicons.min.css"
rel="stylesheet"
/>
<!-- You MUST include jQuery 3.4+ before Fomantic -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.js"></script>
</head>
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
<nav>
<div class="logo">
<i class="bx bx-menu menu-icon"></i>
<span class="logo-name">InfoEco</span>
</div>
<div class="sidebar">
<div class="logo">
<i class="bx bx-menu menu-icon"></i>
<span class="logo-name">InfoEco</span>
</div>
<div class="sidebar-content">
<ul class="lists">
<li class="list">
<a href="#" class="nav-link">
<i class="bx bx-home-alt icon"></i>
<span class="link">Home</span>
</a>
</li>
<li class="list">
<a href="#" class="nav-link">
<i class="bx bx-bar-chart-alt-2 icon"></i>
<span class="link">Label Nav Menu 1</span>
</a>
<div class="sub-menu">
<a href="#">Label Nav Sub Menu 1</a>
<a href="#">Label Nav Sub Menu 2</a>
<a href="#">Label Nav Sub Menu 3</a>
<a href="#">Label Nav Sub Menu 4</a>
</div>
</li>
<li class="list">
<a href="#" class="nav-link">
<i class="bx bx-bell icon"></i>
<span class="link">Label Nav Menu 2</span>
</a>
<div class="sub-menu">
<a href="#">Label Nav Sub Menu 1</a>
<a href="#">Label Nav Sub Menu 2</a>
</div>
</li>
<li class="list">
<a href="#" class="nav-link">
<i class="bx bx-heart icon"></i>
<span class="link">Label Nav Menu 3</span>
</a>
</li>
<li class="list">
<a href="#" class="nav-link">
<i class="bx bx-folder-open icon"></i>
<span class="link">Label Nav Menu 4</span>
</a>
</li>
</ul>
<div class="bottom-cotent">
<li class="list">
<a href="#" class="nav-link">
<i class="bx bx-cog icon"></i>
<span class="link">Label Nav Menu 5</span>
</a>
</li>
<li class="list">
<a href="#" class="nav-link">
<i class="bx bx-log-out icon"></i>
<span class="link">Label Nav Menu 6</span>
</a>
</li>
</div>
</div>
</div>
</nav>
<section class="overlay"></section>
<div class="ui divider"></div>
<div class="ui divider"></div>
<div class="ui divider"></div>
<div class="ui container">
<div class="ui grid">
<div class="four wide column">
<div class="ui vertical menu">
<a class="item">
<h4 class="ui header">Promotions</h4>
<p>Check out our new promotions</p>
</a>
<a class="item">
<h4 class="ui header">Coupons</h4>
<p>Check out our collection of coupons</p>
</a>
<a class="item">
<h4 class="ui header">Rebates</h4>
<p>Visit our rebate forum for information on claiming rebates</p>
</a>
</div>
</div>
<div class="twelve wide column">content</div>
</div>
</div>
<script src="{% static "script/script.js" %}"></script>
</body>
</html>
style.css
/* Google Fonts - Poppins */
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
min-height: 100%;
background: #e3f2fd;
}
nav {
position: fixed;
top: 0;
left: 0;
height: 70px;
width: 100%;
display: flex;
align-items: center;
background: #fff;
box-shadow: 0 0 1px rgba(0, 0, 0, 0.1);
}
nav .logo {
display: flex;
align-items: center;
margin: 0 24px;
}
.logo .menu-icon {
color: #333;
font-size: 24px;
margin-right: 14px;
cursor: pointer;
}
.logo .logo-name {
color: #333;
font-size: 22px;
font-weight: 500;
}
nav .sidebar {
position: fixed;
top: 0;
left: -100%;
height: 100%;
width: 260px;
padding: 20px 0;
background-color: #fff;
box-shadow: 0 5px 1px rgba(0, 0, 0, 0.1);
transition: all 0.4s ease;
}
nav.open .sidebar {
left: 0;
}
.sidebar .sidebar-content {
display: flex;
height: 100%;
flex-direction: column;
justify-content: space-between;
padding: 30px 16px;
}
.sidebar-content .list {
list-style: none;
}
.list .nav-link {
display: flex;
align-items: center;
margin: 8px 0;
padding: 14px 12px;
border-radius: 8px;
text-decoration: none;
}
.lists .nav-link:hover {
background: linear-gradient(#dfe4e6, #eff2f4);
}
.nav-link .icon {
margin-right: 14px;
font-size: 20px;
color: #707070;
}
.nav-link .link {
font-size: 16px;
color: #707070;
font-weight: 400;
}
.lists .nav-link:hover .icon,
.lists .nav-link:hover .link {
color: #4b6a78;
font-weight: 500;
}
.overlay {
position: fixed;
top: 0;
left: -100%;
height: 1000vh;
width: 200%;
opacity: 0;
pointer-events: none;
transition: all 0.4s ease;
background: rgba(0, 0, 0, 0.3);
}
nav.open ~ .overlay {
opacity: 1;
left: 260px;
pointer-events: auto;
}
nav .sidebar .sidebar-content .list .sub-menu {
margin-left: 5px;
padding-left: 10px;
border-left: 1px solid #bbb;
max-height: 0px;
overflow: hidden;
transition: max-height 300ms ease-in-out;
}
nav .sidebar .sidebar-content .list.active .sub-menu {
max-height: 500px;
}
nav .sidebar .sidebar-content .list .sub-menu a {
text-decoration: none;
display: block;
padding: 5px;
margin: 5px 0px;
font-size: 16px;
color: #707070;
font-weight: 400;
cursor: pointer;
}
nav .sidebar .sidebar-content .list .sub-menu a:hover {
background: linear-gradient(#dfe4e6, #eff2f4);
color: #4b6a78;
font-weight: 500;
}
script.js
const navBar = document.querySelector("nav"),
menuBtns = document.querySelectorAll(".menu-icon"),
overlay = document.querySelector(".overlay");
menuBtns.forEach((menuBtn) => {
menuBtn.addEventListener("click", () => {
navBar.classList.toggle("open");
});
});
overlay.addEventListener("click", () => {
navBar.classList.remove("open");
});
document.querySelectorAll("nav .sidebar .sidebar-content .list a").forEach(function(list){
list.addEventListener("click",function(e){
if(e.target.parentNode.children.length > 1){
e.target.parentNode.classList.toggle("active");
}
});
});
I’ve been trying to create a small app that differentiates between Zelle transactions and the actual balance. Of course in order to do that I need bank information. Thus, I am trying to integrate the plaid sdk into my react native ios app.
I am trying to follow this repo’s implementation but I am struggling with one thing.
When my link token is created, I am struggling to get the onSuccess to run so I can have the exchange link token api get called. Does anyone know how I can do this in IOS?
import React, { useState, useEffect, useCallback } from 'react';
import {
View,
Text,
StyleSheet,
Button,
TouchableOpacity,
} from 'react-native';
import { create, open, dismissLink, LinkSuccess, LinkExit, LinkIOSPresentationStyle, LinkLogLevel } from 'react-native-plaid-link-sdk';
// Define the types for transactions
type Transaction = {
id: string;
amount: number;
date: string; // ISO format date string
type: 'credit' | 'debit';
};
// Mock data for demonstration purposes
const mockTransactions: Transaction[] = [
// Add your transaction data here
];
const BalancePage: React.FC = () => {
console.log('Rendering BalancePage');
const [filter, setFilter] = useState<string>('month');
const [filterFromPayout, setFilterFromPayout] = useState<boolean>(false);
const [lastPayoutDate, setLastPayoutDate] = useState<string | null>(null);
const [totalBalance, setTotalBalance] = useState<number>(0);
const [zelleBalance, setZelleBalance] = useState<number>(0);
const [linkToken, setLinkToken] = useState<string | null>(null);
const handlePayout = () => {
const payoutDate = new Date().toISOString();
console.log(`Setting last payout date to: ${payoutDate}`);
setLastPayoutDate(payoutDate);
setFilterFromPayout(true);
};
const createLinkToken = useCallback(async () => {
await fetch(`http://localhost:8000/api/create_link_token/`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ address: 'localhost:8000' })
})
.then((response) => response.json())
.then((data) => {
setLinkToken(data.link_token);
})
.catch((err) => {
console.log(err);
});
}, [setLinkToken]);
const createLinkTokenConfiguration = (token: string, noLoadingState: boolean = false) => {
return {
token: token,
noLoadingState: noLoadingState,
};
};
useEffect(() => {
console.log('useEffect triggered. linkToken:', linkToken);
if (linkToken === null) {
console.log('Getting link token');
createLinkToken();
}
if (linkToken) {
const tokenConfig = createLinkTokenConfiguration(linkToken);
create(tokenConfig)
}
}, [filterFromPayout, linkToken]);
const createLinkOpenProps = () => {
return {
onSuccess: async (success: LinkSuccess) => {
await fetch(`http://localhost:8000/api/exchange_link_token/`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ public_token: success.publicToken }),
})
.catch((err) => {
console.log(err);
});
},
onExit: (linkExit: LinkExit) => {
console.log('Exit: ', linkExit);
dismissLink();
},
iOSPresentationStyle: LinkIOSPresentationStyle.MODAL,
logLevel: LinkLogLevel.ERROR,
};
};
const handleOpenLink = () => {
const openProps = createLinkOpenProps();
open(openProps);
};
const filters = ['day', 'week', 'month', 'monthToDate'];
const calculateBalances = () => {
console.log('Calculating balances...');
let filteredTransactions = filterTransactions(mockTransactions, filter);
if (filterFromPayout && lastPayoutDate) {
console.log(`Filtering transactions from last payout date: ${lastPayoutDate}`);
filteredTransactions = filteredTransactions.filter(
txn => new Date(txn.date) > new Date(lastPayoutDate)
);
}
const balance = filteredTransactions.reduce((acc, txn) => {
return txn.type === 'credit' ? acc + txn.amount : acc - txn.amount;
}, 0);
const zelleTxns = filteredTransactions.filter(txn => txn.type === 'debit'); // Assuming 'debit' as Zelle transactions
const zelleTotal = zelleTxns.reduce((acc, txn) => acc + txn.amount, 0);
console.log(`New total balance: ${balance}, New Zelle balance: ${zelleTotal}`);
setTotalBalance(balance);
setZelleBalance(zelleTotal);
};
const filterTransactions = (transactions: Transaction[], filter: string) => {
console.log(`Filtering transactions with filter: ${filter}`);
const now = new Date();
return transactions.filter(txn => {
const txnDate = new Date(txn.date);
switch (filter) {
case 'day':
return isSameDay(now, txnDate);
case 'week':
return isSameWeek(now, txnDate);
case 'month':
return isSameMonth(now, txnDate);
case 'monthToDate':
return txnDate >= new Date(now.getFullYear(), now.getMonth(), 1);
default:
return true;
}
});
};
const isSameDay = (d1: Date, d2: Date) => {
const result = d1.getDate() === d2.getDate() &&
d1.getMonth() === d2.getMonth() &&
d1.getFullYear() === d2.getFullYear();
console.log(`Comparing dates: ${d1.toISOString()} and ${d2.toISOString()}. Same day: ${result}`);
return result;
}
const isSameWeek = (d1: Date, d2: Date) => {
const onejan = new Date(d1.getFullYear(), 0, 1);
const week1 = Math.ceil((((d1.getTime() - onejan.getTime()) / 86400000) + onejan.getDay() + 1) / 7);
const week2 = Math.ceil((((d2.getTime() - onejan.getTime()) / 86400000) + onejan.getDay() + 1) / 7);
const result = week1 === week2 && d1.getFullYear() === d2.getFullYear();
console.log(`Comparing dates: ${d1.toISOString()} and ${d2.toISOString()}. Same week: ${result}`);
return result;
};
const isSameMonth = (d1: Date, d2: Date) => {
const result = d1.getMonth() === d2.getMonth() && d1.getFullYear() === d2.getFullYear();
console.log(`Comparing dates: ${d1.toISOString()} and ${d2.toISOString()}. Same month: ${result}`);
return result;
}
return (
<View style={styles.container}>
<Text style={styles.title}>Total Balance</Text>
<Text style={styles.balance}>${totalBalance.toFixed(2)}</Text>
<Text style={styles.subtitle}>Filters</Text>
<View style={styles.filterContainer}>
{filters.map(f => (
<TouchableOpacity
key={f}
style={[
styles.filterButton,
filter === f && styles.activeFilter
]}
onPress={() => {
console.log(`Filter selected: ${f}`);
setFilter(f);
}}
>
<Text style={styles.filterText}>{f.charAt(0).toUpperCase() + f.slice(1)}</Text>
</TouchableOpacity>
))}
</View>
<Text style={styles.subtitle}>Zelle Transactions</Text>
<Text style={styles.balance}>${zelleBalance.toFixed(2)}</Text>
<Button title="Paid out" onPress={handlePayout} />
<Button title="Connect Bank" onPress={handleOpenLink} />
{filterFromPayout && (
<Text style={styles.payoutFilter}>
From last paid out: {new Date(lastPayoutDate!).toLocaleString()}
</Text>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
backgroundColor: '#fff',
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginVertical: 8,
},
balance: {
fontSize: 32,
fontWeight: 'bold',
textAlign: 'center',
marginVertical: 8,
color: '#4CAF50',
},
subtitle: {
fontSize: 20,
fontWeight: '600',
marginTop: 16,
marginBottom: 8,
},
filterContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
marginBottom: 16,
},
filterButton: {
padding: 10,
borderRadius: 5,
backgroundColor: '#E0E0E0',
},
activeFilter: {
backgroundColor: '#4CAF50',
},
filterText: {
color: '#000',
},
payoutFilter: {
marginTop: 16,
textAlign: 'center',
color: '#FF5722',
},
});
export default BalancePage;
I’ve tried removing the onSuccess, but that doesnt work. I’ve tried using PlaidLink library, but that is deprecated. I’ve tried ChatGPT (lol) but that also just told me to add better logging to debug.
In javascript, how can I make chrome detect the song being played and manage it from the dedicated section for managing audio or video being played, with the cover of a song being played from a tab with title and author?enter image description here
I tried searching online or asking chatgpt, but they were of no help.