Skip to content

Commit 9d114b9

Browse files
authored
Merge pull request #1 from faustinopsy/SPA-10-evolucao-OO-notificaNews
Spa 10 evolucao oo notifica news
2 parents 7bd2e80 + 2051099 commit 9d114b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2709
-128
lines changed

.htaccess

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Cache de imagens por 1 mês
2+
<FilesMatch "\.(jpg|jpeg|png|gif|ico)$">
3+
Header set Cache-Control "max-age=2592000, assets"
4+
</FilesMatch>
5+
6+
# Cache de CSS e JS por 1 semana
7+
<FilesMatch "\.(css|js)$">
8+
Header set Cache-Control "max-age=604800, assets"
9+
</FilesMatch>
10+
<IfModule mod_deflate.c>
11+
# Ativar a compactação
12+
SetOutputFilter DEFLATE
13+
14+
# Não compactar recursos MIME específicos
15+
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
16+
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
17+
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
18+
19+
# Permitir a compactação somente para navegadores específicos
20+
BrowserMatch ^Mozilla/4 gzip-only-text/html
21+
BrowserMatch ^Mozilla/4\.0[678] no-gzip
22+
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
23+
</IfModule>
24+
#caso queiram URL amigáveis em projetos próprios
25+
#abaixo consegue trocar ult ou retirar extensão
26+
#só serve para hospedagem que roda apache/php
27+
# <IfModule mod_rewrite.c>
28+
# RewriteEngine On
29+
# RewriteCond %{REQUEST_FILENAME} !-f
30+
# RewriteCond %{REQUEST_FILENAME} !-d
31+
# RewriteRule ^(.*)$ /#$1 [L,NE,R=302]
32+
# </IfModule>
33+
34+
# Ativar regras de reescrita
35+
RewriteEngine On
36+
37+
# Forçar HTTPS
38+
RewriteCond %{HTTPS} off
39+
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
40+
41+
# Segurança Transport Layer Security (HSTS)
42+
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
43+
# Prevenir MIME-sniffing
44+
Header always set X-Content-Type-Options "nosniff"
45+
# Política de Segurança de Conteúdo (CSP)
46+
Header always set Content-Security-Policy "default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self'; connect-src 'self'; worker-src 'self'; manifest-src 'self'; child-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests;"
47+
# Bloquear frames/iframe
48+
Header always set X-Frame-Options "DENY"
49+
# Proteção contra Cross-Site Scripting (XSS)
50+
Header always set X-XSS-Protection "1; mode=block"
51+
# Assegurar que o Content-Type seja seguido
52+
Header always set X-Content-Type-Options "nosniff"
53+

assets/css/w3.css

Lines changed: 842 additions & 0 deletions
Large diffs are not rendered by default.

assets/i18n/en.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"font_size": "Font Size:",
3+
"small": "Small",
4+
"medium": "Medium",
5+
"large": "Large",
6+
"xlarge": "E.Large",
7+
"xxlarge": "X.Large",
8+
"dark_mode": "Dark Mode:",
9+
"language": "Language:",
10+
"english": "English",
11+
"portuguese": "Portuguese",
12+
"spanish": "Spanish",
13+
"page_contact": "Contact Page",
14+
"contact_form": "Contact Form",
15+
"name": "Name",
16+
"subject": "Subject",
17+
"message": "Message",
18+
"send_button": "Send",
19+
"mini_spa": "SPA en",
20+
"home": "Home",
21+
"about": "About",
22+
"contact": "Contact",
23+
"extra": "Extra",
24+
"settings": "Settings",
25+
"page_extra": "Extra Page",
26+
"page_home": "Home Page",
27+
"page_about": "About Page",
28+
"hello_layout": "Hello W3.CSS Layout.",
29+
"page_settings": "Settings Page",
30+
"settings_menu": "Settings Menu",
31+
"choose_background_image": "Choose a background image:",
32+
"apply_background_button": "Apply Background Image",
33+
"save_settings_button": "Save Settings",
34+
"reset-settings" : "Reset Settings",
35+
"details": "Details",
36+
"open": "Open",
37+
"install_app": "Install App",
38+
"install_prompt": "Want to install for a full experience?",
39+
"install": "Install",
40+
"cancel": "Cancel",
41+
"backdrop_filter": "Backdrop Filter",
42+
"background_color": "Background Color",
43+
"text_color": "text color",
44+
"font_type": "font type",
45+
"confirmation_prompt": "Are you sure you want to clear the settings?",
46+
"settings_reset": "The settings have been reset to defaults.",
47+
"action_cancelled":"Action cancelled. The settings have not been changed."
48+
}

