mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
enhance tabindex + float button + utm + i18n
* tabindex is working with banner * add new lang and it is working * enhance some tabindex *add utm to blog posts
This commit is contained in:
parent
9caa00c4c6
commit
75e483405d
11 changed files with 196 additions and 42 deletions
|
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
|
||||
* {
|
||||
@apply focus:outline-2 focus:outline-secondary focus:outline-offset-4;
|
||||
@apply focus:outline-4 focus:outline-secondary focus:outline-offset-4;
|
||||
}
|
||||
|
||||
.ace_editor,
|
||||
|
|
@ -111,11 +111,11 @@ body {
|
|||
|
||||
/* HEADER */
|
||||
.header-container {
|
||||
@apply col-span-12 w-full relative h-full max-h-screen transition-all duration-200 ease-in-out rounded-xl;
|
||||
@apply w-full relative h-full max-h-screen transition-all duration-200 ease-in-out xl:ml-68 rounded-xl;
|
||||
}
|
||||
|
||||
.header-el {
|
||||
@apply relative flex flex-wrap items-center justify-between px-0 py-2 mr-6 transition-all ease-in shadow-none duration-250 rounded-2xl lg:flex-nowrap lg:justify-start;
|
||||
@apply relative flex flex-wrap items-center justify-between px-0 pb-2 sm:mx-6 transition-all ease-in shadow-none duration-250 rounded-2xl lg:flex-nowrap lg:justify-start;
|
||||
}
|
||||
|
||||
.header-wrap {
|
||||
|
|
@ -127,7 +127,7 @@ body {
|
|||
}
|
||||
|
||||
.header-breadcrumb-container {
|
||||
@apply flex flex-col xs:flex-row flex-wrap pt-1 mr-12 bg-transparent rounded-lg sm:mr-16;
|
||||
@apply flex flex-wrap pt-1 mr-12 bg-transparent rounded-lg sm:mr-16;
|
||||
}
|
||||
|
||||
.header-breadcrumb-item {
|
||||
|
|
@ -440,6 +440,13 @@ body {
|
|||
@apply dark:brightness-125 font-medium underline text-gray-100 dark:text-gray-50 hover:no-underline;
|
||||
}
|
||||
|
||||
.banner-tabindex-highlight {
|
||||
@apply !transition-none !fixed !left-0 !opacity-100 z-20;
|
||||
}
|
||||
|
||||
.banner-tabindex-hide {
|
||||
@apply !transition-none !fixed !opacity-100 z-10;
|
||||
}
|
||||
/* MENU */
|
||||
|
||||
.menu-account-title-container {
|
||||
|
|
@ -455,7 +462,7 @@ body {
|
|||
}
|
||||
|
||||
.menu-float-btn {
|
||||
@apply transition-all scale-90 sm:scale-100 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 xl:hidden fixed p-3 text-xl bg-white shadow cursor-pointer right-5 sm:right-[5.5rem] z-990 rounded-circle text-slate-700 flex justify-center items-center;
|
||||
@apply transition-all scale-90 sm:scale-100 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 xl:hidden fixed p-3 text-xl bg-white shadow cursor-pointer right-4 sm:right-[9.75rem] xl:right-24 z-990 rounded-circle text-slate-700 flex justify-center items-center;
|
||||
}
|
||||
|
||||
.menu-float-btn-svg {
|
||||
|
|
@ -463,11 +470,11 @@ body {
|
|||
}
|
||||
|
||||
.no-banner.menu-float-btn {
|
||||
@apply top-2;
|
||||
@apply top-[4rem] sm:top-2;
|
||||
}
|
||||
|
||||
.banner.menu-float-btn {
|
||||
@apply top-[4.5rem];
|
||||
@apply top-[8rem] sm:top-[4.5rem];
|
||||
}
|
||||
|
||||
.menu-close-btn {
|
||||
|
|
@ -786,7 +793,7 @@ body {
|
|||
}
|
||||
|
||||
.footer-list-item {
|
||||
@apply hover:italic hover:brightness-90 block sm:px-4 pt-1 pb-0 lg:pb-1 text-xs lg:text-sm tracking-wide font-normal transition duration-300 ease-in-out text-white dark:text-white;
|
||||
@apply capitalize-first hover:italic hover:brightness-90 block sm:px-4 py-1 lg:pt-1 lg:pb-1 text-sm tracking-wide font-normal transition duration-300 ease-in-out text-white dark:text-white;
|
||||
}
|
||||
/* CARD STAT COMPONENT */
|
||||
|
||||
|
|
@ -1141,15 +1148,15 @@ body {
|
|||
/* FEEDBACK */
|
||||
|
||||
.feedback-float-btn-container {
|
||||
@apply transition-all hover:brightness-75 dark:hover:brightness-105 fixed right-4 sm:right-[9.75rem] xl:right-24 z-990;
|
||||
@apply transition-all hover:brightness-75 dark:hover:brightness-105 fixed right-5 sm:right-[5.5rem] z-990;
|
||||
}
|
||||
|
||||
.no-banner.feedback-float-btn-container {
|
||||
@apply top-[4rem] sm:top-2;
|
||||
@apply top-2;
|
||||
}
|
||||
|
||||
.banner.feedback-float-btn-container {
|
||||
@apply top-[8rem] sm:top-[4.5rem];
|
||||
@apply top-[4.5rem];
|
||||
}
|
||||
|
||||
.feedback-float-btn {
|
||||
|
|
@ -1204,10 +1211,6 @@ body {
|
|||
@apply flex flex-col justify-start items-center h-full m-2 overflow-y-auto;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.feedback-alert-container {
|
||||
@apply flex justify-center w-full;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -16,21 +16,22 @@ const banner = reactive({
|
|||
visibleId: 1,
|
||||
default : [
|
||||
{
|
||||
title: "title_1",
|
||||
link: "link_1",
|
||||
linkText: "link_text_1",
|
||||
title: "Get the most of BunkerWeb by upgrading to the PRO version. More info and free trial",
|
||||
link: "https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#pro",
|
||||
linkText: "here",
|
||||
},
|
||||
{
|
||||
title: "title_2",
|
||||
link: "link_2",
|
||||
linkText: "link_text_2",
|
||||
title: "Need premium support or tailored consulting around BunkerWeb ? Check out our",
|
||||
link: "https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#services",
|
||||
linkText: "professional services.",
|
||||
},
|
||||
{
|
||||
title: "title_3",
|
||||
link: "link_3",
|
||||
linkText: "link_text_3",
|
||||
title: "Be part of the Bunker community by joining the",
|
||||
link: "Discord chat.",
|
||||
linkText: "https://discord.bunkerweb.io",
|
||||
},
|
||||
],
|
||||
isTabIndex: false,
|
||||
api: [],
|
||||
apiFormat : computed(() => {
|
||||
if(banner.api.length === 0) return [];
|
||||
|
|
@ -44,9 +45,6 @@ const banner = reactive({
|
|||
}),
|
||||
});
|
||||
|
||||
const data = [{
|
||||
"content": "<p class='p-0 mx-'>content_1</p>",
|
||||
}]
|
||||
// I want to replace the content class content by banner-item-text
|
||||
|
||||
function setupBanner() {
|
||||
|
|
@ -65,6 +63,7 @@ function setupBanner() {
|
|||
banner.api =
|
||||
JSON.parse(sessionStorage.getItem("bannerNews"))
|
||||
banner.default = [];
|
||||
runBanner();
|
||||
return;
|
||||
}
|
||||
// Try to fetch api data
|
||||
|
|
@ -93,10 +92,10 @@ function setupBanner() {
|
|||
|
||||
// Banner animation effect
|
||||
function runBanner() {
|
||||
const nextDelay = 14000;
|
||||
const transDuration = 10000;
|
||||
const nextDelay = 8000;
|
||||
const transDuration = 1000;
|
||||
// Switch item every interval and
|
||||
setInterval(() => {
|
||||
setTimeout(() => {
|
||||
const prev = banner.visibleId;
|
||||
banner.visibleId = banner.visibleId === 3 ? 1 : banner.visibleId + 1;
|
||||
const next = banner.visibleId;
|
||||
|
|
@ -122,17 +121,21 @@ function runBanner() {
|
|||
newItem.classList.add("transition-all");
|
||||
newItem.classList.add("left-0");
|
||||
newItem.classList.remove("left-full");
|
||||
|
||||
runBanner();
|
||||
}, nextDelay);
|
||||
|
||||
}
|
||||
// Observe banner and set is visible or not to
|
||||
// Update float button and menu position
|
||||
let options = {
|
||||
function observeBanner() {
|
||||
const options = {
|
||||
root: null,
|
||||
rootMargin: "0px",
|
||||
threshold: 0.35,
|
||||
};
|
||||
|
||||
let observer = new IntersectionObserver((entries, observer) => {
|
||||
const observer = new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) bannerStore.setBannerVisible(true);
|
||||
if (!entry.isIntersecting) bannerStore.setBannerVisible(false);
|
||||
|
|
@ -142,13 +145,52 @@ function runBanner() {
|
|||
observer.observe(document.getElementById("banner"));
|
||||
}
|
||||
|
||||
function noTabindex() {
|
||||
const bannerItems = document.querySelectorAll(".banner-item");
|
||||
bannerItems.forEach((item) => {
|
||||
item.classList.remove("banner-tabindex-highlight", 'banner-tabindex-hide');
|
||||
});
|
||||
}
|
||||
|
||||
function isTabindex() {
|
||||
const activeElement = document.activeElement;
|
||||
const bannerItems = document.querySelectorAll(".banner-item");
|
||||
bannerItems.forEach((item) => {
|
||||
item.classList.add("banner-tabindex-hide");
|
||||
item.classList.remove("banner-tabindex-highlight");
|
||||
});
|
||||
// Higher z-index for the focused element
|
||||
activeElement.closest('.banner-item').classList.add("banner-tabindex-highlight");
|
||||
activeElement.closest('.banner-item').classList.remove("banner-tabindex-hide");
|
||||
}
|
||||
|
||||
|
||||
// Focus with tabindex break banner animation
|
||||
// When a banner is focused, we need to add in front of the current banner the focus element
|
||||
// And remove it when the focus is lost
|
||||
function handleTabIndex() {
|
||||
// Get the active element after tabindex click
|
||||
document.addEventListener("keyup", (e) => {
|
||||
if(e.key !== "Tab" && !document.activeElement.classList.contains("banner-item-text")) return;
|
||||
if(document.activeElement.classList.contains("banner-item-text")) {
|
||||
isTabindex();
|
||||
return;
|
||||
} else {
|
||||
noTabindex();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
observeBanner();
|
||||
setupBanner();
|
||||
handleTabIndex();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="banner" tabindex="-1" role="list" class="banner-container">
|
||||
<div id="banner" role="list" class="banner-container">
|
||||
<div role="img" aria-hidden="true" class="banner-bg"></div>
|
||||
<div
|
||||
v-for="(bannerEl, index) in banner.default"
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ function updateLangStorage(lang) {
|
|||
:aria-checked="$i18n.locale === locale ? 'true' : 'false'"
|
||||
>
|
||||
<button
|
||||
:tabindex="lang.isOpen ? langIndex : -1"
|
||||
:tabindex="lang.isOpen ? langIndex : '-1'"
|
||||
@click="
|
||||
() => {
|
||||
lang.isOpen = false;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import News from "@components/dashboard/News.vue";
|
|||
import Header from "@components/dashboard/Header.vue";
|
||||
import Banner from "@components/dashboard/Banner.vue";
|
||||
import Feedback from "@components/dashboard/Feedback.vue";
|
||||
import { onMounted } from "vue";
|
||||
|
||||
/**
|
||||
@name Dashboard/Layout.vue
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ onBeforeMount(() => {
|
|||
<h1 class="menu-account-title">
|
||||
{{ menu.username }}
|
||||
</h1>
|
||||
<a class="menu-account-link" href="/account">manage account </a>
|
||||
<a :tabindex=" menu.isDesktop ? menuIndex : menu.isActive ? menuIndex : '-1'" class="menu-account-link" href="/account">manage account </a>
|
||||
</div>
|
||||
<hr class="menu-separator" />
|
||||
<!-- end logo version -->
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ onMounted(() => {
|
|||
<p v-if="news.posts.length === 0" class="news-sidebar-no-posts-content">
|
||||
{{ $t("dashboard_news_fetch_error") }}
|
||||
</p>
|
||||
<a :href="`https://www.bunkerweb.io/blog/post/bunkerweb/${post.slug}`" class="news-sidebar-post"
|
||||
<a :tabindex="news.isActive ? newsIndex : '-1'" :href="`https://www.bunkerweb.io/blog/post/bunkerweb/${post.slug}?utm_campaign=self&utm_source=ui`" class="news-sidebar-post"
|
||||
v-for="(post, index) in news.posts" :key="index"
|
||||
>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@
|
|||
"dashboard_menu_discord_label": "Redirect to BunkerWeb Discord",
|
||||
"dashboard_menu_github_label": "Redirect to BunkerWeb Github",
|
||||
"dashboard_menu_plugins_title": "plugin pages",
|
||||
"dashboard_menu_plugins_none": "Want custom plugins ?",
|
||||
"dashboard_menu_plugins_none_doc": "check doc",
|
||||
"dashboard_menu_mode_light": "light mode",
|
||||
"dashboard_menu_mode_dark": "dark mode",
|
||||
"dashboard_menu_log_out": "log out",
|
||||
|
|
|
|||
109
vuejs/client/src/lang/fr.json
Normal file
109
vuejs/client/src/lang/fr.json
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
{
|
||||
"dashboard_logo_alt": "Image du logo BunkerWeb",
|
||||
"dashboard_logo_link_label": "Rediriger vers la page d'accueil",
|
||||
"dashboard_bw": "BunkerWeb",
|
||||
"dashboard_docs": "documents",
|
||||
"dashboard_blog": "blog",
|
||||
"dashboard_privacy": "confidentialité",
|
||||
"dashboard_license": "licence",
|
||||
"dashboard_sitemap": "plan du site",
|
||||
"dashboard_default": "défautt",
|
||||
"dashboard_info": "info",
|
||||
"dashboard_filter": "filtres",
|
||||
"dashboard_advanced": "avancé",
|
||||
"dashboard_loading": "chargement",
|
||||
"dashboard_lang_dropdown_button_desc": "Basculer entre cacher/afficher le groupe de boutons radio (menu déroulant) pour changer la langue.",
|
||||
"dashboard_home": "accueil",
|
||||
"dashboard_instances": "instances",
|
||||
"dashboard_global_config": "config globale",
|
||||
"dashboard_services": "services",
|
||||
"dashboard_configs": "configs",
|
||||
"dashboard_plugins": "plugins",
|
||||
"dashboard_jobs": "jobs",
|
||||
"dashboard_bans": "bans",
|
||||
"dashboard_actions": "actions",
|
||||
"dashboard_account": "compte",
|
||||
"dashboard_reports": "rapports",
|
||||
"dashboard_cache": "cache",
|
||||
"dashboard_logs": "journaux",
|
||||
"dashboard_feedback_toggle_sidebar": "Basculer la barre latérale de feedback.",
|
||||
"dashboard_feedback_close_sidebar": "Fermer la barre latérale de feedback.",
|
||||
"dashboard_feedback_title": "Feedback",
|
||||
"dashboard_feedback_subtitle": "Actions BunkerWeb",
|
||||
"dashboard_menu_toggle_sidebar": "Basculer la barre latérale du menu.",
|
||||
"dashboard_menu_close_sidebar": "Fermer la barre latérale du menu.",
|
||||
"dashboard_menu_twitter_label": "Rediriger vers le Twitter de BunkerWeb",
|
||||
"dashboard_menu_linkedin_label": "Rediriger vers le Linkedin de BunkerWeb",
|
||||
"dashboard_menu_discord_label": "Rediriger vers le Discord de BunkerWeb",
|
||||
"dashboard_menu_github_label": "Rediriger vers le Github de BunkerWeb",
|
||||
"dashboard_menu_plugins_title": "Pages des plugins",
|
||||
"dashboard_menu_plugins_none": "Vous voulez des plugins personnalisés ?",
|
||||
"dashboard_menu_plugins_none_doc": "consulter la documentation",
|
||||
"dashboard_menu_mode_light": "mode clair",
|
||||
"dashboard_menu_mode_dark": "mode sombre",
|
||||
"dashboard_menu_log_out": "se déconnecter",
|
||||
"dashboard_ui": "ui",
|
||||
"dashboard_scheduler": "scheduler",
|
||||
"dashboard_autoconf": "autoconf",
|
||||
"dashboard_core": "core",
|
||||
"dashboard_global": "global",
|
||||
"dashboard_news_toggle_sidebar": "Basculer la barre latérale des nouvelles.",
|
||||
"dashboard_news_close_sidebar": "Fermer la barre latérale des nouvelles.",
|
||||
"dashboard_news_title": "news",
|
||||
"dashboard_news_subtitle": "Stay up to date !",
|
||||
"dashboard_news_fetch_error": "Impossible to retrieve news",
|
||||
"dashboard_newsletter_title": "Join newsletter",
|
||||
"dashboard_newsletter_placeholder": "john.doe{'@'}example.com",
|
||||
"dashboard_newsletter_privacy_text": "I'v read and agree",
|
||||
"dashboard_newsletter_privacy_text_link": "the privacy policy",
|
||||
"dashboard_newsletter_subscribe_button": "subscribe",
|
||||
"dashboard_feedback_alert_desc": "Own actions feedbacks.",
|
||||
"dashboard_feedback_logs_desc": "BunkerWeb actions feedbacks.",
|
||||
"dashboard_popover_button_desc": "Show setting details on hover.",
|
||||
"dashboard_popover_button": "Show popover with setting details.",
|
||||
"dashboard_popover_detail_desc": "Container with setting details.",
|
||||
"dashboard_up": "up",
|
||||
"dashboard_down": "down",
|
||||
"dashboard_banner_title_1": "Need premium support ?",
|
||||
"dashboard_banner_title_2": "Try BunkerWeb on our",
|
||||
"dashboard_banner_title_3": "All informations about BunkerWeb on our",
|
||||
"dashboard_banner_link_1": "https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui",
|
||||
"dashboard_banner_link_2": "https://demo.bunkerweb.io/link/?utm_campaign=self&utm_source=ui",
|
||||
"dashboard_banner_link_3": "https://www.bunkerweb.io/?utm_campaign=self&utm_source=ui",
|
||||
"dashboard_banner_link_text_1": "Check BunkerWeb Panel",
|
||||
"dashboard_banner_link_text_2": "demo wep app !",
|
||||
"dashboard_banner_link_text_3": "website !",
|
||||
"home_version_is_latest": "is the latest version",
|
||||
"home_version_latest_version": "latest version",
|
||||
"home_version": "version",
|
||||
"home_internal": "internal",
|
||||
"home_external": "external",
|
||||
"home_card_link_label": "Redirect to page with related data.",
|
||||
"instances_hostname": "hostname",
|
||||
"instances_hostname_placeholder": "bwapi",
|
||||
"instances_method": "method",
|
||||
"instances_port": "port",
|
||||
"instances_port_placeholder": "5000",
|
||||
"instances_active": "Instance is active.",
|
||||
"instances_inactive": "Instance is inactive.",
|
||||
"instances_modal_delete_msg": "Are you sure to delete instance with hostname {hostname} ?",
|
||||
"instances_server_name": "server name",
|
||||
"instances_server_name_placeholder": "www.example.com",
|
||||
"action_send": "send {name}",
|
||||
"action_disable": "disable {name}",
|
||||
"action_enable": "enable {name}",
|
||||
"action_save": "save {name}",
|
||||
"action_add": "add {name}",
|
||||
"action_close": "close {name}",
|
||||
"action_delete": "delete {name}",
|
||||
"action_link": "link",
|
||||
"action_edit": "edit {name}",
|
||||
"action_download": "download {name}",
|
||||
"action_create": "create {name}",
|
||||
"action_view": "view {name}",
|
||||
"action_stop": "stop {name}",
|
||||
"action_ping": "ping {name}",
|
||||
"action_reload": "reload {name}",
|
||||
"action_upload": "upload {name}",
|
||||
"action_delete_all": "delete all {name}"
|
||||
}
|
||||
|
|
@ -9,11 +9,12 @@ import { createI18n } from "vue-i18n";
|
|||
*/
|
||||
|
||||
import en from "@lang/en.json" assert { type: "json" };
|
||||
import fr from "@lang/fr.json" assert { type: "json" };
|
||||
|
||||
const availablesLangs = ["en"];
|
||||
const availablesLangs = ["en", "fr"];
|
||||
|
||||
function getAllLang() {
|
||||
return { en: en };
|
||||
return { en: en, fr : fr };
|
||||
}
|
||||
|
||||
function getAllLangCurrPage(pagesArr) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
This is useful for people with disabilities or people who prefer to use the keyboard instead of the mouse.
|
||||
*/
|
||||
const bannerIndex = "-1";
|
||||
const footerIndex = "0";
|
||||
const menuIndex = "1";
|
||||
const langIndex = "2";
|
||||
const menuFloatIndex = "3";
|
||||
|
|
@ -14,6 +13,7 @@ const refreshIndex = "4";
|
|||
const feedbackIndex = "5";
|
||||
const newsIndex = "6";
|
||||
const contentIndex = "7";
|
||||
const footerIndex = "8";
|
||||
|
||||
export {
|
||||
bannerIndex,
|
||||
|
|
|
|||
Loading…
Reference in a new issue