diff --git a/assets-src/sass/components/_panel-sidebar.scss b/assets-src/sass/components/_panel-sidebar.scss new file mode 100644 index 0000000..93d792c --- /dev/null +++ b/assets-src/sass/components/_panel-sidebar.scss @@ -0,0 +1,190 @@ +.panel__sidebar { + + border-right: 1px solid var(--mc-gray-100); +} + +.panel-nav { + height: 100%; + padding: size(40) size(24); + display: flex; + + .user-menu__line { + max-width: 100%; + height: 0px; + left: 16px; + top: 809px; + border-top: 1px solid var(--mc-low-500); + padding: 0; + margin: size(16) size(16); + } + + &.user-menu { + .vertical__line { + border-right: size(1) solid var(--mc-gray-300); + width: 0; + margin-inline: size(22); + height: size(522); + } + + border: none; + padding: 0; + + ul:first-child { + li>a { + color: var(--mc-primary-500) + } + } + } + + &__line { + flex: 1; + max-width: 100%; + align-self: stretch; + border-left: 1px solid var(--mc-gray-300); + margin: 0 size(16); + height: auto; + } + + @include mobile { + &__line { + max-width: 100%; + border-left: none; + border-top: 1px solid var(--mc-gray-300); + width: 100%; + margin: size(16) 0; + } + } + + &__right { + + &--user li{ + svg { + color: var(--mc-primary-500); + } + &:focus, + &:hover, + a.active { + svg { + color: var(--mc-high-500); + } + } + } + } + + @include mobile { + border: none; + display: none; + + padding: size(24) size(16); + } + + &__toggle { + background-color: var(--mc-gray-300); + color: var(--panel-font-title); + font-family: var(--mc-font-body); + font-size: size(18); + font-weight: bold; + width: 100%; + + .iconify { + height: size(24); + margin-right: size(32); + width: size(24); + } + } + + h2 { + margin: 0; + + @include desktop { + @include sr-only; + } + } + + h3 { + color: $panel-font-title; + font-family: 'Open Sans', var(--mc-font-body, sans-serif); + font-weight: 700; + font-size: size(14); + line-height: 100%; + letter-spacing: 0.07em; + text-transform: uppercase; + vertical-align: middle; + margin: 0; + padding: size(16) size(16) size(8); + } + + ul li a { + margin-left: size(13); + } + + > li > a { + margin-left: size(13); + } + + nav { + + @include mobile { + display: none; + + &.--open { + display: block; + } + } + } + + ul { + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + gap: size(8); + } + + li { + list-style: none; + } + + a { + align-items: center; + border-radius: var(--mc-border-radius-sm); + color: inherit; + display: flex; + transition: all 0.2s ease-in-out; + padding: size(8) size(16); + font-size: 14px; + font-weight: 600; + font-family: 'Open Sans'; + text-decoration: none; + + &:focus, + &:hover { + background-color: var(--mc-primary-500); + color: var(--mc-high-500); + + } + + &.active { + background-color: var(--mc-primary-700); + color: var(--mc-high-500); + + &:focus { + background-color: var(--mc-primary-500); + color: var(--mc-high-500); + } + + &:hover { + background-color: var(--mc-primary-700); + color: var(--mc-high-500); + } + + + } + + .iconify { + height: size(24); + margin-right: size(32); + width: size(24); + } + } +} \ No newline at end of file diff --git a/assets-src/sass/theme-BaseV2.scss b/assets-src/sass/theme-BaseV2.scss index 5d40ece..a858e40 100644 --- a/assets-src/sass/theme-BaseV2.scss +++ b/assets-src/sass/theme-BaseV2.scss @@ -46,6 +46,7 @@ $home-opportunities: #f5bb50; $home-feature: #45B648; $home-register: #036293; +$panel-font-title: #3E3E3E; // // Neutral colors @@ -85,6 +86,7 @@ $border-radius-xxs: 2px; @import './components/home-map'; @import './components/home-prosas-notices'; @import './components/home-description'; +@import './components/panel-sidebar'; @import './components/glpi-form'; @import './layouts/home-register'; @import './layouts/main-footer'; diff --git a/components/mc-header-menu/README.md b/components/mc-header-menu/README.md new file mode 100644 index 0000000..436ce8b --- /dev/null +++ b/components/mc-header-menu/README.md @@ -0,0 +1,28 @@ +# Componente `` +O componente `mc-header-menu` é utilizado para renderizar o menu do cabeçalho de um site. Ele lida com a alternância do menu em dispositivos móveis e permite a inclusão de slots para o logotipo e itens do menu. + +## Slots +- **default**: Slot padrão para a inserção dos itens do menu. +- **logo**: Slot para a inserção do logotipo. + +### Importando componente +```PHP +import('mc-header-menu'); +?> +``` + +### Exemplos de uso +```HTML + + + + + +``` \ No newline at end of file diff --git a/components/mc-header-menu/script.js b/components/mc-header-menu/script.js new file mode 100644 index 0000000..4cc2c6a --- /dev/null +++ b/components/mc-header-menu/script.js @@ -0,0 +1,27 @@ +app.component('mc-header-menu', { + template: $TEMPLATES['mc-header-menu'], + + setup() { + // os textos estão localizados no arquivo texts.php deste componente + const text = Utils.getTexts('mc-header-menu') + return { text } + }, + + props: { + }, + + data() { + return { + openMobile: false, + } + }, + + computed: { + }, + + methods: { + toggleMobile() { + this.openMobile = !this.openMobile; + } + }, +}); diff --git a/components/mc-header-menu/template.php b/components/mc-header-menu/template.php new file mode 100644 index 0000000..f2713b4 --- /dev/null +++ b/components/mc-header-menu/template.php @@ -0,0 +1,54 @@ +import(' + mc-icon +'); +?> + +applyTemplateHook('mc-header-logo','before'); ?> + +applyTemplateHook('mc-header-logo','after'); ?> + + +applyTemplateHook('mc-entity-menu','before'); ?> + +applyTemplateHook('mc-entity-menu','after'); ?> + + +
+
+ + + + +
+ applyTemplateHook('mc-entity-menu-mobile','before'); ?> + + applyTemplateHook('mc-entity-menu-mobile','after'); ?> +
\ No newline at end of file diff --git a/components/mc-header-menu/texts.php b/components/mc-header-menu/texts.php new file mode 100644 index 0000000..2e01a92 --- /dev/null +++ b/components/mc-header-menu/texts.php @@ -0,0 +1,5 @@ +` + +Menu de navegação do painel diff --git a/components/panel--nav/init.php b/components/panel--nav/init.php new file mode 100644 index 0000000..6e9ef1d --- /dev/null +++ b/components/panel--nav/init.php @@ -0,0 +1,121 @@ + [ + 'label' => i::__('Menu do Painel de Controle'), + 'column' => 'left', + 'items' => [ + ['route' => 'panel/index', 'icon' => 'dashboard', 'label' => i::__('Painel de Controle')] + ] + ], + + 'opportunities' => [ + 'label' => i::__('Editais e oportunidades'), + 'column' => 'left', + 'items' => [], + 'condition' => function () use ($app) { + return $app->isEnabled('opportunities'); + }, + ], + + 'main' => [ + 'label' => 'Gerenciamento de entidades', + 'column' => 'left', + 'items' => [ + [ + 'route' => 'panel/agents', 'icon' => 'agent', 'label' => i::__('Meus Agentes'), + 'condition' => function () use ($app) { + return $app->isEnabled('agents'); + }, + ], + [ + 'route' => 'panel/spaces', 'icon' => 'space', 'label' => i::__('Meus Espaços'), + 'condition' => function () use ($app) { + return $app->isEnabled('spaces'); + }, + ], + [ + 'route' => 'panel/events', 'icon' => 'event', 'label' => i::__('Meus Eventos'), + 'condition' => function () use ($app) { + return $app->isEnabled('events'); + }, + ], + [ + 'route' => 'panel/projects', 'icon' => 'project', 'label' => i::__('Meus Projetos'), + 'condition' => function () use ($app) { + return $app->isEnabled('projects'); + }, + ], + ], + 'condition' => function () use ($app) { + return $app->isEnabled('agents') || $app->isEnabled('spaces') || $app->isEnabled('events') || $app->isEnabled('projects'); + }, + ], + + 'more' => [ + 'label' => i::__('Outras opções'), + 'column' => 'right', + 'items' => [ + ['route' => 'panel/my-account', 'icon' => 'account', 'label' => i::__('Conta e Privacidade')], + ] + ], + + 'admin' => [ + 'label' => i::__('Administração'), + 'column' => 'right', + 'condition' => function () use ($app) { + return $app->user->is('admin'); + }, + 'items' => [] + ], +]; + +if ($app->user->profile) { + $nav_items['user'] = [ + 'label' => i::__('Usuário Logado'), + 'column' => 'user', + 'items' => [ + ['route' => 'agent/single', 'params' => [$app->user->profile->id], 'icon' => 'agent', 'label' => i::__('Meu Perfil')], + ['route' => 'auth/logout', 'icon' => 'logout', 'label' => i::__('Sair')], + ] + ]; +} + +$app->applyHook('panel.nav', [&$nav_items]); + +$result = []; + +foreach ($nav_items as $id => $group) { + $condition = $group['condition'] ?? function () { + return true; + }; + if (is_callable($condition) && $condition()) { + unset($group['condition']); + + $items = []; + foreach ($group['items'] as $item) { + $condition = $item['condition'] ?? function () { + return true; + }; + if (is_callable($condition) && $condition()) { + unset($item['condition']); + $items[] = $item; + } + } + + $result[] = [ + 'id' => $id, + 'label' => $group['label'], + 'column' => $group['column'] ?? 'left', + 'items' => $items + ]; + } +} + +$this->jsObject['config']['panelNav'] = $result; + +if ($this->activeNav ?? false) { + $this->jsObject['activeNav'] = $this->activeNav; +} diff --git a/components/panel--nav/script.js b/components/panel--nav/script.js new file mode 100644 index 0000000..bb7d906 --- /dev/null +++ b/components/panel--nav/script.js @@ -0,0 +1,58 @@ +app.component('panel--nav', { + template: $TEMPLATES['panel--nav'], + + props: { + classes: { + type: [Array, String], + default: '' + }, + + sidebar: { + type: Boolean, + default: false + }, + + viewport: { + type: String, + default: 'desktop' + } + }, + + data() { + const global = useGlobalState(); + const sidebar = this.sidebar; + const leftGroups = $MAPAS.config.panelNav.filter((group)=>{ + if(group.column == 'user' && sidebar) { + return; + } + if(group.column == 'left' || sidebar) { + return group; + } + }); + const rightGroups = $MAPAS.config.panelNav.filter((group)=>{ + if(group.column == 'right' && !sidebar) { + return group; + } + }); + const userGroup = $MAPAS.config.panelNav.filter((group)=>{ + if(group.column == 'user') { + return group; + } + })[0]; + + return { + entity: global.auth.user?.profile, + grouspColumn : $MAPAS.config.panelNav, + leftGroups, + rightGroups, + userGroup, + } + }, + + methods: { + active(item) { + const route = $MAPAS.route.route; + return $MAPAS.activeNav == item.route || route == item.route; + } + } +}) diff --git a/components/panel--nav/template.php b/components/panel--nav/template.php new file mode 100644 index 0000000..733d90f --- /dev/null +++ b/components/panel--nav/template.php @@ -0,0 +1,74 @@ +import(' + mc-link +'); +?> + + + \ No newline at end of file diff --git a/components/spam-add-config/init.php b/components/spam-add-config/init.php new file mode 100644 index 0000000..0a9f610 --- /dev/null +++ b/components/spam-add-config/init.php @@ -0,0 +1,13 @@ +jsObject['config']['spamAddConfig'] = [ + "spamTerms" => $data, +]; \ No newline at end of file diff --git a/components/spam-add-config/script.js b/components/spam-add-config/script.js new file mode 100644 index 0000000..0c593c4 --- /dev/null +++ b/components/spam-add-config/script.js @@ -0,0 +1,81 @@ +app.component('spam-add-config', { + template: $TEMPLATES['spam-add-config'], + + setup() { + const messages = useMessages(); + const text = Utils.getTexts('spam-add-config') + return { text, messages } + }, + + computed: { + spamTerms() { + return $MAPAS.config.spamAddConfig.spamTerms; + }, + }, + + data() { + return { + notificationTags: $MAPAS.config.spamAddConfig.spamTerms.notification.sort() || [], + blockedTags: $MAPAS.config.spamAddConfig.spamTerms.blocked.sort() || [], + }; + }, + + methods: { + change(event, type) { + if (event.key === 'Enter' || event.key === 'Tab') { + this.addTerms(event, type); + event.preventDefault(); + } + }, + + check(value, type) { + let index = null; + let _type = null; + + if (type == "notificationTags") { + index = this.blockedTags.indexOf(value); + _type = "blockedTags"; + } else { + index = this.notificationTags.indexOf(value); + _type = "notificationTags"; + } + + if (index && index !== -1) { + this[_type].splice(index, 1); + } + }, + + addTerms(event, type) { + let value = event.target.value.trim(); + if (value) { + if (this[type].includes(value)) { + this.messages.error(`${this.text('O termo')} ${value} ${this.text('já esta cadastrado')}`); + return; + } + + this.check(value, type); + this[type].push(value); + this.saveTags(); + this.clear(event); + } + }, + + clear(event) { + event.target.value = ''; + }, + + async saveTags() { + const tagsData = { + notification: this.notificationTags, + blocked: this.blockedTags + }; + + const api = new API(); + let url = Utils.createUrl("spamdetector", "saveterms"); + api.POST(url, tagsData).then(res => res.json()).then(data => { + this.messages.success(this.text('Bloqueio e notificações foi salvo com sucesso')); + }) + }, + }, + +}); \ No newline at end of file diff --git a/components/spam-add-config/template.php b/components/spam-add-config/template.php new file mode 100644 index 0000000..7ab1a20 --- /dev/null +++ b/components/spam-add-config/template.php @@ -0,0 +1,51 @@ +import(' + mc-tag-list +'); + +?> +
+ + + + + + + +
\ No newline at end of file diff --git a/components/spam-add-config/texts.php b/components/spam-add-config/texts.php new file mode 100644 index 0000000..16ac94d --- /dev/null +++ b/components/spam-add-config/texts.php @@ -0,0 +1,8 @@ + i::__('Bloqueio e notificações foi salvo com sucesso'), + 'O termo' => i::__('O termo'), + 'já esta cadastrado' => i::__('já esta cadastrado'), +]; \ No newline at end of file