separate header into a diff component

This commit is contained in:
AnisHADJARAB 2024-10-30 14:02:29 +00:00
parent d7da806989
commit 2ad34191d2
11 changed files with 269 additions and 262 deletions

View File

@ -11,6 +11,8 @@
<title>4NK Application</title>
</head>
<body>
<div id="header-container"></div>
<div id="containerId" class="container">
<!-- 4NK Web5 Solution -->
</div>

View File

@ -83,7 +83,7 @@ body {
background: radial-gradient(circle, white, var(--primary-color));
/* background-color: #CFD8DC; */
display: flex;
justify-content: space-between;
justify-content: flex-end;
align-items: center;
color: #37474F;
height: 9vh;
@ -99,6 +99,7 @@ body {
display: inline-block;
}
.notification-bell, .burger-menu {
z-index: 3;
height: 20px;
width: 20px;
margin-right: 1rem;
@ -144,6 +145,14 @@ body {
}
.brand-logo {
height: 100%;
width: 100vw;
align-content: center;
position: relative;
display: flex;
position: absolute;
align-items: center;
justify-content: center;
text-align: center;
font-size: 1.5em;
font-weight: bold;

View File

@ -0,0 +1,28 @@
<div class="nav-wrapper">
<div class="brand-logo">4NK</div>
<div class="nav-right-icons">
<div class="notification-container">
<div class="bell-icon">
<svg class="notification-bell" onclick="openCloseNotifications()" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"/></svg>
</div>
<div class="notification-badge"></div>
<div id="notification-board" class="notification-board">
<div class="no-notification">No notifications available</div>
</div>
</div>
<div class="burger-menu">
<svg class="burger-menu" onclick="toggleMenu()" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/>
</svg>
<div class="menu-content" id="menu">
<a onclick="unpair()">Revoke</a>
<a>Export</a>
<a>Import</a>
<a>Disconnect</a>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,60 @@
import { currentRoute } from "../../router";
import Services from "../../services/service";
let notifications = []
export async function unpair() {
const service = await Services.getInstance();
await service.unpairDevice();
}
window.unpair = unpair;
function toggleMenu() {
const menu = document.getElementById('menu');
if (menu.style.display === 'block') {
menu.style.display = 'none';
} else {
menu.style.display = 'block';
}
}
window.toggleMenu = toggleMenu
async function getNotifications() {
const service = await Services.getInstance()
notifications = service.getNotifications()
console.log("🚀 ~ getNotifications ~ notifications:", notifications)
const badge = document.querySelector('.notification-badge')
if(badge) badge.innerHTML= notifications.length
}
function openCloseNotifications() {
const notifications = document.querySelector('.notification-board');
console.log("🚀 ~ openCloseNotifications ~ notifications:", notifications)
notifications.style.display = notifications?.style.display === 'none' ? 'block' : 'none';
}
window.openCloseNotifications = openCloseNotifications
if(currentRoute === 'home') {
hideSomeFunctionnalities()
} else {
getNotifications()
}
function hideSomeFunctionnalities() {
const bell = document.querySelector('.bell-icon')
if(bell) bell.style.display = 'none';
const notifBadge = document.querySelector('.notification-badge')
if(notifBadge) notifBadge.style.display = 'none';
const actions = document.querySelectorAll('.menu-content a')
console.log("🚀 ~ hideSomeFunctionnalities ~ actions:", actions)
for(const action of actions) {
console.log("🚀 ~ hideSomeFunctionnalities ~ action:", action)
if(action.innerHTML !== 'Import') {
action.style.display = 'none';
}
}
}

View File

@ -1,32 +1,4 @@
<div class="nav-wrapper">
<div></div>
<div class="brand-logo">4NK</div>
<div class="nav-right-icons">
<div class="notification-container">
<div id="notification-bell" class="bell-icon">
<svg class="notification-bell" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"/></svg>
</div>
<div class="notification-badge"></div>
<div id="notification-board" class="notification-board">
<div class="no-notification">No notifications available</div>
</div>
</div>
<div class="burger-menu">
<svg class="burger-menu" onclick="toggleMenu()" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/>
</svg>
<div class="menu-content" id="menu">
<a href="#">Import</a>
<!-- <button onclick="openModal()">Open Modal</button> -->
</div>
</div>
</div>
</div>
<div class="title-container">
<h1>Create Account / New Session</h1>
</div>

View File

@ -1,31 +1,4 @@
<div class="nav-wrapper">
<div></div>
<div class="brand-logo">4NK</div>
<div class="nav-right-icons">
<div class="notification-container">
<div class="bell-icon">
<svg class="notification-bell" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"/></svg>
</div>
<div class="notification-badge">1</div>
</div>
<div class="burger-menu">
<svg class="burger-menu" onclick="toggleMenu()" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/>
</svg>
<div class="menu-content" id="menu">
<a href="#">Revoke</a>
<a href="#">Export</a>
<a href="#">Import</a>
<a href="#">Disconnect</a>
</div>
</div>
</div>
</div>
<div class="title-container">
<h1>Process {{processTitle}}</h1>
</div>

View File

@ -1,19 +1,15 @@
import Services from "../../services/service"
import Services from '../../services/service';
let currentPageStyle: HTMLStyleElement | null = null;
export async function initProcessElement(id: string, zone: string) {
console.log("🚀 ~ init ~ id:", id)
const processes = await getProcesses()
const currentProcess = processes.find(process => process[0] === id)[1]
console.log("🚀 ~ init ~ currentProcess:", currentProcess)
const test = await loadPage({processTitle: currentProcess.title, inputValue: 'Hello World !'})
console.log("🚀 ~ initProcessElement ~ test:", currentProcess.html)
const wrapper = document.querySelector('.process-container')
const processes = await getProcesses();
const currentProcess = processes.find((process) => process[0] === id)[1];
await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' });
const wrapper = document.querySelector('.process-container');
if (wrapper) {
wrapper.innerHTML = interpolate(currentProcess.html, {processTitle: currentProcess.title, inputValue: 'Hello World !'})
injectCss(currentProcess.css)
wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' });
injectCss(currentProcess.css);
}
}
@ -48,8 +44,6 @@ function removeCss() {
async function getProcesses(): Promise<any[]> {
const service = await Services.getInstance();
const processes = await service.getProcesses()
console.log("🚀 ~ Services ~ getProcesses ~ processes:", processes)
return processes
const processes = await service.getProcesses();
return processes;
}

View File

@ -1,31 +1,4 @@
<div class="nav-wrapper">
<div></div>
<div class="brand-logo">4NK</div>
<div class="nav-right-icons">
<div class="notification-container">
<div class="bell-icon">
<svg class="notification-bell" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"/></svg>
</div>
<div class="notification-badge">1</div>
</div>
<div class="burger-menu">
<svg class="burger-menu" onclick="toggleMenu()" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/>
</svg>
<div class="menu-content" id="menu">
<a href="#" onclick="unpair()">Revoke</a>
<a href="#">Export</a>
<a href="#">Import</a>
<a href="#">Disconnect</a>
</div>
</div>
</div>
</div>
<div class="title-container">
<h1>Process Selection</h1>
</div>

View File

@ -1,14 +1,5 @@
import { navigate } from '../../router';
import Services from '../../services/service';
import { IProcess } from '~/models/process.model';
function toggleMenu() {
const menu = document.getElementById('menu') as HTMLDivElement;
if (menu.style.display === 'block') {
menu.style.display = 'none';
} else {
menu.style.display = 'block';
}
}
// Initialize function, create initial tokens with itens that are already selected by the user
export async function init() {
@ -40,13 +31,12 @@ export async function init() {
search_div.appendChild(autocomplete_list);
search_div.appendChild(dropdown_icon);
const processes = await getProcesses();
for (let process of processes) {
const processName = process[1].title;
const opt = new Option(processName)
opt.value = processName
element.add(opt)
const opt = new Option(processName);
opt.value = processName;
element.add(opt);
}
// set the wrapper as child (instead of the element)
element.parentNode?.replaceChild(wrapper, element);
@ -153,7 +143,6 @@ function clickDropdown(e: Event) {
dropdown.classList.toggle('active');
if (dropdown.classList.contains('active')) {
removePlaceholder(wrapper as HTMLElement);
input_search?.focus();
@ -179,7 +168,7 @@ function clearAutocompleteList(select: HTMLSelectElement) {
// Populate the autocomplete list following a given query from the user
function populateAutocompleteList(select: HTMLSelectElement, query: string, dropdown = false) {
const { autocomplete_options } = getOptions(select);
console.log("🚀 ~ populateAutocompleteList ~ autocomplete_options:", autocomplete_options)
console.log('🚀 ~ populateAutocompleteList ~ autocomplete_options:', autocomplete_options);
let options_to_show;
@ -220,12 +209,12 @@ function populateAutocompleteList(select: HTMLSelectElement, query: string, drop
// Listener to autocomplete results when clicked set the selected property in the select option
function selectOption(e: any) {
console.log("🚀 ~ selectOption ~ e:", e)
console.log('🚀 ~ selectOption ~ e:', e);
const wrapper = e.target.parentNode.parentNode.parentNode;
const input_search = wrapper.querySelector('.selected-input');
const option = wrapper.querySelector(`select option[value="${e.target.dataset.value}"]`);
console.log("🚀 ~ selectOption ~ option:", option)
console.log('🚀 ~ selectOption ~ option:', option);
option.setAttribute('selected', '');
createToken(wrapper, e.target.dataset.value);
if (input_search.value) {
@ -337,13 +326,6 @@ function deletePressed(e: KeyboardEvent) {
return true;
}
// function addOption(target, val, text) {
// const select = document.querySelector(target);
// let opt = document.createElement("option");
// opt.value = val;
// opt.innerHTML = text;
// select.appendChild(opt);
// }
// Dismiss on outside click
document.addEventListener('click', () => {
// get select that has the options available
@ -365,13 +347,6 @@ document.addEventListener('click', () => {
}
});
export async function unpair() {
const service = await Services.getInstance();
await service.unpairDevice();
}
(window as any).unpair = unpair;
async function showSelectedProcess(elem: MouseEvent) {
if (elem) {
const cardContent = document.querySelector('.process-card-content');
@ -396,7 +371,7 @@ async function showSelectedProcess(elem: MouseEvent) {
zoneElement.innerHTML = `${zone.title}: ${zone.description}`;
const service = await Services.getInstance();
// service.addSubscription(zoneElement, 'click', 'goToProcessPage');
zoneElement.addEventListener('click', select)
zoneElement.addEventListener('click', select);
processDiv.appendChild(zoneElement);
}
if (cardContent) cardContent.appendChild(processDiv);
@ -406,32 +381,32 @@ async function showSelectedProcess(elem: MouseEvent) {
function select(event: MouseEvent) {
const target = event.target as HTMLElement;
const oldSelectedProcess = document.querySelector('.selected-process-zone')
oldSelectedProcess?.classList.remove('selected-process-zone')
const oldSelectedProcess = document.querySelector('.selected-process-zone');
oldSelectedProcess?.classList.remove('selected-process-zone');
if (target) {
target.classList.add('selected-process-zone')
target.classList.add('selected-process-zone');
}
const name = target.getAttribute('zone-id')
console.log("🚀 ~ select ~ name:", name)
const name = target.getAttribute('zone-id');
console.log('🚀 ~ select ~ name:', name);
}
function goToProcessPage() {
const target = document.querySelector('.selected-process-zone');
console.log("🚀 ~ goToProcessPage ~ event:", target)
console.log('🚀 ~ goToProcessPage ~ event:', target);
if (target) {
const process = target?.getAttribute('process-id');
console.log('=======================> going to process page', process);
navigate('process-element/' + process)
navigate('process-element/' + process);
}
}
(window as any).goToProcessPage = goToProcessPage
(window as any).goToProcessPage = goToProcessPage;
async function getProcesses(): Promise<any[]> {
const service = await Services.getInstance();
const processes = await service.getProcesses()
console.log("🚀 ~ Services ~ getProcesses ~ processes:", processes)
const processes = await service.getProcesses();
console.log('🚀 ~ Services ~ getProcesses ~ processes:', processes);
return processes
return processes;
}

View File

@ -7,12 +7,12 @@ const routes: { [key: string]: string } = {
'process-element': '/src/pages/process-element/process-element.html',
};
export let currentRoute = ''
export let currentRoute = '';
export async function navigate(path: string) {
path = path.replace(/^\//, '');
if (path.includes('/')) {
const parsedPath = path.split('/')[0]
const parsedPath = path.split('/')[0];
if (!routes[parsedPath]) {
path = 'home';
}
@ -22,10 +22,9 @@ export async function navigate(path: string) {
}
async function handleLocation(path: string) {
console.log("🚀 ~ handleLocation ~ path:", path)
const parsedPath = path.split('/')
const parsedPath = path.split('/');
if (path.includes('/')) {
path = parsedPath[0]
path = parsedPath[0];
}
const routeHtml = routes[path] || routes['home'];
@ -33,23 +32,23 @@ async function handleLocation(path: string) {
if (content) {
const html = await fetch(routeHtml).then((data) => data.text());
content.innerHTML = html;
await new Promise(requestAnimationFrame);
injectHeader();
if (path === 'home') {
const { initHomePage } = await import('./pages/home/home');
initHomePage();
} else if (path === 'process') {
const { init } = await import('./pages/process/process');
init()
init();
} else if (path.includes('process-element')) {
const { initProcessElement } = await import('./pages/process-element/process-element');
if (parsedPath && parsedPath.length) {
const parseProcess = parsedPath[1].split('_')
initProcessElement(parseProcess[0], parseProcess[1])
const parseProcess = parsedPath[1].split('_');
initProcessElement(parseProcess[0], parseProcess[1]);
}
}
currentRoute = path
currentRoute = path;
}
}
@ -71,20 +70,20 @@ async function init(): Promise<boolean> {
await services.restoreProcesses();
await services.restoreMessages();
// if (services.isPaired()) {
// isPaired = true;
// console.log('🚀 ~ setTimeout ~ isPaired:', isPaired);
// await navigate('process');
// return isPaired;
// } else {
// const queryString = window.location.search;
// const urlParams = new URLSearchParams(queryString);
// const pairingAddress = urlParams.get('sp_address');
// if (pairingAddress) {
// setTimeout(async () => await services.sendPairingTx(pairingAddress), 2000);
// }
// return isPaired;
// }
if (services.isPaired()) {
isPaired = true;
console.log('🚀 ~ setTimeout ~ isPaired:', isPaired);
await navigate('process');
return isPaired;
} else {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const pairingAddress = urlParams.get('sp_address');
if (pairingAddress) {
setTimeout(async () => await services.sendPairingTx(pairingAddress), 2000);
}
return isPaired;
}
}, 200);
} catch (error) {
console.error(error);
@ -93,8 +92,21 @@ async function init(): Promise<boolean> {
return isPaired;
}
async function injectHeader() {
const headerContainer = document.getElementById('header-container');
if (headerContainer) {
const headerHtml = await fetch('/src/components/header/header.html').then((res) => res.text());
headerContainer.innerHTML = headerHtml;
// Dynamically load the header JS
const script = document.createElement('script');
script.src = '/src/components/header/header.js';
script.type = 'module';
document.head.appendChild(script);
}
}
(async () => {
const isPaired = await init();
console.log('🚀 ~ handleLocation ~ isPaired:', isPaired);
await navigate('process');
await navigate('home');
})();

View File

@ -548,22 +548,26 @@ export default class Services {
async getProcesses(): Promise<any[]> {
const process = [
['1',{
[
'1',
{
title: 'Messaging',
description: 'Messagerie chiffrée',
html: '<div><input /></div>',
css: '',
script: '',
zones: [{
zones: [
{
id: '1',
title: 'zone 1',
description: 'zone 1'
description: 'zone 1',
},
{
id: '2',
title: 'zone 2',
description: 'zone 2'
}],
description: 'zone 2',
},
],
roles: {
owner: {
members: ['dfdsfdfdsf', 'dfdfdfdsfsfdfdsf'],
@ -576,23 +580,28 @@ export default class Services {
],
},
},
}],
['2',{
},
],
[
'2',
{
title: 'Database',
description: 'Database chiffrée',
html: '<div><input value="{{inputValue}}" /></div>',
css: '',
script: '',
zones: [{
zones: [
{
id: '1',
title: 'zone 1',
description: 'zone 1'
description: 'zone 1',
},
{
id: '2',
title: 'zone 2',
description: 'zone 2'
}],
description: 'zone 2',
},
],
roles: {
owner: {
members: ['dfdsfdfdsf', 'dfdfdfdsfsfdfdsf'],
@ -605,12 +614,12 @@ export default class Services {
],
},
},
}],
},
],
];
return process
return process;
}
private getProcessesCache(): ProcessesCache {
// Regular expression to match 64-character hexadecimal strings
const hexU32KeyRegex: RegExp = /^[0-9a-fA-F]{64}:\d+$/;
@ -709,7 +718,7 @@ export default class Services {
}
public async setProcessesInSelectElement(processList: any[]) {
console.log("🚀 ~ Services ~ setProcessesInSelectElement ~ processList:", processList)
console.log('🚀 ~ Services ~ setProcessesInSelectElement ~ processList:', processList);
const select = document.querySelector('.select-field');
if (select) {
for (const process of processList) {