assets/i18n/es.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"font_size": "Tamaño de Fuente:",
3+
"small": "Pequeño",
4+
"medium": "Mediano",
5+
"large": "Grande",
6+
"xlarge": "E.Grande",
7+
"xxlarge": "X.Grande",
8+
"dark_mode": "Modo Oscuro:",
9+
"language": "Idioma:",
10+
"english": "Inglés",
11+
"portuguese": "Portugués",
12+
"spanish": "Español",
13+
"page_contact": "Página de contacto",
14+
"contact_form": "Formulario de contacto",
15+
"name": "Nombre",
16+
"subject": "Asunto",
17+
"message": "Mensaje",
18+
"send_button": "Enviar",
19+
"mini_spa": "SPA es",
20+
"home": "Inicio",
21+
"about": "Acerca de",
22+
"contact": "Contacto",
23+
"extra": "Extra",
24+
"settings": "Configuración",
25+
"page_extra": "Página Extra",
26+
"page_home": "Página de Inicio",
27+
"page_about": "Página sobre",
28+
"hello_layout": "Hola Diseño W3.CSS.",
29+
"page_settings": "Página de Configuraciones",
30+
"settings_menu": "Menú de Configuraciones",
31+
"choose_background_image": "Elija una imagen de fondo:",
32+
"apply_background_button": "Aplicar Imagen de Fondo",
33+
"save_settings_button": "Guardar Configuraciones",
34+
"reset-settings" : "Limpar Configuraciones",
35+
"details": "Detalles",
36+
"open": "Abrir",
37+
"install_app": "Instalar Aplicación",
38+
"install_prompt": "¿Quieres instalar para una experiencia completa?",
39+
"install": "Instalar",
40+
"cancel": "Cancelar",
41+
"backdrop_filter": "Filtro de Telón",
42+
"background_color": "Color de Fondo",
43+
"text_color": "Color del texto",
44+
"font_type": "Tipo de fuente",
45+
"confirmation_prompt": "¿Está seguro de que desea limpiar las configuraciones?",
46+
"settings_reset": "Las configuraciones han sido restablecidas a los valores predeterminados.",
47+
"action_cancelled":"Acción cancelada. Las configuraciones no han sido cambiadas."
48+
}

