I am currently trying to spawn HTML, CSS, JS, and firebase code within dangerouselySetInnerHTML, and the text successfully renders within avatar-initials textContent (initials) for a millisecond, and then it disappears. This also applies to fullName and email, which are in the menu list (render for a millisecond and then disappear). The HTML, CSS, and JS code is rendered in Next JS. I tried to remove useEffect and put htmlCode outside of the function, remove return, but none of those methods worked. I also previously put in an if statement to check for if (document.getElementById('avatar-initials').textContent == "")
then change otherwise don’t, but that also did not work. On the left is picture which spawns for a millisecond on the right is the picture that spawns afterward. If you need more information please let me know. Thank you in advance!
const NavBar = () => {
useEffect(() => {
// Load Firebase SDK scripts
const script = document.createElement('script');
script.src = "https://www.gstatic.com/firebasejs/9.1.3/firebase-app-compat.js";
script.async = true;
document.body.appendChild(script);
const script2 = document.createElement('script');
script2.src = "https://www.gstatic.com/firebasejs/9.1.3/firebase-firestore-compat.js";
script2.async = true;
document.body.appendChild(script2);
script.onload = () => {
script2.onload = () => {
const scriptInit = document.createElement('script');
scriptInit.innerHTML = `
// Check if Firebase has already been initialized
if (!firebase.apps.length) {
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "AIzaSyBJUBPWGwmNfPa127y42YfUSrYcv63Jh3A",
authDomain: "innovatex-c12c6.firebaseapp.com",
projectId: "innovatex-c12c6",
storageBucket: "innovatex-c12c6.appspot.com",
messagingSenderId: "837977074704",
appId: "1:837977074704:web:ad488537707338cdae2e95",
measurementId: "G-EP0JK2ETP7",
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
}
const db = firebase.firestore();
// Fetch user data from Firestore
db.collection("users").doc(localStorage.getItem("id")).get().then((val) => {
const fullName = val.get("fullName");
const email = val.get("email");
const companyId = val.get("company");
document.getElementById('full-name').innerText = fullName;
document.getElementById('email').innerText = email;
console.log(fullName)
console.log(email)
const initials = fullName.split(' ').map((name, index, arr) => {
if (index === 0 || index === arr.length - 1) {
return name.charAt(0);
}
return '';
}).join('');
document.getElementById('avatar-initials').textContent = initials;
if (companyId) {
db.collection('companies').doc(companyId).get().then((doc) => {
if (doc.exists) {
const employees = doc.data().activeEmployees || {};
window.employees = employees;
}
});
}
});
function navigateTo(url) {
window.location.href = url;
}
function handleSearchQueryChange(event) {
const searchQuery = event.target.value.toLowerCase();
if (searchQuery) {
const filteredEmployees = Object.keys(window.employees).filter((key) =>
window.employees[key].fullName.toLowerCase().includes(searchQuery)
);
showDropdown(true, filteredEmployees);
} else {
showDropdown(false, []);
}
}
function showDropdown(show, filteredEmployees) {
const dropdown = document.getElementById('search-dropdown');
if (show) {
dropdown.style.display = 'flex';
dropdown.innerHTML = filteredEmployees
.map(
(userId) =>
`<button onclick="navigateTo('/c/view/' + '${userId}')">${window.employees[userId].fullName}</button>`
)
.join('');
} else {
dropdown.style.display = 'none';
}
}
function toggleCalculatorPopover() {
const popover = document.getElementById('calculator-popover');
popover.style.display = popover.style.display === 'none' ? 'block' : 'none';
}
function toggleMenu() {
const menuList = document.getElementById('menu-list');
menuList.style.display = menuList.style.display === 'none' ? 'block' : 'none';
}
async function logout() {
localStorage.removeItem('id');
window.location.href = '/';
alert('Logout Successful...');
await firebase.auth().signOut()
}
// Calculator functionality
let input = '';
let result = '';
function handleButtonClick(value) {
input += value;
document.getElementById('calculator-input').value = input;
}
function handleClear() {
input = '';
result = '';
document.getElementById('calculator-input').value = '';
document.getElementById('calculator-result').value = '';
}
function handleCalculate() {
try {
const evaluatedResult = evaluateExpression(input);
result = evaluatedResult;
document.getElementById('calculator-result').value = result;
} catch (error) {
document.getElementById('calculator-result').value = 'Error';
}
}
function evaluateExpression(expr) {
const sanitizedExpr = expr
.replace(/\^/g, '**')
.replace(/\|([^|]+)\|/g, 'Math.abs($1)');
return Function(`'use strict'; return (${sanitizedExpr})`)();
}
function handleInputChange(event) {
const value = event.target.value;
const validChars = '0123456789+-*/^().|';
let sanitizedValue = '';
for (let i = 0; i < value.length; i++) {
if (validChars.includes(value[i])) {
sanitizedValue += value[i];
}
}
input = sanitizedValue;
event.target.value = sanitizedValue;
}
function handleKeyPress(event) {
if (event.key === 'Enter') {
handleCalculate();
}
}
document.addEventListener('click', function(event) {
const menuList = document.getElementById('menu-list');
// const calculatorPopover = document.getElementById('calculator-popover');
if (!event.target.closest('#menu-list') && !event.target.closest('#avatar-initials')) {
menuList.style.display = 'none';
}
// if (!event.target.closest('#calculator-popover') && !event.target.closest('.calculator-button')) {
// calculatorPopover.style.display = 'none';
// }
});
document.getElementById('calculator-input').addEventListener('keypress', handleKeyPress);
document.getElementById('search-input').addEventListener('blur', function() {
showDropdown(false, []);
});
document.getElementById('calculator-popover').addEventListener('blur', function() {
this.style.display = 'none';
});
`;
document.body.appendChild(scriptInit);
};
};
return () => {
document.body.removeChild(script);
document.body.removeChild(script2);
};
}, []);
console.log('once')
const htmlCode = `
<style>
.sidebar {
display: flex;
flex-direction: column;
width: 80px;
height: calc(100vh - 100px);
background-color: #000000;
align-items: center;
padding: 5px;
position: fixed;
top: 85px;
overflow-y: scroll;
left: 8px;
z-index: 1;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.hover-text {
position: relative;
display: inline-block;
}
.hover-text .hover-content {
visibility: hidden;
width: 70px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
position: absolute;
z-index: 1;
bottom: -50%;
left: 100%;
margin-left: -60px;
opacity: 0;
transition: opacity 0.3s;
font-size: 9pt;
}
.hover-text:hover .hover-content {
visibility: visible;
opacity: 1;
}
.icon-button {
margin-bottom: 10px;
border-radius: 8px;
border: none;
cursor: pointer;
padding: 10px;
display: flex;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
}
.icon-button:hover {
background-color: #a0a0a0;
}
.icon-button img {
filter: brightness(0) invert(1);
}
.divider {
margin-bottom: 14px;
margin-top: 8px;
border-color: #dcdcdc;
width: 60%;
height: 1px;
background-color: #dcdcdc;
}
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
width: calc(100% - 20px);
border-radius: 8px;
padding: 4px 5px;
background-color: #000000;
position: fixed;
top: 3px;
left: 8px;
right: 0;
z-index: 2;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
}
.search-box {
position: relative;
width: 300px;
margin: 0 auto;
}
.search-box input {
width: 100%;
padding: 10px 20px;
border-radius: 50px;
border: none;
background-color: #ffffff;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
autocomplete: off;
}
.search-dropdown {
display: flex;
flex-direction: column;
position: absolute;
width: 300px;
background-color: #ffffff;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
border-radius: 8px;
z-index: 3;
}
.search-dropdown button {
display: flex;
align-items: center;
justify-content: flex-start;
border-top: 1px solid #e0e0e0;
padding: 10px;
background-color: #ffffff;
border: none;
cursor: pointer;
width: 100%;
}
.search-dropdown button:hover {
background-color: #f7f7f7;
}
.avatar-menu {
display: flex;
margin-top: 8px;
direction: row;
align-items: center;
justify-content: center;
gap: 3px;
}
.avatar-menu button {
background-color: transparent;
border: none;
cursor: pointer;
}
.avatar-initials {
display: flex;
align-items: center;
justify-content: center;
background-color: purple;
color: white;
border-radius: 50%;
width: 45px;
height: 45px;
font-size: 14pt;
font-weight: 600;
border: 1.5px solid white;
}
.avatar-initials:hover {
opacity:0.85;
}
.menu-list {
display: flex;
flex-direction: column;
align-items: left;
justify-content: center;
padding: 10px;
background-color: #ffffff;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
border-radius: 8px;
position: absolute;
top: 60px;
right: 10px;
z-index: 3;
width: 250px; /* Increased width */
}
.menu-item {
display: flex;
align-items: center;
padding: 10px;
cursor: pointer;
}
.menu-item:hover {
background-color: #f7f7f7;
}
.popover-content {
background-color: #ffffff;
width: 500px;
position: absolute;
top: 75px;
right: 10px;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
border-radius: 8px;
padding: 10px;
}
.popover-header {
font-weight: 500;
font-size: 16pt;
color: #000000;
margin-bottom: 10px;
}
.popover-close-button {
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
background-color: transparent;
border: none;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 8px;
padding-right: 8px;
border-radius: 5px;
}
.popover-close-button:hover {
background-color: #dfdfdf;
}
.calculator-container {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.calculator-input,
.calculator-result {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border-radius: 8px;
border: 1px solid #ccc;
}
.calculator-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.calculator-button {
background-color: #b0b0b0;
border: none;
padding: 20px;
border-radius: 8px;
cursor: pointer;
}
.calculator-button:hover {
background-color: #a0a0a0;
}
.calculator-clear {
grid-column: span 4;
background-color: red;
color: white;
}
.calculator {
width: 100%;
max-width: 400px;
border: 1px solid #2D3748;
border-radius: 0.375rem;
padding: 1.25rem;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
background-color: #2D3748;
}
.calculator input {
width: 100%;
padding: 0.75rem;
margin-bottom: 0.75rem;
border-radius: 0.375rem;
background-color: #2A2F45;
color: white;
font-size: 1.25rem;
text-align: right;
border: none;
}
.calculator-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.75rem;
}
.calculator-button {
padding: 0.75rem;
font-size: 1.25rem;
border-radius: 0.375rem;
background-color: #319795;
color: white;
border: none;
cursor: pointer;
}
.calculator-button-clear {
grid-column: span 4;
background-color: #E53E3E;
}
</style>
<div>
<div class="sidebar">
<div class="hover-text">
<button style="margin-top: 8px" class="icon-button" onclick="navigateTo('/c/main')">
<img src="/home.png" width="25" height="25" />
</button>
<span class="hover-content">Home</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/todolist/overview')">
<img src="/todolist.png" width="25" height="25" />
</button>
<span class="hover-content">To-Do List</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/applicantTracking/overall')">
<img src="/ats.png" width="25" height="25" />
</button>
<span class="hover-content">ATS</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/forum/overall')">
<img src="/forum.png" width="25" height="25" />
</button>
<span class="hover-content">Public Forum</span>
</div>
<div class="divider"></div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/timeTracker/overall')">
<img src="/timeTracker.png" width="25" height="25" />
</button>
<span class="hover-content">Time Tracker</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/timeOff/overall')">
<img src="/timeOff2.png" width="25" height="25" />
</button>
<span class="hover-content">Time Off</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/benefits/overall')">
<img src="/benefits.png" width="25" height="25" />
</button>
<span class="hover-content">Benefits</span>
</div>
<div class="divider"></div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/payroll/overview')">
<img src="/payroll.png" width="25" height="25" />
</button>
<span class="hover-content">Payroll</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/customize')">
<img src="/customize.png" width="25" height="25" />
</button>
<span class="hover-content">Customize</span>
</div>
</div>
<div class="navbar">
<div style="display: flex; align-items: center; gap: 5px;">
<button style="color: white; margin-left: 20px; margin-right: 20px; font-family: Montserrat; background-color: transparent; border: none; font-size: 30pt; font-weight: 800; cursor: pointer;" onclick="navigateTo('/c/main')">
<i>I</i>
</button>
<div class="search-box">
<input type="text" id="search-input" placeholder="Search for a co-worker" autocomplete="off" oninput="handleSearchQueryChange(event)" />
<div id="search-dropdown" class="search-dropdown" style="display: none;">
<!-- Dropdown content will be injected here -->
</div>
</div>
</div>
<div class="avatar-menu">
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/employees')">
<img src="/people.png" width="25" height="25" />
</button>
<span class="hover-content">Employees</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="navigateTo('/c/privateToDo')">
<img src="/toDo.png" width="25" height="25" />
</button>
<span class="hover-content">Private To-Do List</span>
</div>
<div class="hover-text">
<button class="icon-button" onclick="toggleCalculatorPopover()">
<img src="/calculator.png" width="25" height="25" />
</button>
<span class="hover-content">Calculator</span>
</div>
<a href="/c/feedback" style="color: white; font-weight: 800; text-decoration: none; margin-bottom: 8px; margin-left: 5px;">FEEDBACK</a>
<a href="/c/help" style="color: white; margin-bottom: 8px; margin-left: 5px; margin-right: 8px;"><img src="/info.png" width="25" height="25;" /></a>
<div style="margin-left: 14px; margin-right: 22px;">
<button onclick="toggleMenu()">
<div id="avatar-initials" class="avatar-initials"></div>
</button>
<div id="menu-list" class="menu-list" style="display: none;">
<div style="display: flex; flex-direction: column; align-items: left; justify-content: center; padding: 10px;">
<span id="full-name" style="font-size: 12pt; font-weight: 700; color: #000000;"></span>
<span id="email" style="font-size: 10pt; color: gray;"></span>
</div>
<div class="menu-item" onclick="logout()">
<img src="/logout.png" width="25" height="25" />
Log Out
</div>
</div>
</div>
</div>
</div>
<div id="calculator-popover" class="popover-content" style="display: none; z-index: 9999999;" tabindex="0">
<button class="popover-close-button" onclick="toggleCalculatorPopover()" style="font-weight: 900; font-size: 16pt"><img style="width: 20px; height: 20px;" src="/close.png"></button>
<div class="calculator" style="margin-top: 40px; margin-left: 40px">
<input id="calculator-input" placeholder="0" oninput="handleInputChange(event)" onkeypress="handleKeyPress(event)">
<input id="calculator-result" placeholder="Result" readonly>
<div class="calculator-grid">
${["7", "8", "9", "/"].map(value => `
<button class="calculator-button" onclick="handleButtonClick('${value}')">${value}</button>
`).join('')}
${["4", "5", "6", "*"].map(value => `
<button class="calculator-button" onclick="handleButtonClick('${value}')">${value}</button>
`).join('')}
${["1", "2", "3", "-"].map(value => `
<button class="calculator-button" onclick="handleButtonClick('${value}')">${value}</button>
`).join('')}
${["0", ".", "(", ")"].map(value => `
<button class="calculator-button" onclick="handleButtonClick('${value}')">${value}</button>
`).join('')}
${["+", "="].map(value => `
<button class="calculator-button" onclick="${value === '=' ? 'handleCalculate()' : `handleButtonClick('${value}')`}">${value}</button>
`).join('')}
<button class="calculator-button" onclick="handleButtonClick('^')">^</button>
<button class="calculator-button" onclick="handleButtonClick('|')">|</button>
<button class="calculator-button calculator-button-clear" onclick="handleClear()">Clear</button>
</div>
</div>
</div>
</div>
`;
return (
<VStack spacing={4} align="center" marginBottom="5vh">
{/* <Box width="100%" maxW="400px" borderWidth="1px" borderRadius="lg" p={5} boxShadow="lg" backgroundColor="gray.700"> */}
<div dangerouslySetInnerHTML={{ __html: htmlCode }} />
{/* </Box> */}
</VStack>
);
};