├── .gitignore ├── .vscode └── settings.json ├── docs ├── 01-html │ └── index.html ├── 02-html-intermedio │ └── index.html ├── 03-css │ └── index.html ├── 04-css-intermedio │ └── index.html ├── 05-flexbox │ └── index.html ├── 06-flexbox-practica │ └── index.html ├── 07-00-terminal │ └── index.html ├── 07-01-git │ └── index.html ├── 07-02-github │ └── index.html ├── 07-b-fundamentos │ └── index.html ├── 08-b-componentes │ └── index.html ├── 09-b-accordion │ └── index.html ├── 10-b-scroll │ └── index.html ├── 11-01-psint │ └── index.html ├── 11-02-js-basico │ └── index.html ├── 11-03-js │ └── index.html ├── 11-04-js │ └── index.html ├── 11-05-js-dom │ └── index.html ├── 11-06-js-paradigma │ └── index.html ├── 11-07-js-delegacion │ └── index.html ├── 11-08-js-form │ └── index.html ├── 11-09-js-promesas │ └── index.html ├── 11-10-js-fetch │ └── index.html ├── 11-11-js-poo │ └── index.html ├── 11-12-js-modulos │ └── index.html ├── 11-13-js-closure │ └── index.html ├── 11-b-form │ └── index.html ├── 12-b-sass │ └── index.html ├── 13-b-chat │ └── index.html ├── 14-b-range │ └── index.html ├── 15-b-php │ └── index.html ├── 16-b-parsel │ └── index.html ├── 17-b-offcanvas │ └── index.html ├── 18-01-react │ └── index.html ├── 18-02-react-formularios │ └── index.html ├── 18-03-react-todo │ └── index.html ├── 18-04-react-api │ └── index.html ├── 18-05-react-router │ └── index.html ├── 18-06-react-context │ └── index.html ├── 19-01-sql │ └── index.html ├── 19-02-sql │ └── index.html ├── 19-03-sql │ └── index.html ├── 19-04-sql │ └── index.html ├── 20-01-node │ └── index.html ├── 20-02-express │ └── index.html ├── 21-03-api-rest │ └── index.html ├── 21-04-mevn │ └── index.html ├── 404.html ├── assets │ ├── css │ │ └── 0.styles.fe573751.css │ ├── img │ │ └── search.83621669.svg │ └── js │ │ ├── 10.866947a4.js │ │ ├── 11.c17c37e2.js │ │ ├── 12.da3769ab.js │ │ ├── 13.5663183b.js │ │ ├── 14.23d5af8e.js │ │ ├── 15.e46b76b0.js │ │ ├── 16.8d6dc3f7.js │ │ ├── 17.9a606157.js │ │ ├── 18.7dd07034.js │ │ ├── 19.a14ff68f.js │ │ ├── 2.0ac7fe89.js │ │ ├── 20.7ee26afc.js │ │ ├── 21.8cc89470.js │ │ ├── 22.69539fd9.js │ │ ├── 23.3d7de5a4.js │ │ ├── 24.4614da3f.js │ │ ├── 25.784bde9c.js │ │ ├── 26.80322b59.js │ │ ├── 27.ecde74b7.js │ │ ├── 28.6f4713fa.js │ │ ├── 29.e9054ffa.js │ │ ├── 3.c6daeaf2.js │ │ ├── 30.9a4b2420.js │ │ ├── 31.1c12a120.js │ │ ├── 32.7658c927.js │ │ ├── 33.0c2cebce.js │ │ ├── 34.e08a7fdf.js │ │ ├── 35.cf93cc6e.js │ │ ├── 36.d496f058.js │ │ ├── 37.5531251f.js │ │ ├── 38.9785f2e4.js │ │ ├── 39.f10e604c.js │ │ ├── 4.8e3cbe65.js │ │ ├── 40.5ea4994d.js │ │ ├── 41.2561b5df.js │ │ ├── 42.2be087a2.js │ │ ├── 43.1c80e311.js │ │ ├── 44.df299850.js │ │ ├── 45.8d77d76d.js │ │ ├── 46.e375bd67.js │ │ ├── 47.b06e7d1c.js │ │ ├── 48.b5bcc0c2.js │ │ ├── 49.371a6ee5.js │ │ ├── 5.07d5bc9a.js │ │ ├── 50.6828b12b.js │ │ ├── 51.27638769.js │ │ ├── 52.cf7f7628.js │ │ ├── 53.62362e51.js │ │ ├── 54.b34fcbd0.js │ │ ├── 55.50e41ea4.js │ │ ├── 56.964ab5bd.js │ │ ├── 57.7a73fb23.js │ │ ├── 6.9625d00a.js │ │ ├── 7.f837ab7f.js │ │ ├── 8.3a1d618b.js │ │ ├── 9.ea5777ec.js │ │ └── app.4fdaa86a.js ├── img │ ├── MDN-Graphics-inherited-3.png │ ├── MDN-Graphics-instantiation-2-fixed.png │ ├── MDN-Graphics-instantiation-teacher-3.png │ ├── MDN-Graphics-person-person-object-2.png │ ├── Periodic-Table-of-HTML-Elements.png │ ├── array.png │ ├── bean.gif │ ├── beautify.PNG │ ├── busqueda.webp │ ├── cafe-1.JPG │ ├── cafe-2.JPG │ ├── caja-git.png │ ├── checkout-1.JPG │ ├── conflicto-2.JPG │ ├── context-props.png │ ├── display2.png │ ├── entidad-relacion-2.JPG │ ├── error-1.JPG │ ├── estructura-html5.jpg │ ├── execution.png │ ├── feature.png │ ├── fn-0.JPG │ ├── fn-10.JPG │ ├── fn-11.JPG │ ├── fn-12.JPG │ ├── fn-20.jpg │ ├── fn-21.jpg │ ├── fn-30.jpg │ ├── fn-31.JPG │ ├── git-flujo.png │ ├── git-merge.gif │ ├── git-vscode.JPG │ ├── git.png │ ├── github-page.JPG │ ├── hell.jpg │ ├── html-1.png │ ├── html-2.png │ ├── html-2021-2.jpg │ ├── html-2021.jpg │ ├── indentar.gif │ ├── javascript.gif │ ├── joins.png │ ├── js-gif-1.gif │ ├── js-gif.gif │ ├── null.PNG │ ├── objetos-1.PNG │ ├── objetos-2.png │ ├── person-diagram.png │ ├── power-config.JPG │ ├── programar.gif │ ├── promesa.gif │ ├── proto1.png │ ├── proto2.png │ ├── pseint-1.JPG │ ├── pseint-10.JPG │ ├── pseint-2.JPG │ ├── pseint-3.JPG │ ├── pseint-4.JPG │ ├── pseint-5.JPG │ ├── pseint-6.JPG │ ├── pseint-7.JPG │ ├── pseint-8.JPG │ ├── pseint-9.JPG │ ├── repo-github.JPG │ ├── reset.png │ ├── revert.svg │ ├── scaner.gif │ ├── selector.gif │ ├── sitio-css-1.PNG │ ├── todo-relaciones.JPG │ ├── valor-2.png │ ├── valor.png │ ├── velocidad-n1.PNG │ ├── vsc-1.png │ ├── vscode-2.png │ ├── vscode-3.png │ ├── vscode-4.png │ ├── vscode-5.png │ └── vscode-6.png └── index.html ├── package-lock.json ├── package.json ├── src ├── .vuepress │ ├── components │ │ ├── Foo │ │ │ └── Bar.vue │ │ ├── OtherComponent.vue │ │ └── demo-component.vue │ ├── config.js │ ├── enhanceApp.js │ ├── public │ │ └── img │ │ │ ├── MDN-Graphics-inherited-3.png │ │ │ ├── MDN-Graphics-instantiation-2-fixed.png │ │ │ ├── MDN-Graphics-instantiation-teacher-3.png │ │ │ ├── MDN-Graphics-person-person-object-2.png │ │ │ ├── Periodic-Table-of-HTML-Elements.png │ │ │ ├── array.png │ │ │ ├── bean.gif │ │ │ ├── beautify.PNG │ │ │ ├── busqueda.webp │ │ │ ├── cafe-1.JPG │ │ │ ├── cafe-2.JPG │ │ │ ├── caja-git.png │ │ │ ├── checkout-1.JPG │ │ │ ├── conflicto-2.JPG │ │ │ ├── context-props.png │ │ │ ├── display2.png │ │ │ ├── entidad-relacion-2.JPG │ │ │ ├── error-1.JPG │ │ │ ├── estructura-html5.jpg │ │ │ ├── execution.png │ │ │ ├── feature.png │ │ │ ├── fn-0.JPG │ │ │ ├── fn-10.JPG │ │ │ ├── fn-11.JPG │ │ │ ├── fn-12.JPG │ │ │ ├── fn-20.jpg │ │ │ ├── fn-21.jpg │ │ │ ├── fn-30.jpg │ │ │ ├── fn-31.JPG │ │ │ ├── git-flujo.png │ │ │ ├── git-merge.gif │ │ │ ├── git-vscode.JPG │ │ │ ├── git.png │ │ │ ├── github-page.JPG │ │ │ ├── hell.jpg │ │ │ ├── html-1.png │ │ │ ├── html-2.png │ │ │ ├── html-2021-2.jpg │ │ │ ├── html-2021.jpg │ │ │ ├── indentar.gif │ │ │ ├── javascript.gif │ │ │ ├── joins.png │ │ │ ├── js-gif-1.gif │ │ │ ├── js-gif.gif │ │ │ ├── null.PNG │ │ │ ├── objetos-1.PNG │ │ │ ├── objetos-2.png │ │ │ ├── person-diagram.png │ │ │ ├── power-config.JPG │ │ │ ├── programar.gif │ │ │ ├── promesa.gif │ │ │ ├── proto1.png │ │ │ ├── proto2.png │ │ │ ├── pseint-1.JPG │ │ │ ├── pseint-10.JPG │ │ │ ├── pseint-2.JPG │ │ │ ├── pseint-3.JPG │ │ │ ├── pseint-4.JPG │ │ │ ├── pseint-5.JPG │ │ │ ├── pseint-6.JPG │ │ │ ├── pseint-7.JPG │ │ │ ├── pseint-8.JPG │ │ │ ├── pseint-9.JPG │ │ │ ├── repo-github.JPG │ │ │ ├── reset.png │ │ │ ├── revert.svg │ │ │ ├── scaner.gif │ │ │ ├── selector.gif │ │ │ ├── sitio-css-1.PNG │ │ │ ├── todo-relaciones.JPG │ │ │ ├── valor-2.png │ │ │ ├── valor.png │ │ │ ├── velocidad-n1.PNG │ │ │ ├── vsc-1.png │ │ │ ├── vscode-2.png │ │ │ ├── vscode-3.png │ │ │ ├── vscode-4.png │ │ │ ├── vscode-5.png │ │ │ └── vscode-6.png │ └── styles │ │ ├── index.styl │ │ └── palette.styl ├── 01-html │ └── README.md ├── 02-html-intermedio │ └── README.md ├── 03-css │ └── README.md ├── 04-css-intermedio │ └── README.md ├── 05-flexbox │ └── README.md ├── 06-flexbox-practica │ └── README.md ├── 07-00-terminal │ └── README.md ├── 07-01-git │ └── README.md ├── 07-02-github │ ├── README.md │ └── api-paises.json ├── 07-b-fundamentos │ └── README.md ├── 08-b-componentes │ └── README.md ├── 09-b-accordion │ └── README.md ├── 10-b-scroll │ └── README.md ├── 11-01-psint │ └── README.md ├── 11-02-js-basico │ └── README.md ├── 11-03-js │ ├── README.md │ └── index.html ├── 11-04-js │ └── README.md ├── 11-05-js-dom │ ├── README.md │ ├── app.js │ └── index.html ├── 11-06-js-paradigma │ ├── README.md │ ├── app.js │ └── index.html ├── 11-07-js-delegacion │ ├── README.md │ ├── app.js │ └── index.html ├── 11-08-js-form │ ├── README.md │ ├── app.js │ └── index.html ├── 11-09-js-promesas │ ├── README.md │ ├── app.js │ └── index.html ├── 11-10-js-fetch │ ├── README.md │ ├── app.js │ └── index.html ├── 11-11-js-poo │ ├── README.md │ ├── index.html │ └── js │ │ ├── app.js │ │ └── persona.js ├── 11-12-js-modulos │ ├── README.md │ ├── index.html │ └── js │ │ ├── app.js │ │ └── persona.js ├── 11-13-js-closure │ ├── README.md │ ├── index.html │ └── js │ │ └── app.js ├── 11-b-form │ └── README.md ├── 12-b-sass │ └── README.md ├── 13-b-chat │ └── README.md ├── 14-b-range │ └── README.md ├── 15-b-php │ └── README.md ├── 16-b-parsel │ └── README.md ├── 17-b-offcanvas │ └── README.md ├── 18-01-react │ └── README.md ├── 18-02-react-formularios │ └── README.md ├── 18-03-react-todo │ └── README.md ├── 18-04-react-api │ └── README.md ├── 18-05-react-router │ └── README.md ├── 18-06-react-context │ └── README.md ├── 19-01-sql │ └── README.md ├── 19-02-sql │ ├── RDBMS.png │ └── README.md ├── 19-03-sql │ └── README.md ├── 19-04-sql │ └── README.md ├── 20-01-node │ └── README.md ├── 20-02-express │ ├── README.md │ └── login1.js ├── 21-03-api-rest │ └── README.md ├── 21-04-mevn │ └── README.md └── README.md └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | pids 2 | logs 3 | node_modules 4 | npm-debug.log 5 | coverage/ 6 | run 7 | dist 8 | .DS_Store 9 | .nyc_output 10 | .basement 11 | config.local.js 12 | basement_dist 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | HTML, CSS y Bootstrap 5 (bluuweb) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |

404

