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 0000000..4294e87
Binary files /dev/null and b/ui/public/assets/images/abacus-icon.png differ
diff --git a/ui/public/assets/images/fund-accounting.png b/ui/public/assets/images/fund-accounting.png
new file mode 100644
index 0000000..4b32b74
Binary files /dev/null and b/ui/public/assets/images/fund-accounting.png differ
diff --git a/ui/public/assets/scripts/categorias.list.js b/ui/public/assets/scripts/categorias.list.js
new file mode 100644
index 0000000..0fcefa2
--- /dev/null
+++ b/ui/public/assets/scripts/categorias.list.js
@@ -0,0 +1,91 @@
+const categorias = {
+ id: '#categorias',
+ categorias: [],
+ modal: null,
+ 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.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')
+
+
+ @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')
+
+
+ @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')
+
+
+ @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')
+
+
+ @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')
+
+
+@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')
+
+
+ @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')
+ ]
+ );
+ }
+];