From fb181298261705da016c56a693db429801d7c7b2 Mon Sep 17 00:00:00 2001 From: Aldarien Date: Thu, 29 Jul 2021 22:05:48 -0400 Subject: [PATCH] UI incompleto --- ui/Dockerfile | 3 + ui/common/Controller/Bancos.php | 12 ++ ui/common/Controller/Categorias.php | 12 ++ ui/common/Controller/Cuentas.php | 15 ++ ui/common/Controller/Fuentes.php | 12 ++ ui/common/Controller/Home.php | 12 ++ ui/common/Controller/TiposFuentes.php | 12 ++ ui/composer.json | 34 +++++ ui/nginx.conf | 22 +++ ui/public/assets/images/abacus-icon.png | Bin 0 -> 30052 bytes ui/public/assets/images/fund-accounting.png | Bin 0 -> 4299 bytes ui/public/assets/scripts/categorias.list.js | 91 ++++++++++++ ui/public/assets/scripts/cuentas.list.js | 125 ++++++++++++++++ ui/public/assets/scripts/fuentes.show.js | 121 ++++++++++++++++ ui/public/assets/scripts/home.js | 136 ++++++++++++++++++ ui/public/index.php | 7 + ui/resources/routes/bancos.php | 4 + ui/resources/routes/categorias.php | 4 + ui/resources/routes/cuentas.php | 4 + ui/resources/routes/fuentes.php | 4 + ui/resources/routes/home.php | 4 + ui/resources/routes/tipos_fuentes.php | 4 + ui/resources/views/bancos/base.blade.php | 14 ++ ui/resources/views/categorias/base.blade.php | 14 ++ ui/resources/views/categorias/list.blade.php | 28 ++++ ui/resources/views/cuentas/base.blade.php | 14 ++ ui/resources/views/cuentas/list.blade.php | 32 +++++ ui/resources/views/fuentes/base.blade.php | 14 ++ ui/resources/views/fuentes/show.blade.php | 81 +++++++++++ ui/resources/views/home.blade.php | 34 +++++ ui/resources/views/layout/base.blade.php | 5 + ui/resources/views/layout/body.blade.php | 5 + .../views/layout/body/footer.blade.php | 4 + .../views/layout/body/header.blade.php | 3 + ui/resources/views/layout/body/menu.blade.php | 5 + .../layout/body/menu/categorias.blade.php | 3 + .../views/layout/body/menu/cuentas.blade.php | 3 + .../views/layout/body/scripts.blade.php | 11 ++ ui/resources/views/layout/head.blade.php | 5 + .../views/layout/head/styles.blade.php | 8 ++ .../views/tipos_fuentes/base.blade.php | 14 ++ ui/setup/app.php | 45 ++++++ ui/setup/composer.php | 6 + ui/setup/router.php | 9 ++ ui/setup/settings/01_env.php | 4 + ui/setup/settings/02_common.php | 27 ++++ ui/setup/settings/03_web.php | 22 +++ ui/setup/setups/03_web.php | 15 ++ 48 files changed, 1063 insertions(+) create mode 100644 ui/Dockerfile create mode 100644 ui/common/Controller/Bancos.php create mode 100644 ui/common/Controller/Categorias.php create mode 100644 ui/common/Controller/Cuentas.php create mode 100644 ui/common/Controller/Fuentes.php create mode 100644 ui/common/Controller/Home.php create mode 100644 ui/common/Controller/TiposFuentes.php create mode 100644 ui/composer.json create mode 100644 ui/nginx.conf create mode 100644 ui/public/assets/images/abacus-icon.png create mode 100644 ui/public/assets/images/fund-accounting.png create mode 100644 ui/public/assets/scripts/categorias.list.js create mode 100644 ui/public/assets/scripts/cuentas.list.js create mode 100644 ui/public/assets/scripts/fuentes.show.js create mode 100644 ui/public/assets/scripts/home.js create mode 100644 ui/public/index.php create mode 100644 ui/resources/routes/bancos.php create mode 100644 ui/resources/routes/categorias.php create mode 100644 ui/resources/routes/cuentas.php create mode 100644 ui/resources/routes/fuentes.php create mode 100644 ui/resources/routes/home.php create mode 100644 ui/resources/routes/tipos_fuentes.php create mode 100644 ui/resources/views/bancos/base.blade.php create mode 100644 ui/resources/views/categorias/base.blade.php create mode 100644 ui/resources/views/categorias/list.blade.php create mode 100644 ui/resources/views/cuentas/base.blade.php create mode 100644 ui/resources/views/cuentas/list.blade.php create mode 100644 ui/resources/views/fuentes/base.blade.php create mode 100644 ui/resources/views/fuentes/show.blade.php create mode 100644 ui/resources/views/home.blade.php create mode 100644 ui/resources/views/layout/base.blade.php create mode 100644 ui/resources/views/layout/body.blade.php create mode 100644 ui/resources/views/layout/body/footer.blade.php create mode 100644 ui/resources/views/layout/body/header.blade.php create mode 100644 ui/resources/views/layout/body/menu.blade.php create mode 100644 ui/resources/views/layout/body/menu/categorias.blade.php create mode 100644 ui/resources/views/layout/body/menu/cuentas.blade.php create mode 100644 ui/resources/views/layout/body/scripts.blade.php create mode 100644 ui/resources/views/layout/head.blade.php create mode 100644 ui/resources/views/layout/head/styles.blade.php create mode 100644 ui/resources/views/tipos_fuentes/base.blade.php create mode 100644 ui/setup/app.php create mode 100644 ui/setup/composer.php create mode 100644 ui/setup/router.php create mode 100644 ui/setup/settings/01_env.php create mode 100644 ui/setup/settings/02_common.php create mode 100644 ui/setup/settings/03_web.php create mode 100644 ui/setup/setups/03_web.php diff --git a/ui/Dockerfile b/ui/Dockerfile new file mode 100644 index 0000000..da7c7c5 --- /dev/null +++ b/ui/Dockerfile @@ -0,0 +1,3 @@ +FROM php:8-fpm + +WORKDIR /app diff --git a/ui/common/Controller/Bancos.php b/ui/common/Controller/Bancos.php new file mode 100644 index 0000000..d3c8e8d --- /dev/null +++ b/ui/common/Controller/Bancos.php @@ -0,0 +1,12 @@ +render($response, 'bancos.add'); + } +} diff --git a/ui/common/Controller/Categorias.php b/ui/common/Controller/Categorias.php new file mode 100644 index 0000000..3a6e7d8 --- /dev/null +++ b/ui/common/Controller/Categorias.php @@ -0,0 +1,12 @@ +render($response, 'categorias.list'); + } +} diff --git a/ui/common/Controller/Cuentas.php b/ui/common/Controller/Cuentas.php new file mode 100644 index 0000000..b7b24b8 --- /dev/null +++ b/ui/common/Controller/Cuentas.php @@ -0,0 +1,15 @@ +render($response, 'cuentas.list'); + } + public function add(Request $request, Response $response, View $view): Response { + return $view->render($response, 'cuentas.add'); + } +} diff --git a/ui/common/Controller/Fuentes.php b/ui/common/Controller/Fuentes.php new file mode 100644 index 0000000..8f7ebfe --- /dev/null +++ b/ui/common/Controller/Fuentes.php @@ -0,0 +1,12 @@ +render($response, 'fuentes.show', compact('fuente_id')); + } +} diff --git a/ui/common/Controller/Home.php b/ui/common/Controller/Home.php new file mode 100644 index 0000000..86ad804 --- /dev/null +++ b/ui/common/Controller/Home.php @@ -0,0 +1,12 @@ +render($response, 'home'); + } +} diff --git a/ui/common/Controller/TiposFuentes.php b/ui/common/Controller/TiposFuentes.php new file mode 100644 index 0000000..ed17d65 --- /dev/null +++ b/ui/common/Controller/TiposFuentes.php @@ -0,0 +1,12 @@ +render($response, 'tipos_fuentes.add'); + } +} diff --git a/ui/composer.json b/ui/composer.json new file mode 100644 index 0000000..9cfd883 --- /dev/null +++ b/ui/composer.json @@ -0,0 +1,34 @@ +{ + "name": "provm/contabilidad-ui", + "description": "UI para Contabilidad", + "type": "project", + "require": { + "php-di/php-di": "^6.3", + "php-di/slim-bridge": "^3.1", + "rubellum/slim-blade-view": "^0.1.1", + "nyholm/psr7-server": "^1.0", + "zeuxisoo/slim-whoops": "^0.7.3", + "nyholm/psr7": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "kint-php/kint": "^3.3" + }, + "authors": [ + { + "name": "Aldarien", + "email": "aldarien85@gmail.com" + } + ], + "autoload": { + "psr-4": { + "Contabilidad\\Common\\": "common" + } + }, + "repositories": [ + { + "type": "git", + "url": "http://git.provm.cl/ProVM/controller.git" + } + ] +} diff --git a/ui/nginx.conf b/ui/nginx.conf new file mode 100644 index 0000000..dc6baa6 --- /dev/null +++ b/ui/nginx.conf @@ -0,0 +1,22 @@ +server { + listen 80; + index index.php index.html index.htm; + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + root /app/public; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass ui:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + } +} diff --git a/ui/public/assets/images/abacus-icon.png b/ui/public/assets/images/abacus-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4294e87e974cbbe797efd3132f7dec136e05ad8c GIT binary patch literal 30052 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