assets/i18n/pt.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"font_size": "Tamanho da Fonte:",
3+
"small": "Pequeno",
4+
"medium": "Médio",
5+
"large": "Grande",
6+
"xlarge": "E.Grande",
7+
"xxlarge": "X.Grande",
8+
"dark_mode": "Modo Escuro:",
9+
"language": "Idioma:",
10+
"english": "Inglês",
11+
"portuguese": "Português",
12+
"spanish": "Espanhol",
13+
"page_contact": "Página de contato",
14+
"contact_form": "Formulário de contato",
15+
"name": "Nome",
16+
"subject": "Assunto",
17+
"message": "Mensagem",
18+
"send_button": "Enviar",
19+
"mini_spa": "SPA br",
20+
"home": "Início",
21+
"about": "Sobre",
22+
"contact": "Contato",
23+
"extra": "Extra",
24+
"settings": "Configuração",
25+
"page_extra": "Página Extra",
26+
"page_home": "Página Inicial",
27+
"page_about": "Página sobre",
28+
"hello_layout": "Olá Layout W3.CSS.",
29+
"page_settings": "Página de Configurações",
30+
"settings_menu": "Menu de Configurações",
31+
"choose_background_image": "Escolha uma imagem de fundo:",
32+
"apply_background_button": "Aplicar Imagem de Fundo",
33+
"save_settings_button": "Salvar Configurações",
34+
"reset-settings" : "Limpar Configurações",
35+
"details": "Detalhes",
36+
"open": "Abrir",
37+
"install_app": "Instalar Aplicativo",
38+
"install_prompt": "Quer instalar para uma experiência completa?",
39+
"install": "Instalar",
40+
"cancel": "Cancelar",
41+
"backdrop_filter": "Filtro de Fundo",
42+
"background_color": "Cor de Fundo",
43+
"text_color": "Cor do texto",
44+
"font_type": "Tipo de letra",
45+
"confirmation_prompt": "Você tem certeza que deseja limpar as configurações?",
46+
"settings_reset": "As configurações foram redefinidas para os padrões.",
47+
"action_cancelled":"Ação cancelada. As configurações não foram alteradas."
48+
}

assets/img/config.webp

7.63 KB
Binary file not shown.

assets/img/f.webp

9.2 KB
Binary file not shown.

assets/img/imagem1-large.webp

32 KB
Binary file not shown.

assets/img/imagem1-medium.webp

9.08 KB
Binary file not shown.

assets/img/imagem1-small.webp

4.1 KB
Binary file not shown.

assets/img/imagem1.webp

8.13 KB
Binary file not shown.

assets/img/imagem2-large.webp

9.56 KB
Binary file not shown.

assets/img/imagem2-medium.webp

9.56 KB
Binary file not shown.

assets/img/imagem2-small.webp

4.49 KB
Binary file not shown.

assets/img/imagem2.webp

8.08 KB
Binary file not shown.

assets/img/imagem3-large.webp

21.2 KB
Binary file not shown.

assets/img/imagem3-medium.webp

21.2 KB
Binary file not shown.

assets/img/imagem3-small.webp

21.2 KB
Binary file not shown.

assets/img/imagem3.webp

21.2 KB
Binary file not shown.

assets/img/img0.webp

31.5 KB
Binary file not shown.

assets/img/img1.webp

40.2 KB
Binary file not shown.

assets/img/img2.webp

14.2 KB
Binary file not shown.

assets/img/img3.webp

40.1 KB
Binary file not shown.

assets/img/js1.webp

39.8 KB
Binary file not shown.

assets/img/js2.webp

46.9 KB
Binary file not shown.

assets/img/js3.webp

46.2 KB
Binary file not shown.

assets/img/logo192.png

26.1 KB
Loading

assets/img/logo2880.png

539 KB
Loading

assets/img/logo512.png

36.3 KB
Loading

assets/img/notifica.webp

6.18 KB
Binary file not shown.

assets/img/ss.webp

8.06 KB
Binary file not shown.