How did we get here?
19 | Take me home. 20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/assets/img/search.83621669.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/assets/js/3.c6daeaf2.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[3],{343:function(t,e,n){},370:function(t,e,n){"use strict";n(343)},428:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,e){var n=e.props,i=e.slots;return t("span",{class:["badge",n.type],style:{verticalAlign:n.vertical}},n.text||i().default)}},r=(n(370),n(28)),p=Object(r.a)(i,void 0,void 0,!1,null,"15b7b770",null);e.default=p.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/4.8e3cbe65.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[4],{344:function(t,e,a){},371:function(t,e,a){"use strict";a(344)},377:function(t,e,a){"use strict";a.r(e);var n={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}},mounted:function(){this.$parent&&this.$parent.loadTabs&&this.$parent.loadTabs()}},i=(a(371),a(28)),s=Object(i.a)(n,(function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"759a7d02",null);e.default=s.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/5.07d5bc9a.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[5],{345:function(e,t,a){},372:function(e,t,a){"use strict";a(345)},378:function(e,t,a){"use strict";a.r(t);a(72),a(31),a(100),a(101);var o={name:"CodeGroup",data:function(){return{codeTabs:[],activeCodeTabIndex:-1}},watch:{activeCodeTabIndex:function(e){this.activateCodeTab(e)}},mounted:function(){this.loadTabs()},methods:{changeCodeTab:function(e){this.activeCodeTabIndex=e},loadTabs:function(){var e=this;this.codeTabs=(this.$slots.default||[]).filter((function(e){return Boolean(e.componentOptions)})).map((function(t,a){return""===t.componentOptions.propsData.active&&(e.activeCodeTabIndex=a),{title:t.componentOptions.propsData.title,elm:t.elm}})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0),this.activateCodeTab(0)},activateCodeTab:function(e){this.codeTabs.forEach((function(e){e.elm&&e.elm.classList.remove("theme-code-block__active")})),this.codeTabs[e].elm&&this.codeTabs[e].elm.classList.add("theme-code-block__active")}}},n=(a(372),a(28)),c=Object(n.a)(o,(function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ClientOnly",[a("div",{staticClass:"theme-code-group"},[a("div",{staticClass:"theme-code-group__nav"},[a("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(t,o){return a("li",{key:t.title,staticClass:"theme-code-group__li"},[a("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":o===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(o)}}},[e._v("\n "+e._s(t.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?a("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)])}),[],!1,null,"deefee04",null);t.default=c.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/52.cf7f7628.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[52],{421:function(a,e,t){"use strict";t.r(e);var r=t(28),s=Object(r.a)({},(function(){var a=this,e=a.$createElement,t=a._self._c||e;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h1",{attrs:{id:"postgresql-normalizacion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#postgresql-normalizacion"}},[a._v("#")]),a._v(" PostgreSQL Normalización")]),a._v(" "),t("p",[a._v("Conozcamos como normalizar nuestra base de datos.")]),a._v(" "),t("iframe",{attrs:{width:"560",height:"315",src:"https://www.youtube.com/embed/D_Alt-GY-xo",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:""}}),a._v(" "),t("h2",{attrs:{id:"normalizacion"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#normalizacion"}},[a._v("#")]),a._v(" Normalización")]),a._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://explodat.cl/Analytics/desarrollo-de-software/normalizacion-de-bases-de-datos/",target:"_blank",rel:"noopener noreferrer"}},[a._v("fuente #01"),t("OutboundLink")],1)]),a._v(" "),t("li",[a._v("La normalización es el proceso de seguir una serie de reglas (formas normales), para asegurar que nuestras relaciones estén "),t("strong",[a._v("ordenadas y regularizadas")]),a._v(" con el fin de "),t("strong",[a._v("mejorar")]),a._v(" dichas relaciones.")]),a._v(" "),t("li",[a._v("Están enfocadas en evitar la redundancia de datos e inconsistencias en el diseño de nuestras tablas.")])]),a._v(" "),t("h2",{attrs:{id:"¿por-que-normalizar"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#¿por-que-normalizar"}},[a._v("#")]),a._v(" ¿Por qué normalizar?")]),a._v(" "),t("ul",[t("li",[a._v("Evitar redundancia de datos")]),a._v(" "),t("li",[a._v("Proteger la integridad de los datos")]),a._v(" "),t("li",[a._v("Evitar problemas de actualiación.")])]),a._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[a._v("¿Cómo normalizar una DB?")]),a._v(" "),t("ul",[t("li",[a._v("Se siguen "),t("strong",[a._v("en un proceso ordenado")]),a._v(" las formas normales (FN).")]),a._v(" "),t("li",[a._v("Por ende partimos con 1FN, 2FN... hasta la 6FN.")]),a._v(" "),t("li",[a._v("Lo tradicional es llegar hasta la 3FN.\n:::")])]),a._v(" "),t("h2",{attrs:{id:"ejemplo"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ejemplo"}},[a._v("#")]),a._v(" Ejemplo")]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-0.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("h2",{attrs:{id:"_1fn-primera-forma-normal"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1fn-primera-forma-normal"}},[a._v("#")]),a._v(" 1FN (primera forma normal)")]),a._v(" "),t("ul",[t("li",[a._v("Cada campo o atributo deben ser atómicos, es decir debe contener un único valor.")]),a._v(" "),t("li",[a._v("No pueden haber grupos repetitivos.")]),a._v(" "),t("li",[a._v("Existir una llave primaria.")])]),a._v(" "),t("h3",{attrs:{id:"solucion-1"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#solucion-1"}},[a._v("#")]),a._v(" Solución 1")]),a._v(" "),t("ul",[t("li",[a._v("Todos los datos son atómicos")]),a._v(" "),t("li",[a._v("Pero telefono 1 y telefono 2 es un grupo repetitivo, esto genera:\n"),t("ul",[t("li",[a._v("Pérdida de espacios de memoría.")]),a._v(" "),t("li",[a._v("Limitar a solo dos teléfonos nuesta DB.")])])])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-10.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("h2",{attrs:{id:"solucion-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#solucion-2"}},[a._v("#")]),a._v(" Solución 2")]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-11.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("h3",{attrs:{id:"redundancia-solucion-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#redundancia-solucion-2"}},[a._v("#")]),a._v(" Redundancia solución 2")]),a._v(" "),t("ul",[t("li",[a._v("Podemos notar que si un paciente pide otra hora médica genera redundancia en nuestra tabla. Por ende tenemos que separar en una nueva relación:")])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-12.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[a._v("TIP")]),a._v(" "),t("p",[a._v("Antes de pasar a 2FN, conozcamos los tipos de dependencia.")])])]),a._v(" "),t("h2",{attrs:{id:"tipos-de-dependencia"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#tipos-de-dependencia"}},[a._v("#")]),a._v(" Tipos de dependencia")]),a._v(" "),t("ul",[t("li",[t("strong",[a._v("Dependencia Funcional")]),a._v(": Los atributos dependen de la clave primaria.")]),a._v(" "),t("li",[a._v("B y C dependen funcionalmente de A (clave primaria).")]),a._v(" "),t("li",[a._v("Para que exista B debe existir A. y lo mismo para C.")])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-20.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("ul",[t("li",[t("strong",[a._v("Dependencia Transitiva")]),a._v(":")]),a._v(" "),t("li",[a._v("B depende funcionalmente de A.")]),a._v(" "),t("li",[a._v("C depende de B, pero como B depende de A, C tiene una dependencia transitiva de A.")])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-20.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("h2",{attrs:{id:"_2fn-segunda-forma-normal"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2fn-segunda-forma-normal"}},[a._v("#")]),a._v(" 2FN (segunda forma normal)")]),a._v(" "),t("ul",[t("li",[a._v("Debe cumplir con 1FN.")]),a._v(" "),t("li",[a._v("Cada atributo debe depender de la llave primaria, y no solo una parte de ella.")]),a._v(" "),t("li",[a._v("Los atributos que dependen de manera parcial de la llave primaria deben ser\neliminados o almacenados en una nueva entidad.")])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-12.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("h3",{attrs:{id:"llave-primaria-compuesta"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#llave-primaria-compuesta"}},[a._v("#")]),a._v(" Llave primaria compuesta")]),a._v(" "),t("ul",[t("li",[a._v('compuesta de "idpaciente", "especialidad" y "fecha atencion"')]),a._v(" "),t("li",[a._v('si analizamos "area" esta depende exclusivamente de la especilidad y no del id del paciente, por ende no cumple con la 2FN (Cada atributo debe depender de la llave primaria, y no solo una parte de ella.)')])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-21.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("h2",{attrs:{id:"_3fn-tercera-forma-normal"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3fn-tercera-forma-normal"}},[a._v("#")]),a._v(" 3FN (tercera forma normal)")]),a._v(" "),t("ul",[t("li",[a._v("Debe cumplir con 2FN.")]),a._v(" "),t("li",[a._v("Eliminar toda dependencia transitiva.")])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-30.JPG"),alt:"relacion todo sql"}})]),a._v(" "),t("h2",{attrs:{id:"¿desnormalizar"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#¿desnormalizar"}},[a._v("#")]),a._v(" ¿Desnormalizar?")]),a._v(" "),t("ul",[t("li",[a._v("Dependerá de cada caso, si es más factible duplicar datos que realizar múltiples relaciones que pueden ser complejas.")])]),a._v(" "),t("div",{staticClass:"text-center"},[t("img",{attrs:{src:a.$withBase("/img/fn-31.JPG"),alt:"relacion todo sql"}})])])}),[],!1,null,null,null);e.default=s.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/57.7a73fb23.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[57],{426:function(t,e,r){"use strict";r.r(e);var s=r(28),a=Object(s.a)({},(function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"curso-html-css-y-bootstrap-5"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#curso-html-css-y-bootstrap-5"}},[t._v("#")]),t._v(" Curso HTML, CSS y Bootstrap 5")]),t._v(" "),r("div",{staticStyle:{"text-align":"center",padding:"2rem 0"}},[r("a",{attrs:{href:"https://bit.ly/3lNnPeh",target:"_blank"}},[r("img",{staticStyle:{maxWidth:"300px"},attrs:{src:t.$withBase("/img/html-2021-2.jpg"),alt:"foo"}})]),t._v(" "),r("br"),t._v(" "),r("a",{staticClass:"ancla-btn",attrs:{href:"https://bit.ly/3lNnPeh",target:"_blank"}},[t._v("\n 😍 ACCEDE AL CURSO AQUÍ 😍\n ")])]),t._v(" "),r("p",[t._v("Este curso intensivo tiene como finalidad entregar las herramientas necesarias para comenzar en el desarrollo web con HTML, CSS y Bootstrap 5.")]),t._v(" "),r("p",[t._v("Está orientado a la práctica por ende a través de diferentes ejemplos comprenderemos como es el camino del desarrollo web.")]),t._v(" "),r("p",[t._v("Al finalizar el curso el estudiante podrá construir sitios web responsives utilizando HTML, CSS y Bootstrap 5. 👌")]),t._v(" "),r("div",{staticClass:"custom-block tip"},[r("p",{staticClass:"custom-block-title"},[t._v("🎉 Accede al curso con un super descuento 🎉")]),t._v(" "),r("p",[t._v("Este curso está publicado en Udemy, puedes acceder con un descuento especial en el siguiente enlace:")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"curso-bootstrap-5-udemy.bluuweb.cl"}},[t._v("Ir al curso en Udemy aquí")]),t._v("\n:::")])]),t._v(" "),r("h2",{attrs:{id:"¿dudas-y-preguntas"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#¿dudas-y-preguntas"}},[t._v("#")]),t._v(" ¿Dudas y preguntas?")]),t._v(" "),r("p",[t._v("Te invito a nuestro servidor de "),r("strong",[t._v("Discord")]),t._v(", donde todos nos ayudamos. "),r("strong",[t._v("ES GRATIS")]),t._v(" 👏")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://discord.com/invite/hcG7NBvsGD",target:"_blank",rel:"noopener noreferrer"}},[t._v("Click aquí: https://discord.com/invite/hcG7NBvsGD"),r("OutboundLink")],1)])]),t._v(" "),r("h2",{attrs:{id:"gist"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#gist"}},[t._v("#")]),t._v(" Gist")]),t._v(" "),r("p",[t._v("Aquí iré detallando diferentes notas:")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://gist.github.com/bluuweb/8612c7e1c82bb85bce5b92d67f5b285c",target:"_blank",rel:"noopener noreferrer"}},[t._v("Notas de HTML y CSS"),r("OutboundLink")],1)])]),t._v(" "),r("h2",{attrs:{id:"redes-sociales"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#redes-sociales"}},[t._v("#")]),t._v(" Redes Sociales:")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://www.youtube.com/bluuweb",target:"_blank",rel:"noopener noreferrer"}},[t._v("Youtube"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://www.twitch.tv/bluuweb",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitch"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://www.instagram.com/bluuweb_youtube",target:"_blank",rel:"noopener noreferrer"}},[t._v("Instagram"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://www.facebook.com/bluuweb",target:"_blank",rel:"noopener noreferrer"}},[t._v("Facebook"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://twitter.com/bluuweb",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://discord.com/invite/hcG7NBvsGD",target:"_blank",rel:"noopener noreferrer"}},[t._v("Discord"),r("OutboundLink")],1)])])])])}),[],!1,null,null,null);e.default=a.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/6.9625d00a.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[6],{374:function(t,e,s){"use strict";s.r(e);var n=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],o={methods:{getMsg:function(){return n[Math.floor(Math.random()*n.length)]}}},i=s(28),h=Object(i.a)(o,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"theme-container"},[e("div",{staticClass:"theme-default-content"},[e("h1",[this._v("404")]),this._v(" "),e("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),e("RouterLink",{attrs:{to:"/"}},[this._v("\n Take me home.\n ")])],1)])}),[],!1,null,null,null);e.default=h.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/7.f837ab7f.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[7],{376:function(t,s,n){"use strict";n.r(s);var e={data:function(){return{msg:"Hello this is "}}},i=n(28),a=Object(i.a)(e,(function(){var t=this.$createElement;return(this._self._c||t)("p",{staticClass:"demo"},[this._v("\n "+this._s(this.msg)+"\n")])}),[],!1,null,null,null);s.default=a.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/8.3a1d618b.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[8],{427:function(t,n,e){"use strict";e.r(n);var s=e(28),i=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("p",{staticClass:"demo"},[this._v("This is another component")])}),[],!1,null,null,null);n.default=i.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/9.ea5777ec.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[9],{375:function(t,n,s){"use strict";s.r(n);var e={data:function(){return{msg:"Hello this is "}}},i=s(28),o=Object(i.a)(e,(function(){var t=this.$createElement;return(this._self._c||t)("p",{staticClass:"demo"},[this._v("\n "+this._s(this.msg)+"\n")])}),[],!1,null,null,null);n.default=o.exports}}]); -------------------------------------------------------------------------------- /docs/img/MDN-Graphics-inherited-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/MDN-Graphics-inherited-3.png -------------------------------------------------------------------------------- /docs/img/MDN-Graphics-instantiation-2-fixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/MDN-Graphics-instantiation-2-fixed.png -------------------------------------------------------------------------------- /docs/img/MDN-Graphics-instantiation-teacher-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/MDN-Graphics-instantiation-teacher-3.png -------------------------------------------------------------------------------- /docs/img/MDN-Graphics-person-person-object-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/MDN-Graphics-person-person-object-2.png -------------------------------------------------------------------------------- /docs/img/Periodic-Table-of-HTML-Elements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/Periodic-Table-of-HTML-Elements.png -------------------------------------------------------------------------------- /docs/img/array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/array.png -------------------------------------------------------------------------------- /docs/img/bean.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/bean.gif -------------------------------------------------------------------------------- /docs/img/beautify.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/beautify.PNG -------------------------------------------------------------------------------- /docs/img/busqueda.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/busqueda.webp -------------------------------------------------------------------------------- /docs/img/cafe-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/cafe-1.JPG -------------------------------------------------------------------------------- /docs/img/cafe-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/cafe-2.JPG -------------------------------------------------------------------------------- /docs/img/caja-git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/caja-git.png -------------------------------------------------------------------------------- /docs/img/checkout-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/checkout-1.JPG -------------------------------------------------------------------------------- /docs/img/conflicto-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/conflicto-2.JPG -------------------------------------------------------------------------------- /docs/img/context-props.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/context-props.png -------------------------------------------------------------------------------- /docs/img/display2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/display2.png -------------------------------------------------------------------------------- /docs/img/entidad-relacion-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/entidad-relacion-2.JPG -------------------------------------------------------------------------------- /docs/img/error-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/error-1.JPG -------------------------------------------------------------------------------- /docs/img/estructura-html5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/estructura-html5.jpg -------------------------------------------------------------------------------- /docs/img/execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/execution.png -------------------------------------------------------------------------------- /docs/img/feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/feature.png -------------------------------------------------------------------------------- /docs/img/fn-0.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-0.JPG -------------------------------------------------------------------------------- /docs/img/fn-10.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-10.JPG -------------------------------------------------------------------------------- /docs/img/fn-11.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-11.JPG -------------------------------------------------------------------------------- /docs/img/fn-12.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-12.JPG -------------------------------------------------------------------------------- /docs/img/fn-20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-20.jpg -------------------------------------------------------------------------------- /docs/img/fn-21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-21.jpg -------------------------------------------------------------------------------- /docs/img/fn-30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-30.jpg -------------------------------------------------------------------------------- /docs/img/fn-31.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/fn-31.JPG -------------------------------------------------------------------------------- /docs/img/git-flujo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/git-flujo.png -------------------------------------------------------------------------------- /docs/img/git-merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/git-merge.gif -------------------------------------------------------------------------------- /docs/img/git-vscode.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/git-vscode.JPG -------------------------------------------------------------------------------- /docs/img/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/git.png -------------------------------------------------------------------------------- /docs/img/github-page.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/github-page.JPG -------------------------------------------------------------------------------- /docs/img/hell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/hell.jpg -------------------------------------------------------------------------------- /docs/img/html-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/html-1.png -------------------------------------------------------------------------------- /docs/img/html-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/html-2.png -------------------------------------------------------------------------------- /docs/img/html-2021-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/html-2021-2.jpg -------------------------------------------------------------------------------- /docs/img/html-2021.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/html-2021.jpg -------------------------------------------------------------------------------- /docs/img/indentar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/indentar.gif -------------------------------------------------------------------------------- /docs/img/javascript.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/javascript.gif -------------------------------------------------------------------------------- /docs/img/joins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/joins.png -------------------------------------------------------------------------------- /docs/img/js-gif-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/js-gif-1.gif -------------------------------------------------------------------------------- /docs/img/js-gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/js-gif.gif -------------------------------------------------------------------------------- /docs/img/null.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/null.PNG -------------------------------------------------------------------------------- /docs/img/objetos-1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/objetos-1.PNG -------------------------------------------------------------------------------- /docs/img/objetos-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/objetos-2.png -------------------------------------------------------------------------------- /docs/img/person-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/person-diagram.png -------------------------------------------------------------------------------- /docs/img/power-config.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/power-config.JPG -------------------------------------------------------------------------------- /docs/img/programar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/programar.gif -------------------------------------------------------------------------------- /docs/img/promesa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/promesa.gif -------------------------------------------------------------------------------- /docs/img/proto1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/proto1.png -------------------------------------------------------------------------------- /docs/img/proto2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/proto2.png -------------------------------------------------------------------------------- /docs/img/pseint-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-1.JPG -------------------------------------------------------------------------------- /docs/img/pseint-10.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-10.JPG -------------------------------------------------------------------------------- /docs/img/pseint-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-2.JPG -------------------------------------------------------------------------------- /docs/img/pseint-3.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-3.JPG -------------------------------------------------------------------------------- /docs/img/pseint-4.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-4.JPG -------------------------------------------------------------------------------- /docs/img/pseint-5.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-5.JPG -------------------------------------------------------------------------------- /docs/img/pseint-6.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-6.JPG -------------------------------------------------------------------------------- /docs/img/pseint-7.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-7.JPG -------------------------------------------------------------------------------- /docs/img/pseint-8.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-8.JPG -------------------------------------------------------------------------------- /docs/img/pseint-9.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/pseint-9.JPG -------------------------------------------------------------------------------- /docs/img/repo-github.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/repo-github.JPG -------------------------------------------------------------------------------- /docs/img/reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/reset.png -------------------------------------------------------------------------------- /docs/img/revert.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/img/scaner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/scaner.gif -------------------------------------------------------------------------------- /docs/img/selector.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/selector.gif -------------------------------------------------------------------------------- /docs/img/sitio-css-1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/sitio-css-1.PNG -------------------------------------------------------------------------------- /docs/img/todo-relaciones.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/todo-relaciones.JPG -------------------------------------------------------------------------------- /docs/img/valor-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/valor-2.png -------------------------------------------------------------------------------- /docs/img/valor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/valor.png -------------------------------------------------------------------------------- /docs/img/velocidad-n1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/velocidad-n1.PNG -------------------------------------------------------------------------------- /docs/img/vsc-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/vsc-1.png -------------------------------------------------------------------------------- /docs/img/vscode-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/vscode-2.png -------------------------------------------------------------------------------- /docs/img/vscode-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/vscode-3.png -------------------------------------------------------------------------------- /docs/img/vscode-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/vscode-4.png -------------------------------------------------------------------------------- /docs/img/vscode-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/vscode-5.png -------------------------------------------------------------------------------- /docs/img/vscode-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/docs/img/vscode-6.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d-w-update", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "authors": { 7 | "name": "", 8 | "email": "" 9 | }, 10 | "repository": "/d-w-update", 11 | "scripts": { 12 | "dev": "vuepress dev src", 13 | "build": "vuepress build src" 14 | }, 15 | "license": "MIT", 16 | "devDependencies": { 17 | "@vuepress/plugin-back-to-top": "^1.8.2", 18 | "vuepress": "^1.5.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/.vuepress/components/Foo/Bar.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /src/.vuepress/components/OtherComponent.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/.vuepress/components/demo-component.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /src/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: "HTML, CSS y Bootstrap 5 (bluuweb)", 3 | dest: "docs", 4 | base: "/desarrollo-web-bluuweb/", 5 | description: 6 | "Curso de HTML, CSS y Bootstrap 5, Docente: Ignacio Gutiérrez (bluuweb), plataforma: Udemy", 7 | head: [ 8 | ["meta", { name: "theme-color", content: "#3eaf7c" }], 9 | ["meta", { name: "apple-mobile-web-app-capable", content: "yes" }], 10 | [ 11 | "meta", 12 | { name: "apple-mobile-web-app-status-bar-style", content: "black" }, 13 | ], 14 | ], 15 | themeConfig: { 16 | editLinks: false, 17 | editLinkText: "", 18 | lastUpdated: "Last Updated", 19 | smoothScroll: true, 20 | nav: [ 21 | // { 22 | // text: "Guía", 23 | // link: "/", 24 | // }, 25 | // { text: 'Guia', link: '/docs/' }, 26 | { 27 | text: "Youtube", 28 | link: "https://youtube.com/bluuweb", 29 | }, 30 | { 31 | text: "Twitch", 32 | link: "https://www.twitch.tv/bluuweb", 33 | }, 34 | { 35 | text: "Ver curso en Udemy", 36 | link: "https://curso-bootstrap-5-udemy.bluuweb.cl", 37 | }, 38 | { 39 | text: "Curso Vue.js", 40 | link: "https://curso-vue-js-udemy.bluuweb.cl", 41 | }, 42 | { 43 | text: "Curso React.js", 44 | link: "https://curso-react-js-udemy.bluuweb.cl", 45 | }, 46 | ], 47 | sidebar: [ 48 | "/", 49 | "/01-html/", 50 | "/02-html-intermedio/", 51 | "/03-css/", 52 | "/04-css-intermedio/", 53 | "/05-flexbox/", 54 | "/06-flexbox-practica/", 55 | "/07-00-terminal/", 56 | "/07-01-git/", 57 | "/07-02-github/", 58 | "/07-b-fundamentos/", 59 | "/08-b-componentes/", 60 | // "/09-b-accordion/", 61 | "/10-b-scroll/", 62 | "/11-b-form/", 63 | "/12-b-sass/", 64 | "/14-b-range/", 65 | "/13-b-chat/", 66 | "/15-b-php/", 67 | // "/16-b-parsel/", 68 | "/17-b-offcanvas/", 69 | "/11-01-psint/", 70 | "/11-02-js-basico/", 71 | "/11-03-js/", 72 | "/11-04-js/", 73 | "/11-05-js-dom/", 74 | "/11-06-js-paradigma/", 75 | "/11-07-js-delegacion/", 76 | "/11-08-js-form/", 77 | "/11-09-js-promesas/", 78 | "/11-10-js-fetch/", 79 | "/11-11-js-poo/", 80 | "/11-12-js-modulos/", 81 | // "/11-13-js-closures/", 82 | "/18-01-react/", 83 | "/18-02-react-formularios/", 84 | "/18-03-react-todo/", 85 | "/18-04-react-api/", 86 | "/18-05-react-router/", 87 | "/18-06-react-context/", 88 | "/19-01-sql/", 89 | "/19-02-sql/", 90 | "/19-03-sql/", 91 | "/19-04-sql/", 92 | "/20-01-node/", 93 | "/20-02-express/", 94 | "/21-03-api-rest/", 95 | "/21-04-mevn/", 96 | ], 97 | }, 98 | 99 | /** 100 | * Apply plugins,ref:https://v1.vuepress.vuejs.org/zh/plugin/ 101 | */ 102 | plugins: ["@vuepress/plugin-back-to-top", "@vuepress/plugin-medium-zoom"], 103 | }; 104 | 105 | { 106 | /* foo */ 107 | } 108 | 109 | { 110 | /* 111 |
112 | icono visual studio code git 113 |
114 | */ 115 | } 116 | -------------------------------------------------------------------------------- /src/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Client app enhancement file. 3 | * 4 | * https://v1.vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements 5 | */ 6 | 7 | export default ({ 8 | Vue, // the version of Vue being used in the VuePress app 9 | options, // the options for the root Vue instance 10 | router, // the router instance for the app 11 | siteData // site metadata 12 | }) => { 13 | // ...apply enhancements for the site. 14 | } 15 | -------------------------------------------------------------------------------- /src/.vuepress/public/img/MDN-Graphics-inherited-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/MDN-Graphics-inherited-3.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/MDN-Graphics-instantiation-2-fixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/MDN-Graphics-instantiation-2-fixed.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/MDN-Graphics-instantiation-teacher-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/MDN-Graphics-instantiation-teacher-3.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/MDN-Graphics-person-person-object-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/MDN-Graphics-person-person-object-2.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/Periodic-Table-of-HTML-Elements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/Periodic-Table-of-HTML-Elements.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/array.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/bean.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/bean.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/beautify.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/beautify.PNG -------------------------------------------------------------------------------- /src/.vuepress/public/img/busqueda.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/busqueda.webp -------------------------------------------------------------------------------- /src/.vuepress/public/img/cafe-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/cafe-1.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/cafe-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/cafe-2.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/caja-git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/caja-git.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/checkout-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/checkout-1.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/conflicto-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/conflicto-2.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/context-props.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/context-props.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/display2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/display2.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/entidad-relacion-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/entidad-relacion-2.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/error-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/error-1.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/estructura-html5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/estructura-html5.jpg -------------------------------------------------------------------------------- /src/.vuepress/public/img/execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/execution.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/feature.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-0.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-0.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-10.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-10.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-11.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-11.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-12.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-12.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-20.jpg -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-21.jpg -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-30.jpg -------------------------------------------------------------------------------- /src/.vuepress/public/img/fn-31.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/fn-31.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/git-flujo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/git-flujo.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/git-merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/git-merge.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/git-vscode.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/git-vscode.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/git.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/github-page.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/github-page.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/hell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/hell.jpg -------------------------------------------------------------------------------- /src/.vuepress/public/img/html-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/html-1.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/html-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/html-2.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/html-2021-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/html-2021-2.jpg -------------------------------------------------------------------------------- /src/.vuepress/public/img/html-2021.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/html-2021.jpg -------------------------------------------------------------------------------- /src/.vuepress/public/img/indentar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/indentar.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/javascript.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/javascript.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/joins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/joins.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/js-gif-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/js-gif-1.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/js-gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/js-gif.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/null.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/null.PNG -------------------------------------------------------------------------------- /src/.vuepress/public/img/objetos-1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/objetos-1.PNG -------------------------------------------------------------------------------- /src/.vuepress/public/img/objetos-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/objetos-2.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/person-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/person-diagram.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/power-config.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/power-config.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/programar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/programar.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/promesa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/promesa.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/proto1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/proto1.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/proto2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/proto2.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-1.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-10.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-10.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-2.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-3.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-3.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-4.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-4.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-5.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-5.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-6.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-6.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-7.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-7.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-8.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-8.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/pseint-9.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/pseint-9.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/repo-github.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/repo-github.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/reset.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/scaner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/scaner.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/selector.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/selector.gif -------------------------------------------------------------------------------- /src/.vuepress/public/img/sitio-css-1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/sitio-css-1.PNG -------------------------------------------------------------------------------- /src/.vuepress/public/img/todo-relaciones.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/todo-relaciones.JPG -------------------------------------------------------------------------------- /src/.vuepress/public/img/valor-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/valor-2.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/valor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/valor.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/velocidad-n1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/velocidad-n1.PNG -------------------------------------------------------------------------------- /src/.vuepress/public/img/vsc-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/vsc-1.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/vscode-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/vscode-2.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/vscode-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/vscode-3.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/vscode-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/vscode-4.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/vscode-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/vscode-5.png -------------------------------------------------------------------------------- /src/.vuepress/public/img/vscode-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/.vuepress/public/img/vscode-6.png -------------------------------------------------------------------------------- /src/.vuepress/styles/index.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom Styles here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/config/#index-styl 5 | */ 6 | 7 | .home .hero img 8 | max-width 450px!important 9 | 10 | h1 { 11 | text-align: center; 12 | } 13 | 14 | .ancla-btn { 15 | display: inline-block; 16 | margin-top: 20px; 17 | } 18 | 19 | .text-center { 20 | text-align: center; 21 | } 22 | 23 | .embed-container { 24 | position: relative; 25 | padding-bottom: 56.25%; 26 | height: 0; 27 | overflow: hidden; 28 | } 29 | .embed-container iframe { 30 | position: absolute; 31 | top:0; 32 | left: 0; 33 | width: 100%; 34 | height: 100%; 35 | } 36 | -------------------------------------------------------------------------------- /src/.vuepress/styles/palette.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom palette here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/zh/config/#palette-styl 5 | */ 6 | 7 | $accentColor = #FF4700 8 | $textColor = #2c3e50 9 | $borderColor = #eaecef 10 | $codeBgColor = #282c34 11 | -------------------------------------------------------------------------------- /src/02-html-intermedio/README.md: -------------------------------------------------------------------------------- 1 | # HTML Intermedio 2 | Conozcamos cosas más avanzadas de HTML 3 | 4 | ## Tablas 5 | ```html 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Gato3 añosNegro
Perro1 mesAzul
18 | ``` 19 | 20 | * `
` Comienzo y final de una tabla. 21 | * `` Comienzo y final de una fila. 22 | * `` Contenido de una celda. 23 | 24 | ```html{3-5} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
MascotaEdadColor
Gato3 añosNegro
Perro1 mesAzul
42 | ``` 43 | 44 | * `Mascota` Define la fila de encabezado 45 | 46 | ```html{2-3} 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ... 56 | ``` 57 | 58 | #### Estructurar en partes tablas grandes 59 | ```html{4,10,12,18,31} 60 |
Titulo de la tabla
MascotaEdadColor
61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
Titulo de la tabla
MascotaEdadColor
MascotaEdadColor
Gato3 añosNegro
Perro1 mesAzul
92 | ``` 93 | 94 | #### Combinar 95 | ```html{22} 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
MascotaEdadColor
Gato3 añosNegro
Perro1 mesAzul
RanaDesconocido
121 | ``` 122 | 123 | ```html{18} 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 |
MascotaEdadColor
Gato3 añosNegro
Perro1 mesAzul
Rana2 semanas
149 | ``` 150 | 151 | ## Formularios 152 | [https://developer.mozilla.org/en-US/docs/Learn/Forms/Your_first_form](https://developer.mozilla.org/en-US/docs/Learn/Forms/Your_first_form) 153 | Los formularios web son uno de los principales puntos de interacción entre un usuario y un sitio web o aplicación. Los formularios permiten a los usuarios ingresar datos, que generalmente se envían a un servidor web para su procesamiento y almacenamiento. 154 | 155 | #### form 156 | Define el contenedor para el formulario. Admite algunos atributos específicos para configurar la forma en que se comporta el formulario. Todos sus atributos son opcionales, pero es una práctica estándar establecer siempre al menos los atributos action y method: 157 | ```html 158 |
159 | 160 |
161 | ``` 162 | 163 | #### input 164 | Aquí es donde nuestro usuario puede ingresar datos. Contamos con varios atributos: 165 | * `type` dato que recibirá el input. 166 | * `placeholder` texto de ayuda para el usuario. 167 | * `id` identificador único. 168 | * `name` nombre del input, nos sire para asociar información al dato ingresado por ejemplo:
curso = "texto proporcionado por el usuario" 169 | ```html 170 | 171 | ``` 172 | 173 | #### label 174 | Texto adicional que describe al ``input`` es por esto que cuenta con el atributo ``for`` donde ingresamos el id del ``input``. 175 | ```html 176 | 177 | ``` 178 | 179 | #### button 180 | Es un botón para procesar nuestro formulario es por esto que cuenta con el atributo `submit` 181 | ```html 182 | 183 | ``` 184 | 185 | #### Formulario completo 186 | ```html 187 |
188 | 189 | 190 | 191 |
192 | ``` 193 | 194 | ## Input 195 | Existen diferentes tipos de `input` 196 | [https://www.w3schools.com/tags/tag_input.asp](https://www.w3schools.com/tags/tag_input.asp) 197 | 198 | ```html 199 |
200 | 201 | 202 |
203 | ``` 204 | 205 | ```html 206 | 207 | ``` 208 | 209 | ```html 210 | 213 | ``` 214 | 215 | ```html 216 |
217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 | ``` 225 | 226 | 227 | ```html 228 | 229 | ``` 230 | 231 | ```html 232 | 233 | ``` 234 | 235 | ```html 236 | 237 | 238 | ``` 239 | 240 | ```html 241 | 242 | ``` 243 | 244 | ```html 245 | 246 | ``` 247 | 248 | ```html 249 | 250 | ``` 251 | 252 | ```html 253 | 254 | ``` 255 | 256 | ```html 257 | 258 | ``` 259 | 260 | En la siguiente sección conoceremos los estilos en CSS y hablaremos un poco más sobre los formularios. 261 | -------------------------------------------------------------------------------- /src/05-flexbox/README.md: -------------------------------------------------------------------------------- 1 | # CSS Flexbox 2 | 3 | - [css-tricks](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) 4 | - [Mozilla](https://developer.mozilla.org/es/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) 5 | - [https://cssreference.io/](https://cssreference.io/flexbox/) 6 | 7 | ## Contenedor 8 | 9 | Envolvemos todos nuestros items dentro de un div contenedor, el cual tendrá la clase `display: flex` 10 | 11 | ```html 12 |
13 |
item 1
14 |
item 2
15 |
item 3
16 |
17 | ``` 18 | 19 | ```css 20 | .item { 21 | background-color: #fb7813; 22 | text-align: center; 23 | border: solid; 24 | border-radius: 10px; 25 | margin: 10px; 26 | padding: 10px; 27 | width: 200px; 28 | } 29 | 30 | .border { 31 | border: 2px #000 solid; 32 | } 33 | 34 | .flex-container { 35 | display: flex; 36 | } 37 | ``` 38 | 39 | ## flex-direction 40 | 41 | - row 42 | - row-reverse 43 | - column 44 | - column-reverse 45 | 46 | ```css 47 | .flex-container { 48 | display: flex; 49 | flex-direction: row; 50 | } 51 | ``` 52 | 53 | ## flex-wrap 54 | 55 | - nowrap 56 | - wrap 57 | - wrap-reverse 58 | 59 | Disminuir pantalla para visualizar cambios: 60 | 61 | ```css 62 | .flex-container { 63 | display: flex; 64 | flex-direction: row; 65 | flex-wrap: wrap; 66 | } 67 | ``` 68 | 69 | ## justify-content 70 | 71 | - flex-start 72 | - flex-end 73 | - center 74 | - space-between 75 | - space-around 76 | - space-evenly 77 | 78 | ```css 79 | .flex-container { 80 | display: flex; 81 | flex-direction: row; 82 | flex-wrap: wrap; 83 | justify-content: center; 84 | } 85 | ``` 86 | 87 | ## align-items 88 | 89 | Nos sirve para posicionar verticalmente los elementos si estos tienen alturas diferentes. 90 | 91 | ```css 92 | .h-700 { 93 | height: 700px; 94 | } 95 | 96 | /* Colocar a un item */ 97 | .h-200 { 98 | height: 200px; 99 | } 100 | ``` 101 | 102 | ```html 103 |
104 |
item 1
105 |
item 2
106 |
item 3
107 |
108 | ``` 109 | 110 | - stretch 111 | - flex-start 112 | - flex-end 113 | - center 114 | - baseline 115 | 116 | ```css 117 | .flex-container { 118 | display: flex; 119 | flex-direction: row; 120 | flex-wrap: wrap; 121 | justify-content: center; 122 | align-items: center; 123 | } 124 | ``` 125 | 126 | ## align-content 127 | 128 | No confundir con `aling-items` ya que ahora alineamos todo el contenedor verticalmente. 129 | 130 | - flex-start 131 | - flex-end 132 | - space-between 133 | - space-around 134 | - space-evenly 135 | 136 | ```css 137 | .flex-container { 138 | display: flex; 139 | flex-direction: row; 140 | flex-wrap: wrap; 141 | justify-content: center; 142 | align-items: center; 143 | align-content: flex-end; 144 | } 145 | ``` 146 | 147 | ## Propiedades para los items 148 | 149 | ## order 150 | 151 | ```css 152 | .order-1 { 153 | order: 1; 154 | } 155 | .order-2 { 156 | order: 2; 157 | } 158 | .order-3 { 159 | order: 3; 160 | } 161 | ``` 162 | 163 | ```html 164 |
165 |
item 1
166 |
item 2
167 |
item 3
168 |
169 | ``` 170 | 171 | ## flex-grow 172 | 173 | Si todos los elementos se han establecido en `flex-grow:1`, el espacio restante en el contenedor se distribuirá por igual a todos item. Si uno de los item tiene un valor de 2, el espacio restante ocuparía el doble de espacio que los demás (o lo intentará, al menos). 174 | 175 | :::tip 176 | Sacar el ancho a los item para ver los resultados 177 | ::: 178 | 179 | ```html 180 |
181 |
item 1
182 |
item 2
183 |
item 3
184 |
185 | ``` 186 | 187 | ```css 188 | .flex-grow-1 { 189 | flex-grow: 1; 190 | } 191 | ``` 192 | 193 | Jugar: 194 | 195 | ```html 196 |
197 |
item 1
198 |
item 2
199 |
item 3
200 |
201 | ``` 202 | 203 | ## flex-shrink 204 | 205 | Con `flex-shrink: 0;` hacemos que nuestro item no se reduzca de su tamaño establecido. 206 | 207 | ```css 208 | .flex-shrink-0 { 209 | width: 400px; 210 | flex-shrink: 0; 211 | } 212 | ``` 213 | 214 | ```html 215 |
216 |
item 1
217 |
item 2
218 |
item 3
219 |
220 | ``` 221 | 222 | :::tip 223 | Prueba sacando la clase `flex-wrap: wrap;` 224 | ::: 225 | 226 | Ahora con valor mayor a 0 227 | 228 | ```css 229 | .flex-shrink-0 { 230 | width: 400px; 231 | flex-shrink: 1; 232 | } 233 | ``` 234 | 235 | ## flex-basis 236 | 237 | Obligamos a un item a partir de una proporción determinada: 238 | 239 | ```css 240 | .flex-basis-1 { 241 | flex-basis: 50%; 242 | } 243 | ``` 244 | 245 | ```html 246 |
247 |
item 1
248 |
item 2
249 |
item 3
250 |
251 | ``` 252 | 253 | ## flex 254 | 255 | ```css 256 | .item { 257 | flex: flex-grow | flex-shrink | flex-basis; 258 | } 259 | ``` 260 | 261 | ```css 262 | .flex-1 { 263 | flex: 1; 264 | } 265 | ``` 266 | 267 | ```html 268 |
269 |
item 1
270 |
item 2
271 |
item 3
272 |
273 | 274 |
275 |
item 1
276 |
item 2
277 |
item 3
278 |
279 | ``` 280 | 281 | Otro ejemplo: 282 | 283 | ```css 284 | .flex-1 { 285 | flex: 1 1 300px; 286 | } 287 | ``` 288 | 289 | ## align-self 290 | 291 | Esto permite que se anule la alineación predeterminada (o la especificada por `align-items`) para elementos flexibles individuales. 292 | 293 | - Agregar altura a contendedor 294 | - Agregar un align-items 295 | 296 | ```css 297 | .flex-container { 298 | display: flex; 299 | flex-direction: row; 300 | flex-wrap: wrap; 301 | justify-content: center; 302 | align-items: flex-end; 303 | } 304 | 305 | .aling-self { 306 | align-self: flex-start; 307 | } 308 | ``` 309 | 310 | ```html 311 |
312 |
item 1
313 |
item 2
314 |
item 3
315 |
316 | ``` 317 | 318 | ## Notas 319 | 320 | - [inline-flex](https://altruistas.org/flex-e-inline-flex-de-flex-box-en-css-y-html/) 321 | - [Alinear icono y texto vertical](https://css-tricks.com/when-do-you-use-inline-block/) 322 | 323 | Alinear icono y texto vertical 324 | ```css 325 | .button { 326 | display: inline-flex; 327 | align-items: center; 328 | } 329 | ``` -------------------------------------------------------------------------------- /src/07-00-terminal/README.md: -------------------------------------------------------------------------------- 1 | # Terminal CMD 2 | 3 | Este es un tutorial introductorio al símbolo del sistema (CMD.exe), o consola de Windows o línea de comandos. 4 | 5 | ## Abrir cmd.exe 6 | - Busca la lupa de windows y escribe "cmd", aparecerá un programa llamado "símbolo del sistema" click y wuala 👏 7 | 8 | ## Para qué nos sirve 9 | - Posteriormente vamos a conocer el controlador de versiones "GIT", este trabaja de manera óptima a través de la terminal. 10 | - Además cuando comiences a trabajar con node.js podrás instalar dependencias a través de npm utilizando la terminal. 11 | 12 | ## ¿Cómo funciona? 13 | Una línea de comandos (a menudo también conocida como consola o terminal) es una interfaz basada en texto dentro de un sistema operativo a través de la que los usuarios envían **comandos** al sistema operativo. De esta manera pueden, por ejemplo, **organizarse archivos**, **iniciar programas** o ejecutarse otros comandos que afectan al sistema operativo, al ordenador o a la red. [fuente](https://www.ionos.es/digitalguide/servidores/know-how/comandos-cmd/#:~:text=Una%20l%C3%ADnea%20de%20comandos%20(a%20menudo%20tambi%C3%A9n%20conocida%20como%20consola%20o%20terminal)%20es%20una%20interfaz%20basada%20en%20texto%20dentro%20de%20un%20sistema%20operativo%20a%20trav%C3%A9s%20de%20la%20que%20los%20usuarios%20env%C3%ADan%20comandos%20al%20sistema%20operativo.) 14 | 15 | ## Help 16 | Este comando nos sirve para mostrar una lista de todos los comandos y su definición. 17 | 18 | ```sh 19 | help 20 | ``` 21 | 22 | ```sh 23 | help exit 24 | ``` 25 | 26 | Ejecuta ahora 27 | ```sh 28 | exit 29 | ``` 30 | 31 | mensaje error al escribir en la terminal 32 | 33 | 34 | ## Comandos básicos 35 | - [Lista de comandos](https://www.ionos.es/digitalguide/servidores/know-how/comandos-cmd/#:~:text=derechos%20de%20administrador.-,Fundamentos,-Comando%20CMD) 36 | 37 | ## CD 38 | Muestra el nombre del directorio actual o cambia de directorio 39 | ```sh 40 | cd 41 | ``` 42 | 43 | Si quisieramos viajar a esta ruta: "C:\Users\bluuweb\Desktop\jugando con la terminal" 44 | ```sh 45 | cd Desktop 46 | cd jugando con la terminal 47 | cd "jugando con la terminal" 48 | ``` 49 | 50 | Para retroceder un directorio utiliza 51 | ```sh 52 | cd .. 53 | ``` 54 | 55 | Atajo: 56 | ```sh 57 | cd C:\Users\bluuweb\Desktop\jugando con la terminal 58 | ``` 59 | 60 | :::tip 61 | También en la barra de navegación de la carpeta puedes escribir ``cmd`` y se abrirá la consola con la ruta actual de dicha carpeta. 62 | ::: 63 | 64 | ## DIR 65 | El comando lista el contenido del directorio o carpeta donde te encuentras, mostrando todas las subcarpetas o archivos que tiene. Con este comando podrás saber si el archivo que buscas está ahí o a qué subcarpeta navegar. 66 | 67 | ```sh 68 | dir 69 | ``` 70 | 71 | ## CLS 72 | Limpia la consola. 73 | 74 | ```sh 75 | cls 76 | ``` 77 | 78 | ## MKDIR o MD 79 | Sirve para crear una carpeta 80 | 81 | ```sh 82 | md assets 83 | ``` 84 | 85 | ```sh 86 | mkdir nueva-carpeta 87 | ``` 88 | 89 | ## MOVE 90 | Podemos mover archivos a otras carpetas 91 | ```sh 92 | move app.js assets 93 | ``` 94 | 95 | En caso de mover a otro directorio utilizar comillas dobles "C:\Users\bluuweb\Desktop" 96 | ```sh 97 | move index.html "C:\Users\bluuweb\Desktop" 98 | ``` 99 | 100 | ## CTRL + C 101 | A veces necesitamos terminar con una ejecución, este comando es muy útil. 102 | 103 | ## PowerShell 104 | Diferencias: 105 | 106 | Necesitamos las comillas si la carpeta tiene espacios: 107 | ```cd 108 | cd "jugando con la terminal" 109 | ``` 110 | 111 | Podemos utilizar `mv` o `move` para mover carpetas: 112 | ```sh 113 | mv prueba nueva-carpeta 114 | ``` 115 | 116 | Podemos ver el path o ruta actual con: 117 | ```sh 118 | pwd 119 | ``` 120 | 121 | Crear archivos 122 | ```sh 123 | ni index.html 124 | ``` 125 | 126 | ## VSCode 127 | Visual Studio Code tiene una opción para abrir una terminal integrada, la gracia es que nos deja en el directorio del proyecto, muy útil para poder trabajar posteriormente con git o npm. 128 | 129 | configurar powershell en vscode -------------------------------------------------------------------------------- /src/07-01-git/README.md: -------------------------------------------------------------------------------- 1 | # GIT y Github Fundamentos 2 | 3 | Está guía está diseñada para poder obtener el código del curso de GIT / GITHUB de una forma amigable y en español. 4 | 5 | ## Enlaces 6 | - [Instalar Git](https://git-scm.com/) 7 | - [Github](https://github.com/) 8 | 9 | ## ¿Qué es GIT? 10 | Es un software de control de versiones, su propósito es llevar registro de los cambios en archivos de computadora y coordinar el trabajo que varias personas realizan sobre archivos compartidos (También puedes trabajar solo no hay problema :)). Existe la posibilidad de trabajar de forma remota y una opción es GitHub. 11 | 12 | ## ¿Para qué usar GIT? 13 | - Permite regresar a versiones anteriores de forma sencilla y muy rápida. 14 | - Facilita el trabajo colaborativo. 15 | - Permite respaldar tus proyectos en la nube (ej con github). 16 | - Reduce considerablemente los tiempos de deploy. 17 | - Las "branches" o ramas, permiten trabajar con una base de código paralela al proyecto en sí. 18 | - [Fuente](https://blog.coffeedevs.com/8-razones-para-usar-git/) 19 | 20 | ### Flujo de trabajo de GIT 21 |
22 |
23 | flujo git 24 | 25 | [Fuente](https://medium.com/nerd-for-tech/a-non-scary-introduction-to-the-wondrous-world-of-git-eb213643a4e8) 26 | 27 |
28 |
29 | flujo git 30 | 31 |
32 | 33 | :::tip 34 | Tus proyectos vinculados a git serán un repositorio 35 | ::: 36 | 37 | **Tratando de explicar la imagen:** Tenemos nuestro directorio local (una carpeta en nuestro pc) con muchos archivos, Git nos irá registrando los cambios de archivos o códigos cuando nosotros le indiquemos, así podremos viajar en el tiempo retrocediendo cambios o restaurando versiones de código, ya sea en Local o de forma Remota (servidor externo). En la práctica quedará más claro. 38 | 39 | ## ¿Qué es GitHub? 40 | Es una plataforma de desarrollo colaborativo para alojar proyectos (en la nube) utilizando el sistema de control de versiones Git, Además cuenta con una herramienta muy útil que es GitHub Pages donde podemos publicar nuestros proyectos estáticos (HTML, CSS y JS) gratis. 41 | 42 | ## Fundamentos de GIT 43 | En este apartado podrás comenzar a trabajar con git. 44 | 45 | ## Comandos básicos 46 | Aprendamos los primeros comandos con git 47 | 48 | ### Versión de git 49 | ``` js 50 | git version 51 | ``` 52 | 53 | ### Registrar nuevo usuario asociado a git: 54 | 55 | :::warning 56 | **No colocar como nombre de usuario** el correo de su cuenta de Github, podría traer problemas a futuro. 57 | ::: 58 | 59 | ```js 60 | git config --global user.name "mi nombre" 61 | ``` 62 | 63 | Es recomendable utilizar el correo asociado a Github 64 | ```js 65 | git config --global user.email "myemail@example.com" 66 | ``` 67 | 68 | ```js 69 | git config user.name 70 | git config user.email 71 | ``` 72 | 73 | ### Ayuda 74 | ``` js 75 | // Ayuda sobre los comandos 76 | git help 77 | ``` 78 | 79 | ### Mi primer repositorio 80 | ``` js 81 | // Iniciar un nuevo repositorio 82 | // Crear la carpeta oculta .git 83 | // Solo se ejecuta una vez por proyecto 84 | git init 85 | ``` 86 | 87 | ``` js 88 | // Ver que archivos no han sido registrados 89 | git status -s 90 | ``` 91 | 92 | ``` js 93 | // Agregar todos los archivos para que esté pendiente de los cambios 94 | git add . 95 | ``` 96 | 97 |
98 | add archivos git 99 |
100 | 101 | ``` js 102 | // Crear commit (fotografía del proyecto en ese momento) 103 | git commit -m "primer commit" 104 | ``` 105 | 106 | ``` js 107 | // Muestra la lista de commit del mas reciente al más antigüo 108 | git log --oneline 109 | ``` 110 | 111 | En resumidas cuentas nosotros realizamos cambios en nuestros archivos, el comando `status` verificará que archivos han sidos modificados. 112 | Cuando deseemos registrar esos cambios tendremos que agregarlos con `add .` así ya estará listo para poder hacer un commit. 113 | El `commit` realiza la copia de ese instante para poder volver en el tiempo si es que es necesario. 114 | 115 | ::: tip Diferencias entre -- y - 116 | `--decorate` hace referencia a una palabra
117 | `-s` hace referencia al comando o a varios comandos, `-sa` serían dos comandos diferentes 118 | ::: 119 | 120 | ``` js 121 | // Vemos información de la rama maestra 122 | git status -s -b 123 | git status -sb //Hace lo mismo que el comando anterior 124 | ``` 125 | 126 | **Vim** es el editor de código en la línea de comandos 127 | 128 | ::: warning Salir del modo edición "Vim" 129 | Para salir del modo edición de la líneas de comando presionar `:q`, en caso de realizar algún cambio sin guardar escribir `:qa`
130 | `:q!` también sirve para salir sin guardar 131 | ::: 132 | 133 | ## VSCode 134 | Visual Studio Code tiene un apartado de Git, el cual de manera visual podemos trabajar. 135 | 136 |
137 | icono visual studio code git 138 |
139 | 140 | ## Github 141 | - [github](https://github.com/) 142 | 143 |
144 |
145 | 146 |
147 | 148 | ## Crear repositorio 149 |
150 | icono visual studio code git 151 |
152 | 153 | ```sh 154 | git remote add origin https://github.com/bluuweb/tutorial-github.git 155 | git push -u origin master 156 | ``` 157 | 158 | Al ejecutar estas líneas de comando te pedirá el usuario y contraseña de tu cuenta de github. 159 | 160 | :::warning 161 | En caso de que no pida las credenciales o bien tengas otra cuenta vinculada, puedes reiniciar con: 162 | - Panel de control -> 163 | - Cuentas de usuario -> 164 | - Administrar credenciales -> 165 | - Credenciales de Windows -> 166 | - Buscar git:https//github.com y quitar 167 | ::: 168 | 169 | ``` js 170 | // Nos muestra en que repositorio estamos enlazados remotamente. 171 | git remote -v 172 | ``` 173 | 174 | ## Push 175 | Para futuros cambios y subir los registros a github ejecutar: 176 | ```sh 177 | git add . 178 | git commit -m "nuevo commit" 179 | git push 180 | ``` 181 | 182 | ## Clonar repositorio 183 | Para descargar un repositorio completo basta con tomar la url ej: `https://github.com/bluuweb/tutorial-github.git` y ejecutar el siguiente comando en alguna carpeta de su computadora. 184 | 185 | ``` 186 | git clone https://github.com/bluuweb/tutorial-github.git nombreCarpeta 187 | ``` 188 | 189 | ## Github pages 190 |
191 |
192 | icono visual studio code git 193 |
-------------------------------------------------------------------------------- /src/09-b-accordion/README.md: -------------------------------------------------------------------------------- 1 | # Accordion 2 | 3 | ## Importante 4 | 5 | - Debes tener las bases de Bootstrap 5 para comenzar con este tutorial, por favor revisar video anterior: [click aquí](https://youtu.be/1kNwZbRiVcQ) 6 | 7 | ## Desafío 8 | - [Revisar aquí](https://accordion-bootstrap-5.netlify.app/) 9 | 10 | 12 | 13 | ## CDN 14 | 15 | - [starter-template](https://getbootstrap.com/docs/5.0/getting-started/introduction/#starter-template) 16 | 17 | ## Header 18 | 19 | ```html 20 |
21 |
22 |
23 |

A simple solution to complex tasks is coming soon

24 |

25 | Say goodbye to inefficient juggling of multiple apps, teams, and 26 | projects. Officelite is the new collaboration platform built with an 27 | intuitive interface to improve productivity. 28 |

29 | 30 |
31 |
Accordion
32 |
33 |
34 | ``` 35 | 36 | ## Componente Accordion 37 | 38 | - [documentación](https://getbootstrap.com/docs/5.0/components/accordion/) 39 | 40 | ```html 41 |
42 |
43 |

44 | 54 |

55 |
61 |
62 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel, libero 63 | earum ipsa rerum ducimus, corporis quae consectetur tempora voluptate 64 | veniam nostrum aperiam quasi voluptatum consequuntur eligendi est illum 65 | error maiores! 66 |
67 |
68 |
69 | 70 |
71 |

72 | 82 |

83 |
89 |
90 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel, libero 91 | earum ipsa rerum ducimus, corporis quae consectetur tempora voluptate 92 | veniam nostrum aperiam quasi voluptatum consequuntur eligendi est illum 93 | error maiores! 94 |
95 |
96 |
97 | 98 |
99 |

100 | 110 |

111 |
117 |
118 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel, libero 119 | earum ipsa rerum ducimus, corporis quae consectetur tempora voluptate 120 | veniam nostrum aperiam quasi voluptatum consequuntur eligendi est illum 121 | error maiores! 122 |
123 |
124 |
125 |
126 | ``` 127 | -------------------------------------------------------------------------------- /src/11-03-js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/11-05-js-dom/app.js: -------------------------------------------------------------------------------- 1 | const carrito = document.querySelector("#carrito"); 2 | const template = document.querySelector("#template"); 3 | const fragment = document.createDocumentFragment(); 4 | const agregar = document.querySelectorAll(".card button"); 5 | 6 | const carritoObjeto = {}; 7 | 8 | const agregarCarrito = (e) => { 9 | // console.log(e.target.dataset); 10 | // console.log(e.target.dataset.fruta); 11 | 12 | const producto = { 13 | titulo: e.target.dataset.fruta, 14 | id: e.target.dataset.fruta, 15 | cantidad: 1, 16 | }; 17 | 18 | if (carritoObjeto.hasOwnProperty(producto.id)) { 19 | producto.cantidad = carritoObjeto[producto.id].cantidad + 1; 20 | } 21 | 22 | carritoObjeto[producto.id] = producto; 23 | 24 | pintarCarrito(); 25 | }; 26 | 27 | agregar.forEach((boton) => boton.addEventListener("click", agregarCarrito)); 28 | 29 | const pintarCarrito = () => { 30 | carrito.textContent = ""; 31 | 32 | Object.values(carritoObjeto).forEach((item) => { 33 | const clone = template.content.cloneNode(true); 34 | clone.querySelector(".lead").textContent = item.titulo; 35 | clone.querySelector(".rounded-pill").textContent = item.cantidad; 36 | fragment.appendChild(clone); 37 | }); 38 | carrito.appendChild(fragment); 39 | }; 40 | -------------------------------------------------------------------------------- /src/11-05-js-dom/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Carrito Objeto 9 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 |
Frutilla 🍓
21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 |
Banana 🍌
29 | 30 |
31 |
32 |
33 |
34 |
35 |
36 |
Manzana 🍏
37 | 38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 |
    46 | 50 |
51 |
52 | 53 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/11-06-js-paradigma/app.js: -------------------------------------------------------------------------------- 1 | const carrito = document.querySelector("#carrito"); 2 | const template = document.querySelector("#template"); 3 | const fragment = document.createDocumentFragment(); 4 | const carritoArray = []; 5 | 6 | // Delegación de eventos: 7 | document.addEventListener("click", (e) => { 8 | // console.log(e); 9 | // console.log(e.target.dataset.fruta); 10 | // console.log(e.target.matches(".card button")); 11 | if (e.target.matches(".card button")) { 12 | agregarCarrito(e); 13 | } 14 | 15 | // console.log(e.target.matches(".list-group-item .btn-success")); 16 | if (e.target.matches(".list-group-item .btn-success")) { 17 | btnAumentar(e); 18 | } 19 | 20 | // console.log(e.target.matches(".list-group-item .btn-danger")); 21 | if (e.target.matches(".list-group-item .btn-danger")) { 22 | btnDisminuir(e); 23 | } 24 | }); 25 | 26 | const agregarCarrito = (e) => { 27 | const producto = { 28 | titulo: e.target.dataset.fruta, 29 | id: e.target.dataset.fruta, 30 | cantidad: 1, 31 | }; 32 | 33 | // buscamos el indice 34 | const index = carritoArray.findIndex((item) => item.id === producto.id); 35 | 36 | // si no existe empujamos el nuevo elemento 37 | if (index === -1) { 38 | carritoArray.push(producto); 39 | } else { 40 | // en caso contrario aumentamos su cantidad 41 | carritoArray[index].cantidad++; 42 | } 43 | 44 | // console.log(carritoArray); 45 | 46 | pintarCarrito(carritoArray); 47 | }; 48 | 49 | const pintarCarrito = (nuevoCarrito) => { 50 | carrito.textContent = ""; 51 | 52 | // recorremos el carrito y pintamos elementos: 53 | nuevoCarrito.forEach((item) => { 54 | const clone = template.content.cloneNode(true); 55 | clone.querySelector(".lead").textContent = item.titulo; 56 | clone.querySelector(".rounded-pill").textContent = item.cantidad; 57 | clone.querySelector(".btn-success").dataset.id = item.id; 58 | clone.querySelector(".btn-danger").dataset.id = item.id; 59 | fragment.appendChild(clone); 60 | }); 61 | carrito.appendChild(fragment); 62 | }; 63 | 64 | const btnAumentar = (e) => { 65 | console.log(e.target.dataset.id); 66 | const nuevoArray = carritoArray.map((item) => { 67 | if (item.id === e.target.dataset.id) { 68 | item.cantidad++; 69 | } 70 | return item; 71 | }); 72 | pintarCarrito(nuevoArray); 73 | }; 74 | 75 | const btnDisminuir = (e) => { 76 | console.log(e.target.dataset.id); 77 | const nuevoArray = carritoArray.filter((item) => { 78 | if (item.id === e.target.dataset.id) { 79 | item.cantidad--; 80 | if (item.cantidad !== 0) { 81 | return item; 82 | } 83 | } else { 84 | return item; 85 | } 86 | }); 87 | pintarCarrito(nuevoArray); 88 | }; 89 | -------------------------------------------------------------------------------- /src/11-06-js-paradigma/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Carrito Objeto 9 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 |
Frutilla 🍓
21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 |
Banana 🍌
29 | 30 |
31 |
32 |
33 |
34 |
35 |
36 |
Manzana 🍏
37 | 38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 |
    46 |
    47 | 48 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/11-07-js-delegacion/app.js: -------------------------------------------------------------------------------- 1 | const carrito = document.querySelector("#carrito"); 2 | const template = document.querySelector("#template"); 3 | const footer = document.querySelector("#footer"); 4 | const templateFooter = document.querySelector("#templateFooter"); 5 | const fragment = document.createDocumentFragment(); 6 | let carritoArray = []; 7 | 8 | // Delegación de eventos: 9 | document.addEventListener("click", (e) => { 10 | // console.log(e); 11 | // console.log(e.target.dataset.fruta); 12 | // console.log(e.target.matches(".card button")); 13 | if (e.target.matches(".card button")) { 14 | agregarCarrito(e); 15 | } 16 | 17 | // console.log(e.target.matches(".list-group-item .btn-success")); 18 | if (e.target.matches(".list-group-item .btn-success")) { 19 | btnAumentar(e); 20 | } 21 | 22 | // console.log(e.target.matches(".list-group-item .btn-danger")); 23 | if (e.target.matches(".list-group-item .btn-danger")) { 24 | btnDisminuir(e); 25 | } 26 | }); 27 | 28 | const agregarCarrito = (e) => { 29 | // console.log(e.target.dataset); 30 | const producto = { 31 | titulo: e.target.dataset.fruta, 32 | id: e.target.dataset.fruta, 33 | cantidad: 1, 34 | precio: parseInt(e.target.dataset.precio), 35 | }; 36 | 37 | // buscamos el indice 38 | const index = carritoArray.findIndex((item) => item.id === producto.id); 39 | 40 | // si no existe empujamos el nuevo elemento 41 | if (index === -1) { 42 | carritoArray.push(producto); 43 | } else { 44 | // en caso contrario aumentamos su cantidad 45 | carritoArray[index].cantidad++; 46 | } 47 | 48 | // console.log(carritoArray); 49 | pintarCarrito(); 50 | }; 51 | 52 | const pintarCarrito = () => { 53 | carrito.textContent = ""; 54 | 55 | // recorremos el carrito y pintamos elementos: 56 | carritoArray.forEach((item) => { 57 | const clone = template.content.cloneNode(true); 58 | clone.querySelector(".text-white .lead").textContent = item.titulo; 59 | clone.querySelector(".rounded-pill").textContent = item.cantidad; 60 | clone.querySelector("div .lead span").textContent = 61 | item.precio * item.cantidad; 62 | clone.querySelector(".btn-success").dataset.id = item.id; 63 | clone.querySelector(".btn-danger").dataset.id = item.id; 64 | fragment.appendChild(clone); 65 | }); 66 | carrito.appendChild(fragment); 67 | 68 | pintarFooter(); 69 | }; 70 | 71 | const pintarFooter = () => { 72 | footer.textContent = ""; 73 | 74 | const total = carritoArray.reduce( 75 | (acc, current) => acc + current.precio * current.cantidad, 76 | 0 77 | ); 78 | 79 | // console.log(total); 80 | 81 | const clone = templateFooter.content.cloneNode(true); 82 | clone.querySelector("p span").textContent = total; 83 | 84 | // fragment.appendChild(clone); 85 | footer.appendChild(clone); 86 | }; 87 | 88 | const btnAumentar = (e) => { 89 | // console.log(e.target.dataset.id); 90 | carritoArray = carritoArray.map((item) => { 91 | if (item.id === e.target.dataset.id) { 92 | item.cantidad++; 93 | } 94 | return item; 95 | }); 96 | pintarCarrito(); 97 | }; 98 | 99 | const btnDisminuir = (e) => { 100 | // console.log(e.target.dataset.id); 101 | carritoArray = carritoArray.filter((item) => { 102 | // console.log(item); 103 | if (item.id === e.target.dataset.id) { 104 | if (item.cantidad > 0) { 105 | item.cantidad--; 106 | // console.log(item); 107 | if (item.cantidad === 0) return; 108 | return item; 109 | } 110 | } else { 111 | return item; 112 | } 113 | }); 114 | pintarCarrito(); 115 | }; 116 | -------------------------------------------------------------------------------- /src/11-07-js-delegacion/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Carrito Objeto 9 | 11 | 12 | 13 | 14 | 15 |
    16 |
    17 |
    18 |
    19 |
    20 |
    Frutilla 🍓
    21 |

    $300

    22 | 23 |
    24 |
    25 |
    26 |
    27 |
    28 |
    29 |
    Banana 🍌
    30 |

    $100

    31 | 32 |
    33 |
    34 |
    35 |
    36 |
    37 |
    38 |
    Manzana 🍏
    39 |

    $200

    40 | 41 |
    42 |
    43 |
    44 |
    45 |
    46 | 47 |
    48 |
      49 |
      50 | 51 |
      52 | 60 |
      61 | 62 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/11-08-js-form/app.js: -------------------------------------------------------------------------------- 1 | const formulario = document.getElementById("formulario"); 2 | 3 | const userName = document.getElementById("userName"); 4 | const userEmail = document.getElementById("userEmail"); 5 | 6 | const alertSuccess = document.getElementById("alertSuccess"); 7 | const alertName = document.getElementById("alertName"); 8 | const alertEmail = document.getElementById("alertEmail"); 9 | 10 | const regUserName = /^[A-Za-zÑñÁáÉéÍíÓóÚúÜü\s]+$/; 11 | const regUserEmail = /^[a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$/; 12 | 13 | const pintarMensajeExito = () => { 14 | alertSuccess.classList.remove("d-none"); 15 | alertSuccess.textContent = "Mensaje enviado con éxito"; 16 | }; 17 | 18 | const pintarMensajeError = (errores) => { 19 | errores.forEach((item) => { 20 | item.tipo.classList.remove("d-none"); 21 | item.tipo.textContent = item.msg; 22 | }); 23 | }; 24 | 25 | formulario.addEventListener("submit", (e) => { 26 | e.preventDefault(); 27 | 28 | alertSuccess.classList.add("d-none"); 29 | const errores = []; 30 | 31 | // validar nombre 32 | if (!regUserName.test(userName.value) || !userName.value.trim()) { 33 | userName.classList.add("is-invalid"); 34 | 35 | errores.push({ 36 | tipo: alertName, 37 | msg: "Formato no válido campo nombre, solo letras", 38 | }); 39 | } else { 40 | userName.classList.remove("is-invalid"); 41 | userName.classList.add("is-valid"); 42 | alertName.classList.add("d-none"); 43 | } 44 | 45 | // validar email 46 | if (!regUserEmail.test(userEmail.value) || !userEmail.value.trim()) { 47 | userEmail.classList.add("is-invalid"); 48 | 49 | errores.push({ 50 | tipo: alertEmail, 51 | msg: "Escriba un correo válido", 52 | }); 53 | } else { 54 | userEmail.classList.remove("is-invalid"); 55 | userEmail.classList.add("is-valid"); 56 | alertEmail.classList.add("d-none"); 57 | } 58 | 59 | if (errores.length !== 0) { 60 | pintarMensajeError(errores); 61 | return; 62 | } 63 | 64 | console.log("Formulario enviado con éxito"); 65 | pintarMensajeExito(); 66 | }); 67 | -------------------------------------------------------------------------------- /src/11-08-js-form/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Carrito Objeto 8 | 14 | 15 | 16 | 17 |
      18 |

      Formularios

      19 | 20 |
      21 | 31 | 32 |

      33 | 34 | 44 | 45 |

      46 | 47 | 48 |
      49 |
      53 |
      54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/11-09-js-promesas/app.js: -------------------------------------------------------------------------------- 1 | const posts = [ 2 | { 3 | id: 1, 4 | name: "id labore ex et quam laborum", 5 | email: "Eliseo@gardner.biz", 6 | body: 7 | "laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium", 8 | }, 9 | { 10 | id: 2, 11 | name: "quo vero reiciendis velit similique earum", 12 | email: "Jayne_Kuhic@sydney.com", 13 | body: 14 | "est natus enim nihil est dolore omnis voluptatem numquam\net omnis occaecati quod ullam at\nvoluptatem error expedita pariatur\nnihil sint nostrum voluptatem reiciendis et", 15 | }, 16 | { 17 | id: 3, 18 | name: "odio adipisci rerum aut animi", 19 | email: "Nikita@garfield.biz", 20 | body: 21 | "quia molestiae reprehenderit quasi aspernatur\naut expedita occaecati aliquam eveniet laudantium\nomnis quibusdam delectus saepe quia accusamus maiores nam est\ncum et ducimus et vero voluptates excepturi deleniti ratione", 22 | }, 23 | ]; 24 | 25 | // const findPostById = (id) => { 26 | // const post = posts.find((item) => item.id === id); 27 | 28 | // // devolver la promesa 29 | // return new Promise((resolve, reject) => { 30 | // //resolve 31 | // if (post) { 32 | // resolve(post); 33 | // } else { 34 | // reject("No encontrado por id: " + id); 35 | // } 36 | // }); 37 | // }; 38 | 39 | // const findPostById = (id) => 40 | // new Promise((resolve, reject) => { 41 | // setTimeout(() => { 42 | // const post = posts.find((item) => item.id === id); 43 | // post ? resolve(post) : reject("No encontrado por id: " + id); 44 | // }, 2000); 45 | // }); 46 | 47 | // const url = 'https://jsonplaceholder.typicode.com/posts' 48 | 49 | // fetch("https://jsonplaceholder.typicode.com/posts/1") 50 | // .then((res) => res.json()) 51 | // .then((data) => console.log(data)); 52 | 53 | const findPostById = async (id) => { 54 | try { 55 | const res = await fetch( 56 | "https://jsonplaceholder.typicode.com/posts/" + id 57 | ); 58 | const post = await res.json(); 59 | console.log(post); 60 | } catch (error) { 61 | console.log(error); 62 | } 63 | }; 64 | 65 | findPostById(50); 66 | -------------------------------------------------------------------------------- /src/11-09-js-promesas/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Carrito Objeto 8 | 14 | 15 | 16 | 17 |
      18 |

      Callbacks

      19 |
      20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/11-10-js-fetch/app.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", () => { 2 | fetchData(); 3 | }); 4 | 5 | const cards = document.querySelector("#card-dinamica"); 6 | const templateCard = document.querySelector("#template-card").content; 7 | 8 | const fetchData = async () => { 9 | try { 10 | loadingData(true); 11 | 12 | const res = await fetch("https://rickandmortyapi.com/api/character"); 13 | const data = await res.json(); 14 | 15 | pintarDatos(data); 16 | } catch (error) { 17 | console.log(error); 18 | } finally { 19 | loadingData(false); 20 | } 21 | }; 22 | 23 | const loadingData = (estado) => { 24 | const loading = document.querySelector("#loading"); 25 | if (estado) { 26 | loading.classList.remove("d-none"); 27 | } else { 28 | loading.classList.add("d-none"); 29 | } 30 | }; 31 | 32 | const pintarDatos = (data) => { 33 | const fragment = document.createDocumentFragment(); 34 | 35 | cards.textContent = ""; 36 | 37 | data.results.forEach((item) => { 38 | const clone = templateCard.cloneNode(true); 39 | clone.querySelector("h5").textContent = item.name; 40 | clone.querySelector("p").textContent = item.species; 41 | clone.querySelector("img").setAttribute("src", item.image); 42 | 43 | fragment.appendChild(clone); 44 | }); 45 | cards.appendChild(fragment); 46 | }; 47 | -------------------------------------------------------------------------------- /src/11-10-js-fetch/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | Rick and Morty v1 17 | 18 | 19 |
      20 |
      21 | Loading... 22 | 27 |
      28 |
      29 | 46 |
      47 |
      48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/11-11-js-poo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | Rick and Morty v1 17 | 18 | 19 |
      20 |

      Agrega Estudiantes y Profesores

      21 |
      22 | 29 | 36 | 37 | 41 | 42 | 43 |
      44 | 45 |
      46 |
      47 |
      48 |
      49 | 63 | 72 |
      73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/11-11-js-poo/js/app.js: -------------------------------------------------------------------------------- 1 | import { Persona, Estudiante, Profesor } from "./persona.js"; 2 | 3 | const estudiantes = []; 4 | 5 | document.addEventListener("click", (e) => { 6 | if (e.target.dataset.nombre) { 7 | console.log(e.target.dataset.nombre); 8 | if (e.target.matches(".btn-success")) { 9 | estudiantes.map((item) => { 10 | if (item.nombre === e.target.dataset.nombre) { 11 | item.estado = true; 12 | console.log(item); 13 | } 14 | return item; 15 | }); 16 | Persona.pintarPersonaUI(estudiantes, "Estudiantes"); 17 | } 18 | if (e.target.matches(".btn-danger")) { 19 | estudiantes.map((item) => { 20 | if (item.nombre === e.target.dataset.nombre) { 21 | item.estado = false; 22 | console.log(item); 23 | } 24 | return item; 25 | }); 26 | Persona.pintarPersonaUI(estudiantes, "Estudiantes"); 27 | } 28 | } 29 | }); 30 | 31 | const formulario = document.querySelector("#formulario"); 32 | formulario.addEventListener("submit", (e) => { 33 | e.preventDefault(); 34 | const datos = new FormData(formulario); 35 | const [nombre, edad, opcion] = [...datos.values()]; 36 | 37 | // console.log(nombre, edad, opcion); 38 | if (opcion === "Estudiante") { 39 | const estudiante = new Estudiante(nombre, edad); 40 | console.log(estudiante); 41 | estudiante.agregarNuevoEstudiante(); 42 | estudiantes.push(estudiante); 43 | Persona.pintarPersonaUI(estudiantes, "Estudiantes"); 44 | } 45 | if (opcion === "Profesor") { 46 | const profesor = new Profesor(nombre, edad); 47 | console.log(profesor); 48 | profesor.agregarNuevoProfesor(); 49 | } 50 | }); 51 | -------------------------------------------------------------------------------- /src/11-11-js-poo/js/persona.js: -------------------------------------------------------------------------------- 1 | const pintarEstudiante = document.querySelector("#pintarEstudiante"); 2 | const pintarProfesor = document.querySelector("#pintarProfesor"); 3 | const templateEstudiante = document.querySelector("#templateEstudiante") 4 | .content; 5 | const templateProfesor = document.querySelector("#templateProfesor").content; 6 | 7 | class Persona { 8 | constructor(nombre, edad) { 9 | this.nombre = nombre; 10 | this.edad = parseInt(edad); 11 | } 12 | 13 | static pintarPersonaUI(personas, tipo) { 14 | if (tipo === "Estudiantes") { 15 | pintarEstudiante.textContent = ""; 16 | const fragment = document.createDocumentFragment(); 17 | personas.forEach((item) => { 18 | fragment.appendChild(item.agregarNuevoEstudiante()); 19 | }); 20 | pintarEstudiante.appendChild(fragment); 21 | } 22 | if (tipo === "Profesores") { 23 | pintarProfesor.textContent = ""; 24 | const fragment = document.createDocumentFragment(); 25 | personas.forEach((item) => { 26 | fragment.appendChild(item.agregarNuevoProfesor()); 27 | }); 28 | pintarProfesor.appendChild(fragment); 29 | } 30 | } 31 | } 32 | 33 | class Estudiante extends Persona { 34 | #estudiante = "Estudiante"; 35 | #estado = false; 36 | 37 | set estado(estado) { 38 | this.#estado = estado; 39 | } 40 | 41 | agregarNuevoEstudiante() { 42 | const clone = templateEstudiante.cloneNode(true); 43 | clone.querySelector("h5 .text-primary").textContent = this.nombre; 44 | clone.querySelector("h6").textContent = this.#estudiante; 45 | clone.querySelector("p").textContent = this.edad + " años"; 46 | 47 | if (this.#estado) { 48 | clone.querySelector(".badge").className = "badge bg-success"; 49 | clone.querySelector(".btn-success").disabled = true; 50 | clone.querySelector(".btn-danger").disabled = false; 51 | } else { 52 | clone.querySelector(".badge").className = "badge bg-danger"; 53 | clone.querySelector(".btn-success").disabled = false; 54 | clone.querySelector(".btn-danger").disabled = true; 55 | } 56 | clone.querySelector(".badge").textContent = this.#estado 57 | ? "Aprobado" 58 | : "Reprobado"; 59 | 60 | clone.querySelector(".btn-success").dataset.nombre = this.nombre; 61 | clone.querySelector(".btn-danger").dataset.nombre = this.nombre; 62 | 63 | return clone; 64 | } 65 | } 66 | 67 | class Profesor extends Persona { 68 | #profesor = "Profesor"; 69 | 70 | agregarNuevoProfesor() { 71 | const clone = templateProfesor.cloneNode(true); 72 | clone.querySelector("h5").textContent = this.nombre; 73 | clone.querySelector("h6").textContent = this.#profesor; 74 | clone.querySelector("p").textContent = this.edad + " años"; 75 | pintarProfesor.appendChild(clone); 76 | } 77 | } 78 | 79 | export { Persona, Estudiante, Profesor }; 80 | -------------------------------------------------------------------------------- /src/11-12-js-modulos/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | TODO app 17 | 18 | 19 |
      20 |

      TODO

      21 | 22 |
      23 | No deje el Todo vacío 24 |
      25 | 26 |
      27 | 34 | 35 |
      36 | 37 |
      38 | 39 | 49 |
      50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/11-12-js-modulos/js/app.js: -------------------------------------------------------------------------------- 1 | const alert = document.querySelector(".alert"); 2 | const formulario = document.querySelector("#formulario"); 3 | const pintarTodoHTML = document.querySelector("#pintarTodo"); 4 | const templateTodo = document.querySelector("#templateTodo").content; 5 | 6 | let todos = []; 7 | 8 | const procesarFormulario = (e) => { 9 | e.preventDefault(); 10 | alert.classList.add("d-none"); 11 | 12 | const datos = new FormData(formulario); 13 | const [todo] = [...datos.values()]; 14 | 15 | // validación campo vacío 16 | if (!todo.trim()) { 17 | alert.classList.remove("d-none"); 18 | return; 19 | } 20 | 21 | agregarTodo(todo); 22 | pintarTodos(); 23 | }; 24 | 25 | const agregarTodo = (todo) => { 26 | const objetoTodo = { 27 | nombre: todo, 28 | id: `${Date.now()}`, 29 | }; 30 | todos.push(objetoTodo); 31 | }; 32 | 33 | const pintarTodos = () => { 34 | localStorage.setItem("todos", JSON.stringify(todos)); 35 | pintarTodoHTML.textContent = ""; 36 | const fragment = document.createDocumentFragment(); 37 | 38 | todos.forEach((item) => { 39 | const clone = templateTodo.cloneNode(true); 40 | 41 | clone.querySelector(".lead").textContent = item.nombre; 42 | clone.querySelector(".btn-danger").dataset.id = item.id; 43 | 44 | fragment.appendChild(clone); 45 | }); 46 | pintarTodoHTML.appendChild(fragment); 47 | }; 48 | 49 | document.addEventListener("click", (e) => { 50 | if (e.target.matches(".btn-danger")) { 51 | console.log(e.target.dataset.id); 52 | todos = todos.filter((item) => item.id !== e.target.dataset.id); 53 | pintarTodos(); 54 | } 55 | }); 56 | 57 | document.addEventListener("DOMContentLoaded", (e) => { 58 | if (localStorage.getItem("todos")) { 59 | todos = JSON.parse(localStorage.getItem("todos")); 60 | pintarTodos(); 61 | } 62 | }); 63 | 64 | formulario.addEventListener("submit", procesarFormulario); 65 | -------------------------------------------------------------------------------- /src/11-12-js-modulos/js/persona.js: -------------------------------------------------------------------------------- 1 | const sandia = "🍉"; 2 | const banana = "🍌"; 3 | 4 | function guinda() { 5 | console.log("🍒"); 6 | } 7 | 8 | export default () => { 9 | console.log("🍓"); 10 | }; 11 | 12 | export { sandia, banana, guinda }; 13 | -------------------------------------------------------------------------------- /src/11-13-js-closure/README.md: -------------------------------------------------------------------------------- 1 | # JS Closures 2 | - [closures](https://developer.mozilla.org/es/docs/Web/JavaScript/Closures) 3 | - Una clausura o closure es una función que guarda referencias del estado adyacente (ámbito léxico). 4 | - Permite acceder al ámbito de una función exterior desde una función interior. 5 | - En JavaScript, las clausuras se crean cada vez que una función es creada. 6 | 7 | :::tip ¿Quieres apoyar los directos? 😍 8 | Tienes varias jugosas alternativas: 9 | 1. [Suscríbete al canal de Youtube (es gratis) click aquí](https://bit.ly/3kLYAqr) 10 | 2. Si estás viendo un video no olvides regalar un 👍 like y comentario 🙏🏼 11 | 3. También puedes ser miembro del canal de Youtube [click aquí](https://www.youtube.com/channel/UCH7IANkyEcsVW_y1IlpkamQ/join) 12 | 6. Puedes adquirir cursos premium en Udemy 👇🏼👇🏼👇🏼 13 | ¿Quiéres apoyar los directos? 14 | - [Curso de HTML + CSS + Bootstrap 5 + Git y más UDEMY](http://curso-bootstrap-5-udemy.bluuweb.cl) 15 | - [Curso de React + Firebase UDEMY](https://curso-react-js-udemy.bluuweb.cl) 16 | - [Curso Vue.js + Firebase UDEMY](https://curso-vue-js-udemy.bluuweb.cl) 17 | ::: 18 | 19 | ## Recursos 20 | - [video 1](https://www.youtube.com/watch?v=JXG_gQ0OF74&t=1319s) 21 | - [video 2](https://www.youtube.com/watch?v=E6aPTeVujRs) 22 | - [video 3](https://www.youtube.com/watch?v=K6fz_fvQ_jU) 23 | 24 | ## Ámbito léxico 25 | ```js 26 | function iniciar() { 27 | let nombre = "bluuweb"; 28 | } 29 | iniciar(); 30 | 31 | console.log(nombre); 32 | ``` 33 | - La variables por ser una función interna, solo estará disponible dentro del cuerpo de ``iniciar()`` 34 | 35 | ```js 36 | function iniciar() { 37 | let nombre = "bluuweb"; 38 | function mostrarNombre() { 39 | console.log(nombre); 40 | } 41 | mostrarNombre(); 42 | } 43 | 44 | iniciar(); 45 | ``` 46 | - ``mostrarNombre()`` no tiene ninguna variable propia; pero, dado que las funciones internas tienen acceso a las variables de las funciones externas, ``mostrarNombre()`` puede acceder a la variable nombre declarada en la función ``iniciar()``. 47 | - **Este es un ejemplo de ámbito léxico**, el cual describe cómo un analizador sintáctico resuelve los nombres de las variables cuando hay funciones anidadas. 48 | - La palabra léxico hace referencia al hecho de que el ámbito léxico se basa en el lugar donde una variable fue declarada para determinar dónde esta variable estará disponible. 49 | 50 | ```js 51 | function iniciar() { 52 | let nombre = "bluuweb"; 53 | 54 | return function mostrarNombre() { 55 | console.log(nombre); 56 | }; 57 | } 58 | 59 | const iniciarUno = iniciar(); 60 | iniciarUno(); 61 | ``` 62 | 63 | - Si retornamos la función `mostrarNombre()` antes de ejecutarla. 64 | - Parece algo extraño que esto funcione, Normalmente, las variables locales dentro de una función sólo existen mientras dura la ejecución de dicha función. 65 | - ``iniciar()`` termina de ejecutarse, es razonable suponer que no se pueda ya acceder a la variable nombre. 66 | 67 | :::tip ¿Qué pasó aquí? 68 | - La solución a este rompecabezas es que ``mostrarNombre()`` se ha convertido en un closure. 69 | ::: 70 | 71 | Un closure es un tipo especial de objeto que combina dos cosas: 72 | - Una función, y el entorno en que se creó esa función. 73 | - El entorno está formado por las variables locales que estaban dentro del alcance en el momento que se creó el closure. 74 | 75 | ## Emulando métodos privados 76 | Los métodos privados no son sólo útiles para restringir el acceso al código: también proporcionan una poderosa manera de administrar tu espacio de nombres global, evitando que los métodos no esenciales embrollen la interfaz pública de tu código. 77 | 78 | ```js 79 | function makeCounter() { 80 | let privateCounter = 0; 81 | 82 | return { 83 | increment() { 84 | privateCounter++; 85 | }, 86 | decrement() { 87 | privateCounter--; 88 | }, 89 | value() { 90 | return privateCounter; 91 | }, 92 | }; 93 | } 94 | 95 | const counter1 = makeCounter(); 96 | const counter2 = makeCounter(); 97 | 98 | console.log(counter1.value()); 99 | console.log(counter2.value()); 100 | 101 | counter1.increment(); 102 | counter1.increment(); 103 | counter1.increment(); 104 | 105 | counter2.decrement(); 106 | counter2.decrement(); 107 | counter2.decrement(); 108 | 109 | console.log(counter1.value()); 110 | console.log(counter2.value()) 111 | ``` 112 | 113 | - Cada contador es independiente. 114 | - Su entorno es diferente. 115 | - privateCounter tiene una instancia diferente cada vez. 116 | - Utilizar closures de este modo proporciona una serie de beneficios que se asocian normalmente con la programación orientada a objectos, en particular la encapsulación y la ocultación de datos. 117 | 118 | Con funciones de Flecha: 119 | ```js 120 | const crearContador = (num = 0) => ({ 121 | increment() { 122 | num++; 123 | }, 124 | decrement() { 125 | num--; 126 | }, 127 | value() { 128 | return num; 129 | }, 130 | }); 131 | 132 | const counter1 = crearContador(10); 133 | ``` 134 | 135 | - Si bien puedes desarrollar una app sin siquiera saber que estás utilizando closures, el conocer su existencia, definición y uso desbloquea nuevas posibilidades a la hora de crear una solución. 136 | - Closures es uno de esos conceptos que se complican en entender cuando estás empezando, pero hacer el intento de utilizarlos con conocimiento puede permitirte aumentar tus herramientas y avanzar en tu carrera. 137 | - También puede que te lo pregunten como prueba técnica. 138 | - [fuente](https://www.freecodecamp.org/espanol/news/que-es-un-closure-en-javascript/) 139 | 140 | -------------------------------------------------------------------------------- /src/11-13-js-closure/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | TODO app 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/11-13-js-closure/js/app.js: -------------------------------------------------------------------------------- 1 | function makeCounter() { 2 | let privateCounter = 0; 3 | 4 | return { 5 | increment() { 6 | privateCounter++; 7 | }, 8 | decrement() { 9 | privateCounter--; 10 | }, 11 | value() { 12 | return privateCounter; 13 | }, 14 | }; 15 | } 16 | 17 | const crearContador = (num = 0) => ({ 18 | increment() { 19 | num++; 20 | }, 21 | decrement() { 22 | num--; 23 | }, 24 | value() { 25 | return num; 26 | }, 27 | }); 28 | 29 | const counter1 = crearContador(10); 30 | const counter2 = makeCounter(); 31 | 32 | console.log(counter1.value()); 33 | console.log(counter2.value()); 34 | 35 | counter1.increment(); 36 | counter1.increment(); 37 | counter1.increment(); 38 | 39 | counter2.decrement(); 40 | counter2.decrement(); 41 | counter2.decrement(); 42 | 43 | console.log(counter1.value()); 44 | console.log(counter2.value()); 45 | -------------------------------------------------------------------------------- /src/11-b-form/README.md: -------------------------------------------------------------------------------- 1 | # Bootstrap Formulario 2 | 3 | En este apartado veremos un formulario con Bootstrap 5. 4 | 5 | ## Ejemplo 6 | 7 | ```html 8 |
      9 |
      10 | 11 | 18 |
      19 | No compartiremos su correo electrónico. 20 |
      21 |
      22 |
      23 | 24 | 30 |
      31 |
      32 | 38 | 39 |
      40 | 43 | 51 |
      52 | ``` 53 | 54 | ## Javascript 55 | 56 | ```js 57 | console.log("funcionando!"); 58 | 59 | const formulario = document.querySelector("#formulario"); 60 | const btnEnviar = document.querySelector("#btnEnviar"); 61 | const btnCargando = document.querySelector("#btnCargando"); 62 | 63 | formulario.addEventListener("submit", (e) => { 64 | btnEnviar.classList.add("d-none"); 65 | btnCargando.classList.remove("d-none"); 66 | 67 | e.preventDefault(); 68 | const datos = new FormData(formulario); 69 | console.log("email: ", datos.get("campoEmail")); 70 | console.log("password: ", datos.get("campoPassword")); 71 | console.log("aceptar: ", datos.get("campoAceptar")); 72 | 73 | // Enviar datos según sistema de backend 74 | // PHP: https://www.youtube.com/watch?v=nLrL9Ip3tWI 75 | 76 | // Simulación de carga 77 | window.setTimeout(() => { 78 | btnEnviar.classList.remove("d-none"); 79 | btnCargando.classList.add("d-none"); 80 | }, 1000); 81 | }); 82 | ``` 83 | 84 | ## Toast 85 | 86 | ```html 87 | 95 | 96 | 97 | 113 | 114 | ``` 115 | 116 | ```js{7,27-28} 117 | console.log('funcionando!') 118 | 119 | const formulario = document.querySelector('#formulario') 120 | const btnEnviar = document.querySelector('#btnEnviar') 121 | const btnCargando = document.querySelector('#btnCargando') 122 | 123 | const toast = document.querySelector('.toast') 124 | 125 | formulario.addEventListener('submit', e => { 126 | 127 | btnEnviar.classList.add('d-none') 128 | btnCargando.classList.remove('d-none') 129 | 130 | e.preventDefault() 131 | const datos = new FormData(formulario) 132 | console.log('email: ', datos.get('campoEmail')) 133 | console.log('password: ', datos.get('campoPassword')) 134 | console.log('aceptar: ', datos.get('campoAceptar')) 135 | 136 | // Enviar datos según sistema de backend 137 | // PHP: https://www.youtube.com/watch?v=nLrL9Ip3tWI 138 | 139 | window.setTimeout(() => { 140 | btnEnviar.classList.remove('d-none') 141 | btnCargando.classList.add('d-none') 142 | 143 | const eventoToast = new bootstrap.Toast(toast) 144 | eventoToast.show() 145 | 146 | }, 1000) 147 | 148 | }) 149 | ``` 150 | -------------------------------------------------------------------------------- /src/13-b-chat/README.md: -------------------------------------------------------------------------------- 1 | # Chat con Firebase 2 | 3 | - Firebase [documentación](https://firebase.google.com/) 4 | - Agregar Firebase [documentación](https://firebase.google.com/docs/web/setup?authuser=0#add-sdks-initialize) 5 | - Auth con Google [documentación](https://firebase.google.com/docs/auth/web/google-signin?authuser=0) 6 | - Observa cambios entre instantáneas [documentación](https://firebase.google.com/docs/firestore/query-data/listen?authuser=0#view_changes_between_snapshots) 7 | - Reglas [documentación](https://firebase.google.com/docs/firestore/security/rules-structure?authuser=0#basic_readwrite_rules) 8 | - Curso de Javascript Moderno [youtube](https://www.youtube.com/watch?v=Z4TuS0HEJP8&list=PLPl81lqbj-4I2ZOzryjPKxfhK3BzTlaJ7) 9 | - Tutorial de JS [youtube](https://www.youtube.com/watch?v=pnLHUyO96QA&list=PLPl81lqbj-4K4bSaIziJsu3GtCiytRpEL) 10 | 11 | ## HTML 12 | ```html 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Hello, world! 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 45 | 46 | 47 | 58 | 59 |
      60 | 66 |
      67 |
      68 | 69 | 70 |
      71 | 72 | 77 | 78 | 79 | 80 | ``` 81 | 82 | ```scss 83 | @import url('https://fonts.googleapis.com/css2?family=Alata&display=swap'); 84 | // font-family: 'Alata', sans-serif; 85 | $font-family-base: 'Alata', sans-serif; 86 | 87 | 88 | @import "../node_modules/bootstrap/scss/bootstrap"; 89 | 90 | .container-chat { 91 | overflow-y: scroll; 92 | height: calc(100vh - 160px); 93 | } 94 | ``` 95 | 96 | ## JS 97 | ```js 98 | console.log('funcionando!') 99 | 100 | const btnIngreso = document.querySelector('#btnIngreso') 101 | const btnCerrarSesion = document.querySelector('#btnCerrarSesion') 102 | const nombreUsuario = document.querySelector('#nombreUsuario') 103 | const contenidoWeb = document.querySelector('#contenidoWeb') 104 | const texto = document.querySelector('#texto') 105 | const formulario = document.querySelector('#formulario') 106 | 107 | firebase.auth().onAuthStateChanged(user => { 108 | if(user){ 109 | nombreUsuario.innerHTML = user.displayName 110 | accionCerrarSesion() 111 | contenidoChat(user) 112 | }else{ 113 | accionAcceder() 114 | console.log('usuario no registrado') 115 | nombreUsuario.innerHTML = 'Chat' 116 | contenidoWeb.innerHTML = /*html*/` 117 |

      Debes iniciar sesión

      118 | ` 119 | } 120 | }) 121 | 122 | const accionCerrarSesion = () => { 123 | formulario.classList.remove('d-none') 124 | btnCerrarSesion.addEventListener('click', () => firebase.auth().signOut()) 125 | } 126 | 127 | const accionAcceder = () => { 128 | formulario.classList.add('d-none') 129 | btnIngreso.addEventListener('click', async() => { 130 | console.log('entro') 131 | const provider = new firebase.auth.GoogleAuthProvider(); 132 | try { 133 | await firebase.auth().signInWithPopup(provider) 134 | } catch (error) { 135 | console.log(error) 136 | } 137 | }) 138 | } 139 | 140 | const contenidoChat = user => { 141 | 142 | formulario.addEventListener('submit', event => { 143 | event.preventDefault() 144 | console.log(texto.value) 145 | if(!texto.value.trim()){ 146 | console.log('texto vacio') 147 | return 148 | } 149 | firebase.firestore().collection('chat').add({ 150 | texto: texto.value, 151 | uid: user.uid, 152 | fecha: Date.now() 153 | }).then(res => { 154 | console.log('texto agregado') 155 | }) 156 | texto.value = '' 157 | }) 158 | 159 | firebase.firestore().collection('chat').orderBy('fecha') 160 | .onSnapshot(snapshot => { 161 | snapshot.docChanges().forEach((change) => { 162 | if (change.type === "added") { 163 | console.log(change.doc.data()); 164 | console.log(user.uid) 165 | console.log(change.doc.data().uid) 166 | if (user.uid === change.doc.data().uid) { 167 | console.log('entró', change.doc.data().texto) 168 | contenidoWeb.innerHTML += /*html*/` 169 |
      170 | 171 | ${change.doc.data().texto} 172 | 173 |
      174 | ` 175 | }else{ 176 | contenidoWeb.innerHTML += /*html*/` 177 |
      178 | ${change.doc.data().texto} 179 |
      180 | ` 181 | } 182 | contenidoWeb.scrollTop = contenidoWeb.scrollHeight 183 | } 184 | if (change.type === "modified") { 185 | console.log("Modified city: ", change.doc.data()); 186 | } 187 | if (change.type === "removed") { 188 | console.log("Removed city: ", change.doc.data()); 189 | } 190 | }); 191 | }) 192 | } 193 | ``` 194 | 195 | ## Reglas 196 | ``` 197 | rules_version = '2'; 198 | service cloud.firestore { 199 | match /databases/{database}/documents { 200 | match /chat/{doc} { 201 | allow read: if request.auth != null; 202 | allow write: if request.auth != null; 203 | } 204 | } 205 | } 206 | ``` -------------------------------------------------------------------------------- /src/14-b-range/README.md: -------------------------------------------------------------------------------- 1 | # Form Range + JS 2 | Vamos a desarrollar una práctica inspirados en: [FrontendMentor](https://www.frontendmentor.io/challenges/interactive-pricing-component-t0m8PIyY8) 3 | 4 | ## custom.scss 5 | ```scss 6 | @import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.0/font/bootstrap-icons.css"); 7 | 8 | @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@300;500;700&display=swap'); 9 | // font-family: 'Manrope', sans-serif; 10 | 11 | $font-family-base: 'Manrope', sans-serif; 12 | 13 | @import "../node_modules/bootstrap/scss/bootstrap"; 14 | ``` 15 | 16 | ## HTML 17 | ```html 18 | 19 | 20 | 21 | 22 | 23 | 24 | Precios level up 25 | 26 | 27 | 28 |
      29 |
      30 |

      Simple, traffic-based pricing

      31 |

      32 | Sign-up for our 30-day trial. No credit card required. 33 |

      34 |
      35 |
      36 |
      37 |
      38 |
      39 |
      40 |
      41 |

      42 | $ 16.00 43 | / month 44 |

      45 |
      46 |
      49 |

      50 | 100K pageviews 51 |

      52 |
      53 |
      54 | 63 |
      64 |
      65 |
      66 |
      67 |
      68 |
        69 |
      • 70 | 71 | Unlimited websites 72 |
      • 73 |
      • 74 | 75 | 100% updates data ownership 76 |
      • 77 |
      • 78 | 79 | Email report 80 |
      • 81 |
      82 |
      83 |
      84 | 85 |
      86 |
      87 |
      88 |
      89 |
      90 |
      91 |
      92 | 93 | 94 | 95 | 96 | ``` 97 | 98 | ## JS 99 | ```js 100 | console.log('holis') 101 | 102 | const range = document.querySelector('#customRange3') 103 | const views = document.querySelector('#views') 104 | const price = document.querySelector('#price') 105 | const arrayViews = ['10K', '50K', '100K', '500K', '1M'] 106 | 107 | 108 | 109 | range.addEventListener('input', () => { 110 | console.log('me cambiaste 😱') 111 | console.log(range.value) 112 | price.textContent = range.value 113 | views.textContent = arrayViews[(range.value/8 -1)] 114 | }) 115 | ``` -------------------------------------------------------------------------------- /src/15-b-php/README.md: -------------------------------------------------------------------------------- 1 | # Mail PHP 2 | Vamos a configurar un formulario con envío de formulario a través de PHP. 3 | 4 | ## Requisitos 5 | - Hosting con PHP y habilitada la función mail (puede ser hosting compartido) 6 | - Servidor Apache [xampp](https://www.apachefriends.org/es/index.html) 7 | - Clear Cache [Extensión navegador](https://chrome.google.com/webstore/detail/clear-cache/cppjkneekbjaeellbfkmgnhonkkjfpdn?hl=es) 8 | - Estudiar sección de Formularios 👍 9 | 10 | ## HTML 11 | ```html 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | Form PHP 28 | 29 | 30 |
      31 |

      Form PHP

      32 | 33 |
      34 |
      35 | 36 | 43 |
      Looks good!
      44 |
      Escriba un usuario válido
      45 |
      46 |
      47 | 48 | 55 |
      Looks good!
      56 |
      Escriba un correo válido
      57 |
      58 |
      59 | 60 | 67 |
      Looks good!
      68 |
      Escriba un mensaje
      69 |
      70 |
      71 | 72 |
      Mensaje enviado con éxito 🙌
      73 |
      Ocurrió un error de servidor 😱, intentelo más tarde 🙏🏾
      74 |
      75 |
      76 |
      77 | 78 | 83 | 84 | 85 | 86 | 87 | ``` 88 | 89 | ## JS 90 | ```js 91 | // Fetch all the forms we want to apply custom Bootstrap validation styles to 92 | const form = document.getElementById("formulario"); 93 | const usuario = document.getElementById("validationCustom01"); 94 | const correo = document.getElementById("validationCustom02"); 95 | const mensaje = document.getElementById("validationCustom03"); 96 | const boton = document.getElementById("boton"); 97 | 98 | form.addEventListener( 99 | "submit", 100 | function (event) { 101 | event.preventDefault(); 102 | event.stopPropagation(); 103 | 104 | const data = new FormData(form); 105 | 106 | // Validar usuario 107 | if (!data.get("usuario").trim()) { 108 | console.log("campo vacio usuario"); 109 | campoError(usuario); 110 | return 111 | } else { 112 | campoValido(usuario); 113 | } 114 | 115 | // Validar correo 116 | if (!data.get("correo").trim()) { 117 | console.log("campo vacio correo"); 118 | campoError(correo); 119 | return 120 | } else { 121 | campoValido(correo); 122 | } 123 | 124 | // Validar mensaje 125 | if (!data.get("mensaje").trim()) { 126 | console.log(data.get("mensaje")); 127 | campoError(mensaje); 128 | return 129 | } else { 130 | campoValido(mensaje); 131 | } 132 | console.log("todos los campos completados"); 133 | 134 | fetch("formulario.php", { 135 | method: "POST", 136 | body: data, 137 | }) 138 | .then((res) => res.json()) 139 | .then((datos) => { 140 | console.log(datos); 141 | 142 | if (datos.error && datos.campo === "usuario") { 143 | console.log("error con usuario php"); 144 | campoError(usuario); 145 | return; 146 | } 147 | campoValido(usuario); 148 | 149 | if (datos.error && datos.campo === "correo") { 150 | console.log("error con correo php"); 151 | campoError(correo); 152 | return; 153 | } 154 | campoValido(correo); 155 | 156 | if (datos.error && datos.campo === "mensaje") { 157 | console.log("error con mensaje php"); 158 | campoError(mensaje); 159 | return; 160 | } 161 | campoValido(mensaje); 162 | 163 | if (datos.error && datos.campo === 'mail') { 164 | console.log('Existe un error con la función mail de php.') 165 | campoError(boton); 166 | return; 167 | } 168 | 169 | if (!datos.error) { 170 | limpiarFormulario(form); 171 | campoValido(boton) 172 | } 173 | }) 174 | .catch((e) => { 175 | console.log(e) 176 | campoError(boton); 177 | }); 178 | }, 179 | false 180 | ); 181 | 182 | const campoError = (campo) => { 183 | campo.classList.add("is-invalid"); 184 | campo.classList.remove("is-valid"); 185 | }; 186 | 187 | const campoValido = (campo) => { 188 | campo.classList.remove("is-invalid"); 189 | campo.classList.add("is-valid"); 190 | }; 191 | 192 | const limpiarFormulario = (form) => { 193 | console.log("Mensaje enviado con éxito!"); 194 | form.reset(); 195 | correo.classList.remove("is-valid"); 196 | usuario.classList.remove("is-valid"); 197 | mensaje.classList.remove("is-valid"); 198 | }; 199 | ``` 200 | 201 | ## PHP 202 | ```php 203 | true, 231 | 'campo' => 'usuario' 232 | )); 233 | return; 234 | } 235 | 236 | if(empty($correo)){ 237 | echo json_encode(array( 238 | 'error' => true, 239 | 'campo' => 'correo' 240 | )); 241 | return; 242 | } 243 | 244 | if(empty($mensaje)){ 245 | echo json_encode(array( 246 | 'error' => true, 247 | 'campo' => 'mensaje' 248 | )); 249 | return; 250 | } 251 | 252 | // Cuerpo del mensaje 253 | $cuerpo = 'Usuario: ' . $usuario . "
      "; 254 | $cuerpo.= 'Email: ' . $correo . "
      "; 255 | $cuerpo.= 'Mensaje: ' . $mensaje . "
      "; 256 | 257 | // Dirección 258 | $destinatario = 'correoDestino@destino.com'; 259 | $asunto = 'Mensaje de mi sitio web'; 260 | 261 | // Para que acepte correo con HTML 262 | $headers = 'MIME-Version: 1.0' . "\r\n" .'Content-type: text/html; charset=utf-8' . "\r\n" .'From: ' . $correo . "\r\n"; 263 | 264 | if(mail($destinatario, $asunto, $cuerpo, $headers)){ 265 | echo json_encode(array( 266 | 'error' => false, 267 | 'campo' => 'exito' 268 | )); 269 | }else { 270 | echo json_encode(array( 271 | 'error' => true, 272 | 'campo' => 'mail' 273 | )); 274 | } 275 | 276 | 277 | }else { 278 | echo json_encode(array( 279 | 'error' => true, 280 | 'campo' => 'post' 281 | )); 282 | return; 283 | } 284 | ``` 285 | -------------------------------------------------------------------------------- /src/16-b-parsel/README.md: -------------------------------------------------------------------------------- 1 | # Parcel 2 | Veamos una configuración avanzada para trabajar con Parcel.js y NPM de node.js 3 | 4 | ## NPM y parcel 5 | ``` 6 | npm init -y 7 | ``` 8 | 9 | ``` 10 | npm install bootstrap@next 11 | ``` 12 | 13 | ``` 14 | package.json 15 | src 16 | index.html 17 | -css 18 | -custom.scss 19 | -js 20 | -app.js 21 | -assets 22 | -imagen.jpg 23 | ``` 24 | 25 | ## package.json 26 | ```json 27 | "scripts": { 28 | "dev": "parcel src/index.html src/js/app.js src/css/custom.scss src/assets/*", 29 | "build": "parcel build src/index.html src/js/app.js src/css/custom.scss src/assets/* --public-url . -d build/" 30 | }, 31 | ``` 32 | 33 | ## index.html 34 | ```html 35 | 36 | 37 | 38 | 39 | 40 | JS Bootstrap 5! 41 | 42 | 43 | 44 |
      45 | 46 | 49 | 50 | 51 | 68 |
      69 | 70 | 71 | 72 | 73 | ``` 74 | 75 | ## custom.scss 76 | - [sass/#importing](https://getbootstrap.com/docs/5.0/customize/sass/#importing) 77 | ```scss 78 | $primary: rgb(65, 1, 139); 79 | // Todos los estilos 80 | // @import "../../node_modules/bootstrap/scss/bootstrap"; 81 | 82 | // Uno por uno **Recomendado 83 | // Required 84 | @import "../../node_modules/bootstrap/scss/functions"; 85 | @import "../../node_modules/bootstrap/scss/variables"; 86 | @import "../../node_modules/bootstrap/scss/mixins"; 87 | 88 | // Optional 89 | @import "../../node_modules/bootstrap/scss/root"; 90 | @import "../../node_modules/bootstrap/scss/reboot"; 91 | @import "../../node_modules/bootstrap/scss/type"; 92 | @import "../../node_modules/bootstrap/scss/images"; 93 | @import "../../node_modules/bootstrap/scss/containers"; 94 | @import "../../node_modules/bootstrap/scss/grid"; 95 | 96 | @import "../../node_modules/bootstrap/scss/buttons"; 97 | @import "../../node_modules/bootstrap/scss/modal"; 98 | @import "../../node_modules/bootstrap/scss/close"; 99 | ``` 100 | 101 | ## app.js 102 | - [5.0/customize/optimize/](https://getbootstrap.com/docs/5.0/customize/optimize/) 103 | ```js 104 | import 'bootstrap/js/dist/modal'; 105 | ``` 106 | 107 | ## Dev y Build 108 | ``` 109 | npm run dev 110 | ``` 111 | 112 | Cuando finalizamos el proyecto. 113 | ``` 114 | npm run build 115 | ``` 116 | 117 | ## Purge.css 118 | Esto lo vimos la sección anterior [01-fundamentos/#purgecss](https://bluuweb.github.io/bootstrap-5/01-fundamentos/#purgecss) 119 | 120 | :::warning 121 | Me optimiza más de la cuenta, por ende me excluye algunos estilos esenciales, si alguien tiene la solución, por favor compartir 😍 122 | ::: 123 | 124 | ```json 125 | "scripts": { 126 | "build-purge": "purgecss --css build/css/custom.css --content index.html --output build/css/reducido.css" 127 | }, 128 | ``` 129 | 130 | -------------------------------------------------------------------------------- /src/19-01-sql/README.md: -------------------------------------------------------------------------------- 1 | # Bases de datos 2 | 3 | En este capitulo conoceremos los fundamentos de bases de datos trabajadas con MariaDB. 4 | 5 | 6 | 7 | ## ¿Qué es una DB? 8 | 9 | - DB: data base o base de datos. 10 | - Una base de datos es un conjunto de datos pertenecientes a un mismo contexto y almacenados sistemáticamente para su posterior uso. 11 | - Resumen: Guardar y leer datos pero de forma ordenada. 12 | 13 | ## Tipos de bases de datos 14 | 15 | - **Bases de datos relacionales**. 16 | - Bases de datos NoSQL. 17 | - Bases de datos orientadas a objetos. 18 | - Bases de datos distribuidas. 19 | - etc [más info](https://www.oracle.com/cl/database/what-is-database/) 20 | 21 | :::tip Bases de datos relacionales 22 | 23 | - Las bases de datos relacionales se basan en el modelo relacional 24 | - Una forma intuitiva y directa de representar datos en tablas. 25 | - Cada tabla utiliza filas y columnas. 26 | ::: 27 | 28 | :::tip Bases de datos no relacionales 29 | 30 | - noSQL: la información se organiza normalmente mediante documentos y es muy útil cuando no tenemos un esquema exacto de lo que se va a almacenar. 31 | ::: 32 | 33 | ## DBMS 34 | 35 | - Sistema gestor de base de datos (Database Management System). 36 | - Resumen: Software que nos permite gestionar las bases de datos. 37 | - Administrar, acceder, controlar permisos, respaldar, crear informes.etc. 38 | - Este sistema (DBMS) necesita de alguna manera consultar estos datos y para ello una **alternativa** es utilizar SQL. 39 | 40 | ## SQL 41 | 42 | - SQL (Structured Query Language): lenguaje de consulta estructurada, diseñado para administrar, y recuperar información de sistemas de gestión de bases de datos relacionales. 43 | - si un DBMS utiliza SQL sería "Un sistema de gestión de bases de datos relacionales" (RDBMS, por sus siglas en inglés). 44 | - SQL es el lenguaje más común para realizar consultas en base de datos. 45 | 46 | ## Conclusión 47 | 48 | - En RDBMS (software) creas y administras las bases de datos, utilizando SQL para las consultas. 49 | 50 | ## RDBMS populares 51 | 52 | - Oracle 53 | - MySQL 54 | - Microsoft SQL Server 55 | - PostgreSQL 56 | - IBM Db2 57 | - SQLite 58 | - Microsoft Access 59 | - MariaDB 60 | 61 | ## PostgreSQL 62 | 63 | - [postgresql.org](https://www.postgresql.org/) 64 | - PostgreSQL, también llamado Postgres, es un sistema de gestión de bases de datos relacional orientado a objetos y de código abierto, publicado bajo la licencia PostgreSQL, ​ similar a la BSD o la MIT. 65 | - Como muchos otros proyectos de código abierto, el desarrollo de PostgreSQL no es manejado por una empresa o persona, sino que es dirigido por una comunidad de desarrolladores que trabajan de forma desinteresada, altruista, libre o apoyados por organizaciones comerciales. Dicha comunidad es denominada el PGDG (PostgreSQL Global Development Group). 66 | - [descargar](https://www.postgresql.org/download/) 67 | - [doc](https://www.postgresql.org/docs/) 68 | 69 | :::tip 70 | Existen dos maneras de trabajar, una es con SQL Shell y la otra es a través de pgAdmin 4, esta última nos permite hacer todo de manera visual. 71 | ::: 72 | 73 | Comandos de navegación en SQL Shell 74 | 75 | ```sh 76 | \l -> listar DBs 77 | \q -> exit 78 | \c nombreDB -> cambiar de base de datos 79 | \dt -> listar tablas 80 | ``` 81 | 82 | Crear DB 83 | 84 | ```sh 85 | CREATE DATABASE prueba; 86 | \c prueba 87 | ``` 88 | 89 | ## SQL 90 | 91 | - [tipos de datos](http://codigoelectronica.com/blog/postgresql-tipo-de-datos) 92 | - [Data models industry](http://www.databaseanswers.org/data_models/index.htm) 93 | 94 | Diagrama entidad relación: 95 | 96 |
      97 | relacion todo sql 98 |
      99 | 100 | ## CREATE 101 | 102 | ```sql 103 | CREATE TABLE usuarios( 104 | nombre VARCHAR(100) NOT NULL, 105 | edad INT, 106 | descripcion TEXT, 107 | id_usuario SERIAL, 108 | PRIMARY KEY (id_usuario) 109 | ); 110 | 111 | SELECT * FROM usuarios; 112 | ``` 113 | 114 | ```sql 115 | CREATE TABLE tareas( 116 | id_tarea SERIAL PRIMARY KEY, 117 | id_usuario INT NOT NULL, 118 | titulo VARCHAR(50) NOT NULL, 119 | fecha DATE DEFAULT CURRENT_DATE, 120 | estado BOOLEAN DEFAULT false, 121 | FOREIGN KEY (id_usuario) REFERENCES usuarios(id_usuario) 122 | ); 123 | 124 | SELECT * FROM tareas; 125 | ``` 126 | 127 | ## ALTER 128 | 129 | - [más info](https://www.todopostgresql.com/comandos-postgresql-alter/) 130 | 131 | Agregar columna: 132 | 133 | ```sql 134 | ALTER TABLE tareas 135 | ADD descripcion TEXT; 136 | ``` 137 | 138 | Eliminar: 139 | 140 | ```sql 141 | ALTER TABLE tareas 142 | DROP descripcion; 143 | ``` 144 | 145 | Cambiar tipo de dato: 146 | 147 | ```sql 148 | ALTER TABLE tareas 149 | ALTER COLUMN descripcion SET DATA TYPE VARCHAR(500); 150 | ``` 151 | 152 | Cambiar nombre columna: 153 | 154 | ```sql 155 | ALTER TABLE tareas 156 | RENAME COLUMN titulo TO cabecera; 157 | ``` 158 | 159 | ## INSERT 160 | 161 | ```sql 162 | INSERT INTO usuarios(nombre, edad, descripcion) 163 | VALUES ( 164 | 'alex', 165 | 50, 166 | 'me gusta la programación' 167 | ); 168 | ``` 169 | 170 | ```sql 171 | INSERT INTO tareas(id_usuario, titulo) 172 | VALUES ( 173 | 1, 174 | 'Componer una canción' 175 | ); 176 | 177 | SELECT * FROM tareas; 178 | ``` 179 | 180 | ## UPDATE 181 | 182 | ```sql 183 | UPDATE usuarios 184 | SET nombre = 'Felipe 2' 185 | WHERE id_usuario = 3; 186 | ``` 187 | 188 | ## DELETE 189 | 190 | ```sql 191 | DELETE FROM usuarios 192 | WHERE id_usuario = 3; 193 | ``` 194 | 195 | :::warning 196 | ERROR: update o delete en «usuarios» viola la llave foránea «tareas_id_usuario_fkey» en la tabla «tareas» 197 | 198 | DETAIL: La llave (id_usuario)=(2) todavía es referida desde la tabla «tareas». 199 | SQL state: 23503 200 | ::: 201 | -------------------------------------------------------------------------------- /src/19-02-sql/RDBMS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluuweb/desarrollo-web-bluuweb/93572b632ec9fa400cd23f2e79431fbd05458163/src/19-02-sql/RDBMS.png -------------------------------------------------------------------------------- /src/19-03-sql/README.md: -------------------------------------------------------------------------------- 1 | # PostgreSQL JOIN 2 | 3 | En esta sección conoceremos como realizar consultas en tablas relacionadas utilizando JOIN. 4 | 5 | 6 | 7 | ## Recursos: 8 | 9 | - [Relational DB](http://www.databaseanswers.org/data_models/amazon_and_starbucks/index.htm) 10 | 11 | Modelo entidad relación (ERD): 12 | 13 |
      14 | relacion todo sql 15 |
      16 | 17 | ## Tablas 18 | 19 | ```sql 20 | DROP TABLE IF EXISTS cliente_ordenes_productos; 21 | DROP TABLE IF EXISTS cliente_ordenes; 22 | DROP TABLE IF EXISTS clientes; 23 | DROP TABLE IF EXISTS productos; 24 | 25 | CREATE TABLE clientes ( 26 | cliente_id SERIAL PRIMARY KEY, 27 | cliente_nombre VARCHAR(50) 28 | ); 29 | 30 | CREATE TABLE productos ( 31 | producto_id SERIAL PRIMARY KEY, 32 | producto_nombre VARCHAR(50), 33 | producto_precio NUMERIC(6,2) CHECK(producto_precio >= 0), 34 | producto_stock SMALLINT CHECK(producto_stock >= 0) DEFAULT 0, 35 | producto_tipo VARCHAR(20) 36 | ); 37 | 38 | CREATE TABLE cliente_ordenes ( 39 | cliente_orden_id SERIAL PRIMARY KEY, 40 | cliente_id INT REFERENCES clientes(cliente_id), 41 | orden_fecha DATE DEFAULT NOW() 42 | ); 43 | 44 | CREATE TABLE cliente_ordenes_productos ( 45 | cliente_orden_id INT REFERENCES cliente_ordenes(cliente_orden_id), 46 | producto_id INT REFERENCES productos(producto_id), 47 | cantidad SMALLINT DEFAULT 1 48 | ); 49 | 50 | 51 | INSERT INTO productos 52 | (producto_nombre, producto_precio, producto_stock, producto_tipo) 53 | VALUES 54 | ('Latte', 2.50, 100, 'café'), 55 | ('Cappuccino', 1.90, 100, 'café'), 56 | ('Dulce de leche Latte', 20.50, 100, 'café'), 57 | ('Café Americano', 3.50, 100, 'café'), 58 | ('Iced Café Americano', 0.50, 100, 'ice café'), 59 | ('Café Mocha', 50, 100, 'café'), 60 | ('Caramel Macchiato', 3.2, 100, 'café'), 61 | ('Iced Mocha', 2.50, 100, 'ice café'), 62 | ('Mocha Blanco', 2.50, 0, null), 63 | ('Vanilla Latte', 2.50, 100, 'té'), 64 | ('Flat White', 2.50, 100, 'té'), 65 | ('Espresso', 2.50, 100, 'café'), 66 | ('Espresso Macchiato', 0.90, 0, 'café'), 67 | ('Espresso Con Panna', 1.50, 100, 'café'), 68 | ('Café Cortado', 3.50, 100, 'café'), 69 | ('Torta Cuatro Leches', 4.50, 100, 'postre'), 70 | ('Pie de Berries', 5.50, 0, 'postre'), 71 | ('Bagel', 2.50, 100, 'postre'), 72 | ('Donut Rellena', 6.50, 100, 'donut'), 73 | ('Scone de 4 quesos', 7.50, 100, 'sandwich'), 74 | ('Muffin Zanahoria Nuez', 8.50, 100, 'muffin'), 75 | ('Media luna', 9.50, 100, 'donut'), 76 | ('Pan de Queso', 11.50, 100, 'sandwich'), 77 | ('Praline Cake', 12.50, 100, 'sandwich'), 78 | ('Lemon Cake', 22.50, 100, null), 79 | ('Muffin con Chips', 33.50, 100, 'muffin'), 80 | ('Muffin de Arándano', 454.50, 10, 'muffin'); 81 | 82 | INSERT INTO clientes (cliente_nombre) 83 | VALUES 84 | ('María'), 85 | ('Carmen'), 86 | ('Josefa'), 87 | ('Antonio'), 88 | ('José'), 89 | ('Manuel'), 90 | ('David'), 91 | ('Daniel'); 92 | 93 | SELECT * FROM clientes; 94 | SELECT * FROM productos; 95 | ``` 96 | 97 | ## Agregar Ordenes 98 | 99 | Agregar una nueva orden de un cliente: 100 | 101 | ```sql 102 | INSERT INTO cliente_ordenes (cliente_id) 103 | VALUES (4); 104 | 105 | SELECT * FROM cliente_ordenes; 106 | ``` 107 | 108 | Cliente compra producto con id: 12 109 | 110 | ```sql 111 | INSERT INTO 112 | cliente_ordenes_productos (cliente_orden_id, producto_id, cantidad) 113 | VALUES (1, 12, 1); 114 | 115 | SELECT * FROM cliente_ordenes_productos; 116 | ``` 117 | 118 | Descontar stock del producto con id: 12 119 | 120 | ```sql 121 | UPDATE productos 122 | SET producto_stock = producto_stock - 1 123 | WHERE productos.producto_id = 12; 124 | 125 | SELECT * FROM productos; 126 | ``` 127 | 128 | ¿Si desea agregar otro producto? 129 | 130 | ```sql 131 | INSERT INTO 132 | cliente_ordenes_productos (cliente_orden_id, producto_id, cantidad) 133 | VALUES (1, 27, 2); 134 | 135 | UPDATE productos 136 | SET producto_stock = producto_stock - 2 137 | WHERE productos.producto_id = 27; 138 | 139 | SELECT * FROM productos; 140 | ``` 141 | 142 | :::tip Transacciones 143 | Más adelante vamos a realizar una transacción, así validamos que exista el stock necesario para comprar un producto. 144 | 145 | [Más info](https://www.todopostgresql.com/comandos-de-transacciones-en-postgresql/) 146 | ::: 147 | 148 | :::tip 149 | Cómo pudimos verificar todo el proceso lo hicimos de manera manual, ingresando estáticamente los id y stock correspondientes. Al finalizar los conceptos de join podremos hacer el ejercicio de manera dinámica. 150 | ::: 151 | 152 | ## JOIN 153 | 154 | - [Fuente](https://www.postgresqltutorial.com/postgresql-joins/) 155 | - La unión o join de PostgreSQL se utiliza para combinar columnas de una o más tablas, en función de los valores de las columnas comunes entre tablas relacionadas. 156 | - Existen diferentes tipos de join: 157 | - INNER JOIN o JOIN 158 | - LEFT JOIN 159 | - RIGHT JOIN 160 | - FULL JOIN o FULL OUTER JOIN 161 | - y otros... saquen su autodidacta interior 🤙 162 | 163 |
      164 | relacion todo sql 165 |
      166 | 167 | ## INNER JOIN 168 | 169 | - [INNER JOIN](https://www.postgresqltutorial.com/postgresql-inner-join/) 170 | 171 | ¿Si quisieramos pintar, el nombre del producto y la cantidad comprada? 172 | 173 | ```sql 174 | SELECT * 175 | FROM productos AS p 176 | INNER JOIN cliente_ordenes_productos AS cop 177 | ON p.producto_id = cop.producto_id; 178 | ``` 179 | 180 | ```sql 181 | SELECT p.producto_nombre, cop.cantidad 182 | FROM productos p 183 | INNER JOIN cliente_ordenes_productos cop 184 | ON p.producto_id = cop.producto_id; 185 | ``` 186 | 187 | Pintar el total a pagar por producto: 188 | 189 | ```sql 190 | SELECT 191 | p.producto_nombre, 192 | p.producto_precio * cop.cantidad "$ producto" 193 | FROM productos p 194 | JOIN cliente_ordenes_productos cop 195 | ON p.producto_id = cop.producto_id; 196 | ``` 197 | 198 | Pintar la suma total a pagar: 199 | 200 | ```sql 201 | SELECT 202 | SUM(p.producto_precio * cop.cantidad) "Total a pagar" 203 | FROM productos p 204 | JOIN cliente_ordenes_productos cop 205 | ON p.producto_id = cop.producto_id; 206 | ``` 207 | 208 | ## LEFT JOIN 209 | 210 | - [LEFT JOIN](https://www.postgresqltutorial.com/postgresql-left-join/) 211 | 212 | ```sql 213 | SELECT 214 | * 215 | FROM productos p 216 | LEFT JOIN cliente_ordenes_productos cop 217 | ON p.producto_id = cop.producto_id; 218 | ``` 219 | 220 | Pintar productos que no se aún no se venden: 221 | 222 | ```sql 223 | SELECT p.producto_nombre 224 | FROM productos p 225 | LEFT JOIN cliente_ordenes_productos cop 226 | ON p.producto_id = cop.producto_id 227 | WHERE cop.producto_id IS NULL; 228 | ``` 229 | 230 | ## RIGHT JOIN 231 | 232 | - [RIGHT JOIN](https://www.postgresqltutorial.com/postgresql-right-join/) 233 | 234 | ```sql 235 | SELECT 236 | * 237 | FROM productos p 238 | RIGHT JOIN cliente_ordenes_productos cop 239 | ON p.producto_id = cop.producto_id; 240 | ``` 241 | 242 | ## FULL JOIN 243 | 244 | - [FULL JOIN](https://www.postgresqltutorial.com/postgresql-full-outer-join/) 245 | 246 | ```sql 247 | SELECT 248 | * 249 | FROM productos p 250 | FULL JOIN cliente_ordenes_productos cop 251 | ON p.producto_id = cop.producto_id; 252 | ``` 253 | 254 | ## JOIN \* N TABLAS 255 | 256 | Pintar fecha de orden y nombre del producto: 257 | 258 | ```sql 259 | SELECT * 260 | FROM cliente_ordenes co 261 | JOIN cliente_ordenes_productos cop 262 | ON co.cliente_orden_id = cop.cliente_orden_id 263 | JOIN productos p 264 | ON cop.producto_id = p.producto_id; 265 | ``` 266 | 267 | ```sql 268 | SELECT co.orden_fecha, producto_nombre 269 | FROM cliente_ordenes co 270 | JOIN cliente_ordenes_productos cop 271 | ON co.cliente_orden_id = cop.cliente_orden_id 272 | JOIN productos p 273 | ON cop.producto_id = p.producto_id; 274 | ``` 275 | 276 | Pintar nombre cliente, fecha orden, cantidad, nombre producto y cantidad \* precio: 277 | 278 | ```sql 279 | SELECT 280 | c.cliente_nombre, 281 | co.orden_fecha, 282 | cop.cantidad, 283 | p.producto_nombre, 284 | cop.cantidad * p.producto_precio total 285 | FROM clientes c 286 | JOIN cliente_ordenes co 287 | ON c.cliente_id = co.cliente_id 288 | JOIN cliente_ordenes_productos cop 289 | ON co.cliente_orden_id = cop.cliente_orden_id 290 | JOIN productos p 291 | ON cop.producto_id = p.producto_id; 292 | ``` 293 | 294 | 322 | -------------------------------------------------------------------------------- /src/19-04-sql/README.md: -------------------------------------------------------------------------------- 1 | # PostgreSQL Normalización 2 | 3 | Conozcamos como normalizar nuestra base de datos. 4 | 5 | 6 | 7 | ## Normalización 8 | 9 | - [fuente #01](https://explodat.cl/Analytics/desarrollo-de-software/normalizacion-de-bases-de-datos/) 10 | - La normalización es el proceso de seguir una serie de reglas (formas normales), para asegurar que nuestras relaciones estén **ordenadas y regularizadas** con el fin de **mejorar** dichas relaciones. 11 | - Están enfocadas en evitar la redundancia de datos e inconsistencias en el diseño de nuestras tablas. 12 | 13 | ## ¿Por qué normalizar? 14 | 15 | - Evitar redundancia de datos 16 | - Proteger la integridad de los datos 17 | - Evitar problemas de actualiación. 18 | 19 | :::tip ¿Cómo normalizar una DB? 20 | 21 | - Se siguen **en un proceso ordenado** las formas normales (FN). 22 | - Por ende partimos con 1FN, 2FN... hasta la 6FN. 23 | - Lo tradicional es llegar hasta la 3FN. 24 | ::: 25 | 26 | ## Ejemplo 27 | 28 |
      29 | relacion todo sql 30 |
      31 | 32 | ## 1FN (primera forma normal) 33 | 34 | - Cada campo o atributo deben ser atómicos, es decir debe contener un único valor. 35 | - No pueden haber grupos repetitivos. 36 | - Existir una llave primaria. 37 | 38 | ### Solución 1 39 | 40 | - Todos los datos son atómicos 41 | - Pero telefono 1 y telefono 2 es un grupo repetitivo, esto genera: 42 | - Pérdida de espacios de memoría. 43 | - Limitar a solo dos teléfonos nuesta DB. 44 | 45 |
      46 | relacion todo sql 47 |
      48 | 49 | ## Solución 2 50 | 51 |
      52 | relacion todo sql 53 |
      54 | 55 | ### Redundancia solución 2 56 | 57 | - Podemos notar que si un paciente pide otra hora médica genera redundancia en nuestra tabla. Por ende tenemos que separar en una nueva relación: 58 | 59 |
      60 | relacion todo sql 61 |
      62 | 63 | :::tip 64 | Antes de pasar a 2FN, conozcamos los tipos de dependencia. 65 | ::: 66 | 67 | ## Tipos de dependencia 68 | 69 | - **Dependencia Funcional**: Los atributos dependen de la clave primaria. 70 | - B y C dependen funcionalmente de A (clave primaria). 71 | - Para que exista B debe existir A. y lo mismo para C. 72 | 73 |
      74 | relacion todo sql 75 |
      76 | 77 | - **Dependencia Transitiva**: 78 | - B depende funcionalmente de A. 79 | - C depende de B, pero como B depende de A, C tiene una dependencia transitiva de A. 80 | 81 |
      82 | relacion todo sql 83 |
      84 | 85 | ## 2FN (segunda forma normal) 86 | 87 | - Debe cumplir con 1FN. 88 | - Cada atributo debe depender de la llave primaria, y no solo una parte de ella. 89 | - Los atributos que dependen de manera parcial de la llave primaria deben ser 90 | eliminados o almacenados en una nueva entidad. 91 | 92 |
      93 | relacion todo sql 94 |
      95 | 96 | ### Llave primaria compuesta 97 | 98 | - compuesta de "idpaciente", "especialidad" y "fecha atencion" 99 | - si analizamos "area" esta depende exclusivamente de la especilidad y no del id del paciente, por ende no cumple con la 2FN (Cada atributo debe depender de la llave primaria, y no solo una parte de ella.) 100 | 101 |
      102 | relacion todo sql 103 |
      104 | 105 | ## 3FN (tercera forma normal) 106 | 107 | - Debe cumplir con 2FN. 108 | - Eliminar toda dependencia transitiva. 109 | 110 |
      111 | relacion todo sql 112 |
      113 | 114 | ## ¿Desnormalizar? 115 | 116 | - Dependerá de cada caso, si es más factible duplicar datos que realizar múltiples relaciones que pueden ser complejas. 117 | 118 |
      119 | relacion todo sql 120 |
      121 | -------------------------------------------------------------------------------- /src/20-02-express/login1.js: -------------------------------------------------------------------------------- 1 | //Para evitar inyecciones no sql 2 | const sanitize = require("mongo-sanitize"); 3 | const User = require("../models/User"); 4 | const Joi = require("@hapi/joi"); 5 | const bcrypt = require("bcrypt"); 6 | const jwt = require("jsonwebtoken"); 7 | 8 | //Validacion contra esquema 9 | const schemaLogin = Joi.object({ 10 | email: Joi.string() 11 | .min(6) 12 | .max(255) 13 | .required() 14 | .email(), 15 | password: Joi.string() 16 | .min(3) 17 | .max(1024) 18 | .required(), 19 | }); 20 | 21 | const loginUser = async (req, res) => { 22 | //Evitar inyección a mongo 23 | req.body = sanitize(req.body); 24 | 25 | //Comprobar si el body cumple los requisitos del esquma 26 | const { error } = schemaLogin.validate(req.body); 27 | 28 | //En casso de error devolver documento mal formado, 29 | //junto array de errores 30 | if (error) return res.status(400).json({ error: error.details[0].message }); 31 | 32 | //Comprobar a traves del email si el usuario existe en la BBDD 33 | const user = await User.findOne({ email: req.body.email }); 34 | 35 | //Si no existe devolver error 36 | if (!user) return res.status(404).json({ error: "Usuario no encontrado" }); 37 | 38 | //Comprobar el password 39 | const validPassword = await bcrypt.compare( 40 | req.body.password, 41 | user.password 42 | ); 43 | if (!validPassword) 44 | return res.status(400).json({ error: "contraseña no válida" }); 45 | 46 | //Obtener token con tiempo de expiración de una hora 47 | const token = jwt.sign( 48 | { 49 | nombre: user.nombre, 50 | id: user._id, 51 | }, 52 | process.env.TOKEN_SECRET, 53 | { 54 | expiresIn: "1h", 55 | } 56 | ); 57 | 58 | //Devolver token al cliente 59 | res.header("auth-token", token).json({ 60 | error: null, 61 | data: { token }, 62 | }); 63 | }; 64 | 65 | module.exports = loginUser; 66 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # Curso HTML, CSS y Bootstrap 5 2 | 3 |
      4 | 5 | foo 6 | 7 |
      8 | 9 | 😍 ACCEDE AL CURSO AQUÍ 😍 10 | 11 |
      12 | 13 | Este curso intensivo tiene como finalidad entregar las herramientas necesarias para comenzar en el desarrollo web con HTML, CSS y Bootstrap 5. 14 | 15 | Está orientado a la práctica por ende a través de diferentes ejemplos comprenderemos como es el camino del desarrollo web. 16 | 17 | Al finalizar el curso el estudiante podrá construir sitios web responsives utilizando HTML, CSS y Bootstrap 5. 👌 18 | 19 | :::tip 🎉 Accede al curso con un super descuento 🎉 20 | Este curso está publicado en Udemy, puedes acceder con un descuento especial en el siguiente enlace: 21 | 22 | - [Ir al curso en Udemy aquí](curso-bootstrap-5-udemy.bluuweb.cl) 23 | ::: 24 | 25 | ## ¿Dudas y preguntas? 26 | 27 | Te invito a nuestro servidor de **Discord**, donde todos nos ayudamos. **ES GRATIS** 👏 28 | 29 | - [Click aquí: https://discord.com/invite/hcG7NBvsGD](https://discord.com/invite/hcG7NBvsGD) 30 | 31 | ## Gist 32 | 33 | Aquí iré detallando diferentes notas: 34 | 35 | - [Notas de HTML y CSS](https://gist.github.com/bluuweb/8612c7e1c82bb85bce5b92d67f5b285c) 36 | 37 | ## Redes Sociales: 38 | 39 | - [Youtube](https://www.youtube.com/bluuweb) 40 | - [Twitch](https://www.twitch.tv/bluuweb) 41 | - [Instagram](https://www.instagram.com/bluuweb_youtube) 42 | - [Facebook](https://www.facebook.com/bluuweb) 43 | - [Twitter](https://twitter.com/bluuweb) 44 | - [Discord](https://discord.com/invite/hcG7NBvsGD) 45 | 46 | 151 | --------------------------------------------------------------------------------