$ 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 literal 0 HcmV?d00001 diff --git a/ui/public/assets/images/fund-accounting.png b/ui/public/assets/images/fund-accounting.png new file mode 100644 index 0000000000000000000000000000000000000000..4b32b744223128388c169dfffe628080c5860f26 GIT binary patch literal 4299 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 t1eBt3-i9ph39=q{^&Zrp`I( { + if (data.categorias === null || data.categorias.length == 0) { + return + } + this.categorias = data.categorias + }).then(() => { + this.draw() + }) + }, + getParent: function() { + let parent = $(this.id).find('tbody') + if (parent.length == 0) { + const table = $('
').attr('class', 'ui table').append( + $('').append( + $('').append( + $('').html('Categoría') + ).append( + $('').attr('class', 'right aligned').append( + $('').attr('class', 'ui tiny green circular icon button').append( + $('').attr('class', 'plus icon') + ) + ) + ) + ) + ) + table.find('.ui.button').click((e) => { + e.preventDefault() + this.add() + return false + }) + parent = $('') + table.append(parent) + $(this.id).append(table) + } + return parent + }, + draw: function() { + const parent = this.getParent() + parent.html('') + $.each(this.categorias, (i, el) => { + parent.append( + $('').append( + $('').html(el.nombre) + ) + ) + }) + }, + add: function() { + this.modal.find('form').trigger('reset') + this.modal.modal('show') + }, + doAdd: function() { + const data = JSON.stringify({ + nombre: $("[name='nombre']").val() + }) + return $.ajax({ + url: _urls.api + '/categorias/add', + method: 'POST', + data: data, + dataType: 'json' + }).then((data) => { + this.modal.modal('hide') + this.getCategorias() + }) + }, + setupModal: function() { + this.modal = $('.ui.modal') + this.modal.modal() + this.modal.find('.close.icon').click(() => { + this.modal.modal('hide') + }) + this.modal.find('form').submit((e) => { + e.preventDefault() + this.doAdd() + return false + }) + }, + setup: function() { + this.setupModal() + this.getCategorias() + } +} diff --git a/ui/public/assets/scripts/cuentas.list.js b/ui/public/assets/scripts/cuentas.list.js new file mode 100644 index 0000000..aad4e20 --- /dev/null +++ b/ui/public/assets/scripts/cuentas.list.js @@ -0,0 +1,125 @@ +const cuentas = { + id: '#cuentas', + cuentas: [], + categorias: [], + getCuentas: function() { + return $.ajax({ + url: _urls.api + '/cuentas', + method: 'GET', + dataType: 'json' + }).then((data) => { + if (data.cuentas === null || data.cuentas.length == 0) { + return + } + this.cuentas = data.cuentas + }).then(() => { + this.draw() + }) + }, + getCategorias: function() { + return $.ajax({ + url: _urls.api + '/categorias', + method: 'GET', + dataType: 'json' + }).then((data) => { + if (data.categorias === null || data.categorias.length == 0) { + return + } + this.categorias = data.categorias + }).then(() => { + this.drawCategorias() + }) + }, + drawCategorias: function() { + const select = $("[name='categoria']") + $.each(this.categorias, (i, el) => { + select.append( + $('').attr('value', el.id).html(el.nombre) + ) + }) + }, + buildParent: function(segment) { + const table = $('
').attr('class', 'ui table').append( + $('').append( + $('').append( + $('').html('Cuenta') + ).append( + $('').html('Categoría') + ).append( + $('').attr('class', 'right aligned').append( + $('').attr('class', 'ui tiny green circular icon button').append( + $('').attr('class', 'plus icon') + ) + ) + ) + ) + ) + table.find('.ui.button').click((e) => { + e.preventDefault() + this.add() + return false + }) + parent = $('') + table.append(parent) + segment.append(table) + return parent + }, + getParent: function() { + const segment = $(this.id) + let parent = segment.find('tbody') + if (parent.length == 0) { + parent = this.buildParent(segment) + } + return parent + }, + draw: function() { + const parent = this.getParent() + parent.html('') + $.each(this.cuentas, (i, el) => { + parent.append( + $('').append( + $('').html(el.nombre) + ).append( + $('').html(el.categoria.nombre) + ) + ) + }) + }, + add: function() { + this.modal.find('form').trigger('reset') + this.modal.modal('show') + }, + doAdd: function() { + const data = JSON.stringify({ + categoria_id: $("[name='categoria']").val(), + nombre: $("[name='nombre']").val() + }) + return $.ajax({ + url: _urls.api + '/cuentas/add', + method: 'POST', + data: data, + dataType: 'json' + }).then((data) => { + this.modal.modal('hide') + this.getCuentas() + }) + }, + setupModal: function() { + this.modal = $('.ui.modal') + this.modal.modal() + this.modal.find('.close.icon').css('cursor', 'pointer').click(() => { + this.modal.modal('hide') + }) + this.modal.find('form').submit((e) => { + e.preventDefault() + this.doAdd() + return false + }) + }, + setup: function() { + this.setupModal() + this.getCuentas().then(() => { + this.getCategorias() + }) + } +} diff --git a/ui/public/assets/scripts/fuentes.show.js b/ui/public/assets/scripts/fuentes.show.js new file mode 100644 index 0000000..3593e44 --- /dev/null +++ b/ui/public/assets/scripts/fuentes.show.js @@ -0,0 +1,121 @@ +const entradas = { + id: '#entradas', + modal: null, + fuente: null, + entradas: [], + getEntradas: function() { + return $.ajax({ + url: _urls.api + '/fuente/' + this.fuente + '/entradas', + method: 'GET', + dataType: 'json' + }).then((data) => { + if (data.fuente === null) { + return + } + $('#fuente').html(data.fuente.tipo.descripcion + ' - ' + data.fuente.banco.nombre + ' (' + data.fuente.saldoFormateado + ')') + if (data.entradas == null || data.entradas.length == 0) { + return + } + this.entradas = data.entradas + }).then(() => { + this.draw() + }) + }, + draw: function() { + const table = $(this.id) + table.html('') + $.each(this.entradas, (i, el) => { + table.append( + $('').append( + $('').html(el.fechaFormateada) + ).append( + $('').html(el.cuenta.nombre + ' (' + el.cuenta.categoria.nombre + ')') + ).append( + $('').html(el.glosa) + ).append( + $('').html(el.detalle) + ).append( + $('').attr('class', 'right aligned').html(el.valorFormateado) + ) + ) + }) + }, + getCuentas: function() { + return $.ajax({ + url: _urls.api + '/cuentas', + method: 'GET', + dataType: 'json' + }).then((data) => { + if (data.cuentas === null || data.cuentas.length == 0) { + return + } + this.cuentas = data.cuentas + }).then(() => { + const select = $("select[name='cuenta']") + $.each(this.cuentas, (i, el) => { + select.append( + $('').attr('value', el.id).html(el.nombre + ' (' + el.categoria.nombre + ')') + ) + }) + }) + }, + add: function() { + this.modal.find('form').trigger('reset') + this.modal.modal('show') + }, + doAdd: function() { + const data = JSON.stringify({ + fecha: $("[name='fecha']").val(), + fuente_id: this.fuente, + glosa: $("[name='glosa']").val(), + detalle: $("[name='detalle']").val(), + cuenta_id: $("[name='cuenta']").val(), + valor: $("[name='valor']").val() + }) + return $.ajax({ + url: _urls.api + '/entradas/add', + method: 'POST', + data: data, + dataType: 'json' + }).then((data) => { + this.modal.modal('hide') + this.getEntradas() + }) + }, + setupModal: function() { + this.modal = $('.ui.modal') + this.modal.modal() + this.modal.find('.ui.calendar').calendar({ + type: 'date', + formatter: { + date: function(date, settings) { + if (!date) return '' + let day = date.getDate() + let month = ('00' + (date.getMonth() + 1)).slice(-2) + let year = date.getFullYear() + return year + '/' + month + '/' + day + } + }, + maxDate: new Date() + }) + this.modal.find('.close.icon').css('cursor', 'pointer').click(() => { + this.modal.modal('hide') + }) + this.modal.find('form').submit((e) => { + e.preventDefault() + this.doAdd() + return false + }) + }, + setup: function() { + this.setupModal() + this.getEntradas().then(() => { + this.getCuentas() + }) + $(this.id).parent().find('.ui.button').click((e) => { + e.preventDefault() + this.add() + return false + }) + } +} diff --git a/ui/public/assets/scripts/home.js b/ui/public/assets/scripts/home.js new file mode 100644 index 0000000..87f851b --- /dev/null +++ b/ui/public/assets/scripts/home.js @@ -0,0 +1,136 @@ +const fuentes = { + id: '#fuentes', + fuentes: [], + tipos: [], + bancos: [], + modal: null, + getParent: function() { + let parent = $(this.id) + if (parent.length === 0) { + const table = $('
').attr('class', 'ui table').append( + $('').append( + $('').append( + $('').html('Fuente') + ).append( + $('').html('Saldo') + ).append( + $('').attr('class', 'right aligned').append( + $('').attr('class', 'ui tiny green circular icon button').append( + $('').attr('class', 'plus icon') + ).click(() => { + this.add() + }) + ) + ) + ) + ) + parent = $('').attr('id', this.id) + table.append(parent) + $('h1.header').after(table) + } + return parent + }, + setup: async function() { + this.modal = $('.ui.modal') + this.modal.modal() + this.modal.find('.close.icon').css('cursor', 'pointer').click(() => { + this.modal.modal('hide') + }) + this.getFuentes().then(() => { + this.getTipos().then(() => { + this.getBancos() + }) + }) + }, + add: function() { + this.modal.find('form').trigger('reset') + this.modal.find('form').submit((e) => { + e.preventDefault() + this.doAdd() + return false + }) + this.modal.modal('show') + }, + doAdd: function() { + const data = JSON.stringify({ + tipo_id: $("select[name='tipo']").val(), + banco_id: $("select[name='banco']").val() + }) + $.ajax({ + url: _urls.api + '/fuentes/add', + method: 'POST', + data: data, + dataType: 'json' + }).then((data) => { + this.modal.modal('hide') + this.getFuentes() + }) + }, + getFuentes: function() { + return $.ajax({ + url: _urls.api + '/fuentes', + method: 'GET', + dataType: 'json' + }).then((data) => { + if (data.fuentes === null || data.fuentes.length == 0) { + return + } + this.fuentes = data.fuentes + }).then(() => { + this.draw() + }) + }, + getTipos: function() { + return $.ajax({ + url: _urls.api + '/tipos_fuentes', + method: 'GET', + dataType: 'json' + }).then((data) => { + if (data.tipos_fuentes === null || data.tipos_fuentes.length == 0) { + return + } + this.tipos = data.tipos_fuentes + }).then(() => { + const select = $("select[name='tipo']") + select.html('') + $.each(this.tipos, (i, el) => { + select.append( + $('').attr('value', el.id).html(el.descripcion) + ) + }) + select.dropdown() + }) + }, + getBancos: function() { + return $.ajax({ + url: _urls.api + '/bancos', + method: 'GET', + dataType: 'json' + }).then((data) => { + if (data.bancos === null || data.bancos.length == 0) { + return + } + this.bancos = data.bancos + }).then(() => { + const select = $("select[name='banco']") + $.each(this.bancos, (i, el) => { + select.append( + $('').attr('value', el.id).html(el.nombre) + ) + }) + }) + }, + draw: function() { + const parent = this.getParent() + $.each(this.fuentes, (i, el) => { + const f = $('').append( + $('').append( + $('').attr('href', _urls.base + 'fuente/' + el.id).html(el.tipo.descripcion + ' - ' + el.banco.nombre) + ) + ).append( + $('').html(el.saldoFormateado) + ) + parent.append(f) + }) + } +} diff --git a/ui/public/index.php b/ui/public/index.php new file mode 100644 index 0000000..e6d2557 --- /dev/null +++ b/ui/public/index.php @@ -0,0 +1,7 @@ +run(); diff --git a/ui/resources/routes/bancos.php b/ui/resources/routes/bancos.php new file mode 100644 index 0000000..c0ea4e8 --- /dev/null +++ b/ui/resources/routes/bancos.php @@ -0,0 +1,4 @@ +get('/bancos/add', [Bancos::class, 'add']); diff --git a/ui/resources/routes/categorias.php b/ui/resources/routes/categorias.php new file mode 100644 index 0000000..0923540 --- /dev/null +++ b/ui/resources/routes/categorias.php @@ -0,0 +1,4 @@ +get('/categorias', Categorias::class); diff --git a/ui/resources/routes/cuentas.php b/ui/resources/routes/cuentas.php new file mode 100644 index 0000000..be40131 --- /dev/null +++ b/ui/resources/routes/cuentas.php @@ -0,0 +1,4 @@ +get('/cuentas', Cuentas::class); diff --git a/ui/resources/routes/fuentes.php b/ui/resources/routes/fuentes.php new file mode 100644 index 0000000..fa0ba4c --- /dev/null +++ b/ui/resources/routes/fuentes.php @@ -0,0 +1,4 @@ +get('/fuente/{fuente_id}', [Fuentes::class, 'show']); diff --git a/ui/resources/routes/home.php b/ui/resources/routes/home.php new file mode 100644 index 0000000..8e0c408 --- /dev/null +++ b/ui/resources/routes/home.php @@ -0,0 +1,4 @@ +get('[/]', Home::class); diff --git a/ui/resources/routes/tipos_fuentes.php b/ui/resources/routes/tipos_fuentes.php new file mode 100644 index 0000000..5ce612e --- /dev/null +++ b/ui/resources/routes/tipos_fuentes.php @@ -0,0 +1,4 @@ +get('/tipos_fuentes/add', [TiposFuentes::class, 'add']); diff --git a/ui/resources/views/bancos/base.blade.php b/ui/resources/views/bancos/base.blade.php new file mode 100644 index 0000000..b9ea728 --- /dev/null +++ b/ui/resources/views/bancos/base.blade.php @@ -0,0 +1,14 @@ +@extends('layout.base') + +@section('page_content') +

+ @hasSection('bancos_title') + Banco @yield('bancos_title') + @else + Bancos + @endif +

+
+ @yield('bancos_content') +
+@endsection diff --git a/ui/resources/views/categorias/base.blade.php b/ui/resources/views/categorias/base.blade.php new file mode 100644 index 0000000..4b14c94 --- /dev/null +++ b/ui/resources/views/categorias/base.blade.php @@ -0,0 +1,14 @@ +@extends('layout.base') + +@section('page_content') +

+ @hasSection('categorias_title') + Categoría @yield('categorias_title') + @else + Categorías + @endif +

+
+ @yield('categorias_content') +
+@endsection diff --git a/ui/resources/views/categorias/list.blade.php b/ui/resources/views/categorias/list.blade.php new file mode 100644 index 0000000..666e8b6 --- /dev/null +++ b/ui/resources/views/categorias/list.blade.php @@ -0,0 +1,28 @@ +@extends('categorias.base') + +@section('categorias_content') +
+ +@endsection + +@push('scripts') + + +@endpush diff --git a/ui/resources/views/cuentas/base.blade.php b/ui/resources/views/cuentas/base.blade.php new file mode 100644 index 0000000..c8d6d8d --- /dev/null +++ b/ui/resources/views/cuentas/base.blade.php @@ -0,0 +1,14 @@ +@extends('layout.base') + +@section('page_content') +

+ @hasSection('cuentas_title') + Cuenta @yield('cuentas_title') + @else + Cuentas + @endif +

+
+ @yield('cuentas_content') +
+@endsection diff --git a/ui/resources/views/cuentas/list.blade.php b/ui/resources/views/cuentas/list.blade.php new file mode 100644 index 0000000..9437bd3 --- /dev/null +++ b/ui/resources/views/cuentas/list.blade.php @@ -0,0 +1,32 @@ +@extends('cuentas.base') + +@section('cuentas_content') +
+ +@endsection + +@push('scripts') + + +@endpush diff --git a/ui/resources/views/fuentes/base.blade.php b/ui/resources/views/fuentes/base.blade.php new file mode 100644 index 0000000..0265aa6 --- /dev/null +++ b/ui/resources/views/fuentes/base.blade.php @@ -0,0 +1,14 @@ +@extends('layout.base') + +@section('page_content') +

+ @hasSection('fuentes_title') + Fuente @yield('fuentes_title') + @else + Fuentes + @endif +

+
+ @yield('fuentes_content') +
+@endsection diff --git a/ui/resources/views/fuentes/show.blade.php b/ui/resources/views/fuentes/show.blade.php new file mode 100644 index 0000000..25b6a32 --- /dev/null +++ b/ui/resources/views/fuentes/show.blade.php @@ -0,0 +1,81 @@ +@extends('fuentes.base') + +@section('fuentes_title') + +@endsection + +@section('fuentes_content') + + + + + + + + + + + + + +
+ Fecha + + Cuenta + + Glosa + + Detalle + + Valor + + +
+ +@endsection + +@push('scripts') + + +@endpush diff --git a/ui/resources/views/home.blade.php b/ui/resources/views/home.blade.php new file mode 100644 index 0000000..f606a8b --- /dev/null +++ b/ui/resources/views/home.blade.php @@ -0,0 +1,34 @@ +@extends('layout.base') + +@section('page_content') +

+ Contabilidad +

+ +@endsection + +@push('scripts') + + +@endpush diff --git a/ui/resources/views/layout/base.blade.php b/ui/resources/views/layout/base.blade.php new file mode 100644 index 0000000..9deb8c1 --- /dev/null +++ b/ui/resources/views/layout/base.blade.php @@ -0,0 +1,5 @@ + + +@include('layout.head') +@include('layout.body') + diff --git a/ui/resources/views/layout/body.blade.php b/ui/resources/views/layout/body.blade.php new file mode 100644 index 0000000..d9a4511 --- /dev/null +++ b/ui/resources/views/layout/body.blade.php @@ -0,0 +1,5 @@ + + @include('layout.body.header') + @yield('page_content') + @include('layout.body.footer') + diff --git a/ui/resources/views/layout/body/footer.blade.php b/ui/resources/views/layout/body/footer.blade.php new file mode 100644 index 0000000..c3b1007 --- /dev/null +++ b/ui/resources/views/layout/body/footer.blade.php @@ -0,0 +1,4 @@ +
+ +
+@include('layout.body.scripts') diff --git a/ui/resources/views/layout/body/header.blade.php b/ui/resources/views/layout/body/header.blade.php new file mode 100644 index 0000000..f75fe10 --- /dev/null +++ b/ui/resources/views/layout/body/header.blade.php @@ -0,0 +1,3 @@ +
+ @include('layout.body.menu') +
diff --git a/ui/resources/views/layout/body/menu.blade.php b/ui/resources/views/layout/body/menu.blade.php new file mode 100644 index 0000000..6735d97 --- /dev/null +++ b/ui/resources/views/layout/body/menu.blade.php @@ -0,0 +1,5 @@ + diff --git a/ui/resources/views/layout/body/menu/categorias.blade.php b/ui/resources/views/layout/body/menu/categorias.blade.php new file mode 100644 index 0000000..9c4951d --- /dev/null +++ b/ui/resources/views/layout/body/menu/categorias.blade.php @@ -0,0 +1,3 @@ + + Categorías + diff --git a/ui/resources/views/layout/body/menu/cuentas.blade.php b/ui/resources/views/layout/body/menu/cuentas.blade.php new file mode 100644 index 0000000..8e05793 --- /dev/null +++ b/ui/resources/views/layout/body/menu/cuentas.blade.php @@ -0,0 +1,3 @@ + + Cuentas + diff --git a/ui/resources/views/layout/body/scripts.blade.php b/ui/resources/views/layout/body/scripts.blade.php new file mode 100644 index 0000000..f3bfbe3 --- /dev/null +++ b/ui/resources/views/layout/body/scripts.blade.php @@ -0,0 +1,11 @@ + + + + + +@stack('scripts') diff --git a/ui/resources/views/layout/head.blade.php b/ui/resources/views/layout/head.blade.php new file mode 100644 index 0000000..518f1fe --- /dev/null +++ b/ui/resources/views/layout/head.blade.php @@ -0,0 +1,5 @@ + + + Contabilidad + @include('layout.head.styles') + diff --git a/ui/resources/views/layout/head/styles.blade.php b/ui/resources/views/layout/head/styles.blade.php new file mode 100644 index 0000000..405e4b6 --- /dev/null +++ b/ui/resources/views/layout/head/styles.blade.php @@ -0,0 +1,8 @@ + + + + + + + +@stack('styles') diff --git a/ui/resources/views/tipos_fuentes/base.blade.php b/ui/resources/views/tipos_fuentes/base.blade.php new file mode 100644 index 0000000..89758c7 --- /dev/null +++ b/ui/resources/views/tipos_fuentes/base.blade.php @@ -0,0 +1,14 @@ +@extends('layout.base') + +@section('page_content') +

+ @hasSection('tipos_fuentes_title') + Tipo Fuente @yield('tipos_fuentes_title') + @else + Tipos Fuentes + @endif +

+
+ @yield('tipos_fuentes_content') +
+@endsection diff --git a/ui/setup/app.php b/ui/setup/app.php new file mode 100644 index 0000000..79fb83b --- /dev/null +++ b/ui/setup/app.php @@ -0,0 +1,45 @@ +isDir()) { + continue; + } + $builder->addDefinitions($file->getRealPath()); + } +} + +$container = $builder->build(); +$app = Bridge::create($container); + +$app->addRoutingMiddleware(); +$app->add(new WhoopsMiddleware()); + + +$folder = 'middlewares'; +if (file_exists($folder)) { + $files = new DirectoryIterator($folder); + foreach ($files as $file) { + if ($file->isDir() or $file->getExtension() != 'php') { + continue; + } + include_once $file->getRealPath(); + } +} + +include_once 'router.php'; diff --git a/ui/setup/composer.php b/ui/setup/composer.php new file mode 100644 index 0000000..c8fb135 --- /dev/null +++ b/ui/setup/composer.php @@ -0,0 +1,6 @@ +getContainer()->get('folders')->routes; +$files = new DirectoryIterator($folder); +foreach ($files as $file) { + if ($file->isDir() or $file->getExtension() != 'php') { + continue; + } + include_once $file->getRealPath(); +} diff --git a/ui/setup/settings/01_env.php b/ui/setup/settings/01_env.php new file mode 100644 index 0000000..161b2d4 --- /dev/null +++ b/ui/setup/settings/01_env.php @@ -0,0 +1,4 @@ + $_ENV['DEBUG'] ?? false +]; diff --git a/ui/setup/settings/02_common.php b/ui/setup/settings/02_common.php new file mode 100644 index 0000000..0228dce --- /dev/null +++ b/ui/setup/settings/02_common.php @@ -0,0 +1,27 @@ + function(Container $c) { + $arr = [ + 'base' => dirname(__DIR__, 2) + ]; + $arr['resources'] = implode(DIRECTORY_SEPARATOR, [ + $arr['base'], + 'resources' + ]); + $arr['routes'] = implode(DIRECTORY_SEPARATOR, [ + $arr['resources'], + 'routes' + ]); + $arr['cache'] = implode(DIRECTORY_SEPARATOR, [ + $arr['base'], + 'cache' + ]); + $arr['templates'] = implode(DIRECTORY_SEPARATOR, [ + $arr['resources'], + 'views' + ]); + return (object) $arr; + } +]; diff --git a/ui/setup/settings/03_web.php b/ui/setup/settings/03_web.php new file mode 100644 index 0000000..ce36463 --- /dev/null +++ b/ui/setup/settings/03_web.php @@ -0,0 +1,22 @@ + function(Container $c) { + $arr = ['base' => $_ENV['BASE_URL'] ?? '/']; + $arr['assets'] = str_replace('//', '/', implode('/', [ + $arr['base'], + 'assets' + ])); + $arr['images'] = implode('/', [ + $arr['assets'], + 'images' + ]); + $arr['scripts'] = implode('/', [ + $arr['assets'], + 'scripts' + ]); + $arr['api'] = $_ENV['API_URL'] ?? 'http://localhost:9001'; + return (object) $arr; + } +]; diff --git a/ui/setup/setups/03_web.php b/ui/setup/setups/03_web.php new file mode 100644 index 0000000..96e1740 --- /dev/null +++ b/ui/setup/setups/03_web.php @@ -0,0 +1,15 @@ + function(Container $c) { + return new Slim\Views\Blade( + $c->get('folders')->templates, + $c->get('folders')->cache, + null, + [ + 'urls' => $c->get('urls') + ] + ); + } +];