assets/js/App.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import rotas from './router.js';
2+
import Navbar from '../js/componentes/navbar.js';
3+
import Configuracoes from '../js/paginas/Configuracoes.js';
4+
import I18nService from '../js/libs/I18nService.js';
5+
import FloatingButton from '../js/componentes/floatingButton.js';
6+
class App {
7+
constructor() {
8+
this.nav = document.getElementById("nav");
9+
this.conteudo = document.getElementById("app");
10+
this.componenteAtual = null;
11+
this.linguagem = new I18nService();
12+
this.init();
13+
}
14+
15+
async init() {
16+
await this.linguagem.loadTranslations();
17+
this.configuracoes = new Configuracoes();
18+
this.configuracoes.applySettings();
19+
const floatingButton = new FloatingButton(this.linguagem, this.navegar.bind(this));
20+
floatingButton.render();
21+
const navbar = new Navbar();
22+
this.nav.innerHTML = navbar.render(this.linguagem);
23+
navbar.fixNavbarOnMobile();
24+
navbar.afterRender();
25+
window.addEventListener('resize', () => navbar.fixNavbarOnMobile());
26+
window.addEventListener("hashchange", () => this.navegar(location.hash));
27+
this.navegar(location.hash);
28+
}
29+
30+
atualizarMeta(meta) {
31+
document.title = meta.title;
32+
document.querySelector('meta[name="description"]').content = meta.description;
33+
}
34+
35+
async navegar(rota) {
36+
const rotaAtual = rota || '#home';
37+
const classeAtual = rotas[rotaAtual].component;
38+
39+
if (this.componenteAtual && this.componenteAtual.destroy) {
40+
this.componenteAtual.destroy();
41+
}
42+
43+
this.conteudo.innerHTML = '';
44+
this.conteudo.innerHTML = classeAtual.render(this.linguagem);
45+
this.componenteAtual = classeAtual;
46+
if (this.componenteAtual.afterRender) {
47+
await this.componenteAtual.afterRender();
48+
}
49+
this.atualizarMeta(rotas[rotaAtual].meta);
50+
document.documentElement.scrollTop = 0;
51+
}
52+
53+
}
54+
55+
const navegador = new App();
56+

assets/js/Atualizacoes.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
class Atualizacoes {
2+
constructor() {
3+
this.listenForHashChange();
4+
this.listenForSWMessages();
5+
this.createNotificationBox();
6+
}
7+
8+
listenForHashChange() {
9+
window.addEventListener('hashchange', () => {
10+
if (location.hash === '#home' || location.hash === '#') {
11+
navigator.serviceWorker.controller.postMessage({
12+
action: 'checkForUpdates'
13+
});
14+
}
15+
}, false);
16+
}
17+
18+
listenForSWMessages() {
19+
navigator.serviceWorker.addEventListener('message', event => {
20+
if (event.data.type === 'UPDATE_AVAILABLE') {
21+
this.handleUpdateAvailable(event.data.ultimaModificacao);
22+
}
23+
});
24+
}
25+
26+
handleUpdateAvailable(ultimaModificacao) {
27+
const ultimaDataSalva = localStorage.getItem('ultimaModificacao');
28+
if (!ultimaDataSalva || new Date(ultimaModificacao) > new Date(ultimaDataSalva)) {
29+
console.log('Nova atualização disponível!');
30+
localStorage.setItem('ultimaModificacao', ultimaModificacao);
31+
this.showNotification();
32+
}
33+
}
34+
35+
createNotificationBox() {
36+
if (!document.getElementById('notificationBox')) {
37+
const notificationBox = document.createElement('div');
38+
notificationBox.id = 'notificationBox';
39+
notificationBox.className = 'notification-box hidden';
40+
notificationBox.innerHTML = `
41+
<p> ☄️🚀☄️ news!</p>
42+
<img src="./assets/img/notifica.webp" alt="Notifica" style="width:100px">
43+
`;
44+
45+
document.body.appendChild(notificationBox);
46+
}
47+
}
48+
49+
showNotification() {
50+
const notificationBox = document.getElementById('notificationBox');
51+
if (!notificationBox) this.createNotificationBox();
52+
notificationBox.classList.remove('hidden');
53+
notificationBox.classList.add('show');
54+
55+
setTimeout(() => {
56+
notificationBox.classList.remove('show');
57+
setTimeout(() => {
58+
notificationBox.classList.add('hidden');
59+
}, 500);
60+
}, 10000);
61+
}
62+
}
63+
64+
if (document.readyState === 'loading') {
65+
document.addEventListener('DOMContentLoaded', () => new Atualizacoes());
66+
} else {
67+
new Atualizacoes();
68+
}

0 commit comments

Comments
 (0)