From e2414f10979769c6a5d05591080cbb0151405424 Mon Sep 17 00:00:00 2001 From: carlos tomas Date: Mon, 14 Oct 2024 08:43:32 +0200 Subject: [PATCH] update unsocial with post and password hiding #175 --- staff/carlos-tomas/unsocial.7/.gitkeep | 0 staff/carlos-tomas/unsocial.7/compo.js | 127 +++++++++++ staff/carlos-tomas/unsocial.7/data.js | 4 + staff/carlos-tomas/unsocial.7/index.html | 28 +++ staff/carlos-tomas/unsocial.7/logic.js | 44 ++++ staff/carlos-tomas/unsocial.7/main.js | 9 + staff/carlos-tomas/unsocial.7/style.css | 39 ++++ staff/carlos-tomas/unsocial.7/view.js | 174 ++++++++++++++++ staff/carlos-tomas/unsocial.8/.gitkeep | 0 staff/carlos-tomas/unsocial.8/compo.demo.html | 19 ++ staff/carlos-tomas/unsocial.8/compo.demo.js | 26 +++ staff/carlos-tomas/unsocial.8/compo.js | 197 ++++++++++++++++++ staff/carlos-tomas/unsocial.8/data.js | 4 + staff/carlos-tomas/unsocial.8/index.html | 28 +++ staff/carlos-tomas/unsocial.8/logic.js | 44 ++++ staff/carlos-tomas/unsocial.8/main.js | 9 + staff/carlos-tomas/unsocial.8/style.css | 39 ++++ staff/carlos-tomas/unsocial.8/view.js | 174 ++++++++++++++++ staff/carlos-tomas/unsocial/compo.demo.html | 19 ++ staff/carlos-tomas/unsocial/compo.demo.js | 31 +++ staff/carlos-tomas/unsocial/compo.js | 184 ++++++++++++++-- staff/carlos-tomas/unsocial/data.js | 15 ++ staff/carlos-tomas/unsocial/logic.js | 20 ++ staff/carlos-tomas/unsocial/main.js | 3 + staff/carlos-tomas/unsocial/style.css | 1 - staff/carlos-tomas/unsocial/view.js | 179 ++++++++++++---- 26 files changed, 1362 insertions(+), 55 deletions(-) create mode 100644 staff/carlos-tomas/unsocial.7/.gitkeep create mode 100644 staff/carlos-tomas/unsocial.7/compo.js create mode 100644 staff/carlos-tomas/unsocial.7/data.js create mode 100644 staff/carlos-tomas/unsocial.7/index.html create mode 100644 staff/carlos-tomas/unsocial.7/logic.js create mode 100644 staff/carlos-tomas/unsocial.7/main.js create mode 100644 staff/carlos-tomas/unsocial.7/style.css create mode 100644 staff/carlos-tomas/unsocial.7/view.js create mode 100644 staff/carlos-tomas/unsocial.8/.gitkeep create mode 100644 staff/carlos-tomas/unsocial.8/compo.demo.html create mode 100644 staff/carlos-tomas/unsocial.8/compo.demo.js create mode 100644 staff/carlos-tomas/unsocial.8/compo.js create mode 100644 staff/carlos-tomas/unsocial.8/data.js create mode 100644 staff/carlos-tomas/unsocial.8/index.html create mode 100644 staff/carlos-tomas/unsocial.8/logic.js create mode 100644 staff/carlos-tomas/unsocial.8/main.js create mode 100644 staff/carlos-tomas/unsocial.8/style.css create mode 100644 staff/carlos-tomas/unsocial.8/view.js create mode 100644 staff/carlos-tomas/unsocial/compo.demo.html create mode 100644 staff/carlos-tomas/unsocial/compo.demo.js diff --git a/staff/carlos-tomas/unsocial.7/.gitkeep b/staff/carlos-tomas/unsocial.7/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/staff/carlos-tomas/unsocial.7/compo.js b/staff/carlos-tomas/unsocial.7/compo.js new file mode 100644 index 00000000..56a259c4 --- /dev/null +++ b/staff/carlos-tomas/unsocial.7/compo.js @@ -0,0 +1,127 @@ +/** + * Constructs Compo instances + * @param {HTMLElement} container The DOM container of the Compo instance + */ +function Compo(container) { + this.children = [] + this.container = container +} + +Compo.prototype.add = function (child) { + this.children.push(child) // Par poder montar nuestro comcepto + this.container.appendChild(child.container) //Para poder montar el HTML +} +Compo.prototype.remove = function () { + this.container.remove() +} + +Compo.prototype.add = function (child) { + this.children.push(child) + this.container.appendChild(child.container) +} + +Compo.prototype.remove = function () { + this.container.remove() +} + +Compo.prototype.addBehavior = function (type, callback) { + this.container.addEventListener(type, callback) +} +/** + * Construcus Form instances + */ +function Form() { + Compo.call(this, document.createElement("form")) +} + +Form.prototype = Object.create(Compo.prototype) +Form.prototype.constructor = Form + +Form.prototype.reset = function () { + this.container.reset() +} + +/** + * Constructs Button instances + * @param {string} text The text of the button + * @param {string} type The button type + */ +function Button(text, type) { + Compo.call(this, document.createElement("button")) + + this.container.innerText = text + this.container.type = type +} + +Button.prototype = Object.create(Compo.prototype) +Button.prototype.constructor = Button + +/** + * Constructs Label instances + * + * @param {string} text The text of the label + * @param {string} id The id of the input to relate with + */ +function Label(text, id) { + Compo.call(this, document.createElement("label")) + + this.container.innerText = text + this.container.htmlFor = id +} + +Label.prototype = Object.create(Compo.prototype) +Label.prototype.constructor = Label + +/** + * Constructs Input instances + * + * @param {string} type The input type + * @param {string} id The input id + */ +function Input(type, id) { + Compo.call(this, document.createElement("input")) + + this.container.type = type + this.container.id = id +} + +Input.prototype = Object.create(Compo.prototype) +Input.prototype.constructor = Input + +Input.prototype.getValue = function () { + return this.container.value +} + +Input.prototype.setValue = function (value) { + this.container.value = value +} + +/** + * Constructs Heading instances + * + * @param {string} text The text of the heading + * @param {number} level The heading level + */ +function Heading(text, level) { + Compo.call(this, document.createElement('h' + level)) + + this.container.innerText = text +} + +Heading.prototype = Object.create(Compo.prototype) +Heading.prototype.constructor = Heading + +/** + * Constructs Link instances + * + * @param {string} text The text of the link + */ +function Link(text) { + Compo.call(this, document.createElement('a')) + + this.container.innerText = text + this.container.href = '' +} + +Link.prototype = Object.create(Compo.prototype) +Link.prototype.constructor = Link diff --git a/staff/carlos-tomas/unsocial.7/data.js b/staff/carlos-tomas/unsocial.7/data.js new file mode 100644 index 00000000..7478bdcb --- /dev/null +++ b/staff/carlos-tomas/unsocial.7/data.js @@ -0,0 +1,4 @@ +var users = [ + { name: 'Peter Pan', email: 'peter@pan.com', username: 'peterpan', password: '123123123' }, + { name: 'Wendy Darling', email: 'wendy@darling.com', username: 'wendydarling', password: '123123123' } +] \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.7/index.html b/staff/carlos-tomas/unsocial.7/index.html new file mode 100644 index 00000000..204fcc5e --- /dev/null +++ b/staff/carlos-tomas/unsocial.7/index.html @@ -0,0 +1,28 @@ + + + + + + + Unsocial + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.7/logic.js b/staff/carlos-tomas/unsocial.7/logic.js new file mode 100644 index 00000000..edb64111 --- /dev/null +++ b/staff/carlos-tomas/unsocial.7/logic.js @@ -0,0 +1,44 @@ +function registerUser(name, email, username, password, passwordRepeat) { + if (name.length < 2) + throw new Error('invalid name') + + if (!/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i.test(email)) + throw new Error('invalid e-mail') + + if (username.length < 4 || username.length > 12) + throw new Error('invalid username') + + if (password.length < 8) + throw new Error('invalid password') + + if (password !== passwordRepeat) + throw new Error('passwords do not match') + + var user = users.find(function (user) { + return user.username === username || user.email === email + }) + + if (user !== undefined) + throw new Error('user already exists') + + user = { name: name, email: email, username: username, password: password } + + users.push(user) +} + +function authenticateUser(username, password) { + if (username.length < 4 || username.length > 12) + throw new Error('invalid username') + + if (password.length < 8) + throw new Error('invalid password') + + var user = users.find(function (user) { + return user.username === username && user.password === password + }) + + if (user === undefined) + throw new Error('wrong credentials') + + return user +} \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.7/main.js b/staff/carlos-tomas/unsocial.7/main.js new file mode 100644 index 00000000..8f119fcc --- /dev/null +++ b/staff/carlos-tomas/unsocial.7/main.js @@ -0,0 +1,9 @@ +var loggedInUser = null + +var page = new Compo(document.querySelector("body")) + +var title = new Heading("Unsocial", 1) +page.add(title) + +var login = new Login() +page.add(login) diff --git a/staff/carlos-tomas/unsocial.7/style.css b/staff/carlos-tomas/unsocial.7/style.css new file mode 100644 index 00000000..8b8fe271 --- /dev/null +++ b/staff/carlos-tomas/unsocial.7/style.css @@ -0,0 +1,39 @@ +@import url('https://fonts.googleapis.com/css2?family=Fontdiner+Swanky&display=swap'); + +:root { + --color: dodgerblue; + --font: "Fontdiner Swanky", serif; + font-family: var(--font); +} + +body { + background-color: #fffe9a; + + text-align: center; + width: 100%; + height: 100vh; + margin: 0; +} + +.login { + margin-top: 100px; +} + +.register { + margin-top: 100px; +} + +input { + background-color: inherit; + font-family: inherit; + display: block; + width: 20px; + max-width: 500px; + min-width: 300px; + margin: 15px auto; + border-radius: 10px; +} + +a:visited { + color: black; +} \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.7/view.js b/staff/carlos-tomas/unsocial.7/view.js new file mode 100644 index 00000000..823b0b87 --- /dev/null +++ b/staff/carlos-tomas/unsocial.7/view.js @@ -0,0 +1,174 @@ +/** + * Constructs Login instances + */ +function Login() { + Compo.call(this, document.createElement("Section")) + + var compo = this + + var title = new Heading("Login", 2) + compo.add(title) + + var form = new Form() + compo.add(form) + + form.add(new Label("Username", "username")) + var usernameInput = new Input("text", ' username') + form.add(usernameInput) + + form.add(new Label('Password', 'password')) + var passwordInput = new Input('password', 'password') + form.add(passwordInput) + + var submitButton = new Button("Login", "submit") + form.add(submitButton) + + form.addBehavior('submit', function (event) { + event.preventDefault() + + var username = usernameInput.getValue() + var password = passwordInput.getValue() + + try { + loggedInUser = authenticateUser(username, password) + + form.reset() + + compo.remove() + + var home = new Home() + + page.add(home) + } catch (error) { + + passwordInput.setValue('') + + alert(error.message) + + console.error(error) + } + }) + + var registerLink = new Link('Register') + compo.add(registerLink) + + registerLink.addBehavior('click', function (event) { + event.preventDefault() + + compo.remove() + + var register = new Register() + + page.add(register) + }) +} + +Login.prototype = Object.create(Compo.prototype) +Login.prototype.constructor = Login + +/** + * Constructs Register instances + */ +function Register() { + Compo.call(this, document.createElement('section')) + + var compo = this + + var title = new Heading('Register', 2) + compo.add(title) + + var form = new Form() + compo.add(form) + + form.add(new Label('Name', 'name')) + var nameInput = new Input('text', 'name') + form.add(nameInput) + + form.add(new Label('E-mail', 'email')) + var emailInput = new Input('email', 'email') + form.add(emailInput) + + form.add(new Label('Username', 'username')) + var usernameInput = new Input('text', 'username') + form.add(usernameInput) + + form.add(new Label('Password', 'password')) + var passwordInput = new Input('password', 'password') + form.add(passwordInput) + + form.add(new Label('Repeat Password', 'password-repeat')) + var passwordRepeatInput = new Input('password', 'password-repeat') + form.add(passwordRepeatInput) + + var submitButton = new Button('Register', 'submit') + form.add(submitButton) + + form.addBehavior('submit', function (event) { + event.preventDefault() + + var name = nameInput.getValue() + var email = emailInput.getValue() + var username = usernameInput.getValue() + var password = passwordInput.getValue() + var passwordRepeat = passwordRepeatInput.getValue() + + try { + registerUser(name, email, username, password, passwordRepeat) + + form.reset() + + compo.remove() + + page.add(login) + } catch (error) { + alert(error.message) + + console.error(error) + } + + }) + + var loginLink = new Link('Login') + compo.add(loginLink) + + loginLink.addBehavior('click', function (event) { + event.preventDefault() + + compo.remove() + page.add(login) + }) +} +Register.prototype = Object.create(Compo.prototype) +Register.prototype.constructor = Register + +/** + * Constructs Home instances + */ +function Home() { + Compo.call(this, document.createElement('section')) + + var compo = this + + var title = new Heading('Home', 2) + compo.add(title) + + + var userTitle = new Heading('Hello, ' + loggedInUser.name + '!', 3) + compo.add(userTitle) + + var logoutButton = new Button('Logout', 'button') + compo.add(logoutButton) + + logoutButton.addBehavior('click', function (event) { + event.preventDefault() // Parar cargar la paguina web + + loggedInUser = null + + compo.remove() + + page.add(login)// LLamar al body a la login Section + }) +} + +Home.prototype = Object.create(Compo.prototype) +Home.prototype.constructor = Home \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/.gitkeep b/staff/carlos-tomas/unsocial.8/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/staff/carlos-tomas/unsocial.8/compo.demo.html b/staff/carlos-tomas/unsocial.8/compo.demo.html new file mode 100644 index 00000000..f50451b0 --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/compo.demo.html @@ -0,0 +1,19 @@ + + + + + + + Document + + + + + + + + + + + + \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/compo.demo.js b/staff/carlos-tomas/unsocial.8/compo.demo.js new file mode 100644 index 00000000..cef02215 --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/compo.demo.js @@ -0,0 +1,26 @@ +var page = new Compo(document.body) + +var title = new Heading("Compo", 1) +page.add(title) + +var inputTitle = new Heading("Input", 2) +page.add(inputTitle) + +var input = new Input("password", "password") +page.add(input) +var linkTitle = new Heading("Link", 2) +page.add(linkTitle) + + + +var passwordInputTitle = new Heading("PasswordInput") +page.add(passwordInputTitle) + +var link = new Link("Google") +page.add(link) + +var passwordInputTitle = new Heading("PasswordInput", 2) +page.add(passwordInputTitle) + +var passwordInput = new passwordInput("password") +page.add(passwordInput) \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/compo.js b/staff/carlos-tomas/unsocial.8/compo.js new file mode 100644 index 00000000..3ddda796 --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/compo.js @@ -0,0 +1,197 @@ +/** + * Constructs Compo instances + * + * @param {HTMLElement} container The DOM container of the Compo instance + */ +function Compo(container) { + this.children = [] + this.container = container +} + +Compo.prototype.add = function (child) { + this.children.push(child) // Par poder montar nuestro comcepto + this.container.appendChild(child.container) //Para poder montar el HTML +} +Compo.prototype.remove = function () { + this.container.remove() +} + +Compo.prototype.add = function (child) { + this.children.push(child) + this.container.appendChild(child.container) +} + +Compo.prototype.remove = function () { + this.container.remove() +} + +Compo.prototype.addBehavior = function (type, callback) { + this.container.addEventListener(type, callback) +} +/** + * Construcus Form instances + */ +function Form() { + Compo.call(this, document.createElement("form")) +} + +Form.prototype = Object.create(Compo.prototype) +Form.prototype.constructor = Form + +Form.prototype.reset = function () { + this.container.reset() +} + +/** + * Constructs Button instances + * @param {string} text The text of the button + * @param {string} type The button type + */ +function Button(text, type) { + Compo.call(this, document.createElement("button")) + + this.container.innerText = text + this.container.type = type +} + +Button.prototype = Object.create(Compo.prototype) +Button.prototype.constructor = Button + +/** + * Constructs Label instances + * + * @param {string} text The text of the label + * @param {string} id The id of the input to relate with + */ +function Label(text, id) { + Compo.call(this, document.createElement("label")) + + this.container.innerText = text + this.container.htmlFor = id +} + +Label.prototype = Object.create(Compo.prototype) +Label.prototype.constructor = Label + +/** + * Constructs Input instances + * + * @param {string} type The input type + * @param {string} id The input id + */ +function Input(type, id) { + Compo.call(this, document.createElement("input")) + this.container.style.width = "100%" + this.container.style.boxSizing = " boder-box" + + this.container.type = type + this.container.id = id +} + +Input.prototype = Object.create(Compo.prototype) +Input.prototype.constructor = Input + +Input.prototype.getValue = function () { + return this.container.value +} + +Input.prototype.setValue = function (value) { + this.container.value = value +} + +Input.prototype.getType = function () { + return this.container.type +} + +Input.prototype.setType = function (type) { + this.container.type = type +} + +/** + * Constructs Heading instances + * + * @param {string} text The text of the heading + * @param {number} level The heading level + */ +function Heading(text, level) { + Compo.call(this, document.createElement('h' + level)) + + this.container.innerText = text +} + +Heading.prototype = Object.create(Compo.prototype) +Heading.prototype.constructor = Heading + +/** + * Constructs Link instances + * + * @param {string} text The text of the link + */ +function Link(text) { + Compo.call(this, document.createElement('a')) + + this.container.innerText = text + this.container.href = '' +} + +Link.prototype = Object.create(Compo.prototype) +Link.prototype.constructor = Link + + +/** + * Constructs Span instances + * + * @param {string} text The text inside span + */ +function Span(text) { + Compo.call(this, document.createElement("span")) + + this.container.innerText = text +} + +Span.prototype = Object.create(Compo.prototype) +Span.prototype.constructor = Span + +Span.prototype.setText = function (text) { + this.container.innerText = text +} + +Span.prototype.getText = function () { + return this.container.innerText +} + +/** + * + */ + +function PasswordInput(id) { + Compo.call(this, document.createElement("div")) + this.container.style.display = "flex" + + var input = new Input("password", id) + input.container.style.paddingRight = "18px" + this.add(input) + + var span = new Span('😌') + span.container.style.cursor = "pointer" + span.container.style.position = "absolute" + span.container.style.right = "10px" + this.add(span) + + span.addBehavior("click", function () { + if (span.getText() === '😌') { + input.setType("text") + span.setText('😳') + } else { + input.setType("password") + span.setText('😌') + } + }) +} + +PasswordInput.prototype = Object.create(Compo.prototype) +PasswordInput.prototype.constructor = PasswordInput + +PasswordInput.prototype.getValue = function () { + return this.children[0].container.value +} \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/data.js b/staff/carlos-tomas/unsocial.8/data.js new file mode 100644 index 00000000..7478bdcb --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/data.js @@ -0,0 +1,4 @@ +var users = [ + { name: 'Peter Pan', email: 'peter@pan.com', username: 'peterpan', password: '123123123' }, + { name: 'Wendy Darling', email: 'wendy@darling.com', username: 'wendydarling', password: '123123123' } +] \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/index.html b/staff/carlos-tomas/unsocial.8/index.html new file mode 100644 index 00000000..204fcc5e --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/index.html @@ -0,0 +1,28 @@ + + + + + + + Unsocial + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/logic.js b/staff/carlos-tomas/unsocial.8/logic.js new file mode 100644 index 00000000..edb64111 --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/logic.js @@ -0,0 +1,44 @@ +function registerUser(name, email, username, password, passwordRepeat) { + if (name.length < 2) + throw new Error('invalid name') + + if (!/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i.test(email)) + throw new Error('invalid e-mail') + + if (username.length < 4 || username.length > 12) + throw new Error('invalid username') + + if (password.length < 8) + throw new Error('invalid password') + + if (password !== passwordRepeat) + throw new Error('passwords do not match') + + var user = users.find(function (user) { + return user.username === username || user.email === email + }) + + if (user !== undefined) + throw new Error('user already exists') + + user = { name: name, email: email, username: username, password: password } + + users.push(user) +} + +function authenticateUser(username, password) { + if (username.length < 4 || username.length > 12) + throw new Error('invalid username') + + if (password.length < 8) + throw new Error('invalid password') + + var user = users.find(function (user) { + return user.username === username && user.password === password + }) + + if (user === undefined) + throw new Error('wrong credentials') + + return user +} \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/main.js b/staff/carlos-tomas/unsocial.8/main.js new file mode 100644 index 00000000..8f119fcc --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/main.js @@ -0,0 +1,9 @@ +var loggedInUser = null + +var page = new Compo(document.querySelector("body")) + +var title = new Heading("Unsocial", 1) +page.add(title) + +var login = new Login() +page.add(login) diff --git a/staff/carlos-tomas/unsocial.8/style.css b/staff/carlos-tomas/unsocial.8/style.css new file mode 100644 index 00000000..8b8fe271 --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/style.css @@ -0,0 +1,39 @@ +@import url('https://fonts.googleapis.com/css2?family=Fontdiner+Swanky&display=swap'); + +:root { + --color: dodgerblue; + --font: "Fontdiner Swanky", serif; + font-family: var(--font); +} + +body { + background-color: #fffe9a; + + text-align: center; + width: 100%; + height: 100vh; + margin: 0; +} + +.login { + margin-top: 100px; +} + +.register { + margin-top: 100px; +} + +input { + background-color: inherit; + font-family: inherit; + display: block; + width: 20px; + max-width: 500px; + min-width: 300px; + margin: 15px auto; + border-radius: 10px; +} + +a:visited { + color: black; +} \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial.8/view.js b/staff/carlos-tomas/unsocial.8/view.js new file mode 100644 index 00000000..823b0b87 --- /dev/null +++ b/staff/carlos-tomas/unsocial.8/view.js @@ -0,0 +1,174 @@ +/** + * Constructs Login instances + */ +function Login() { + Compo.call(this, document.createElement("Section")) + + var compo = this + + var title = new Heading("Login", 2) + compo.add(title) + + var form = new Form() + compo.add(form) + + form.add(new Label("Username", "username")) + var usernameInput = new Input("text", ' username') + form.add(usernameInput) + + form.add(new Label('Password', 'password')) + var passwordInput = new Input('password', 'password') + form.add(passwordInput) + + var submitButton = new Button("Login", "submit") + form.add(submitButton) + + form.addBehavior('submit', function (event) { + event.preventDefault() + + var username = usernameInput.getValue() + var password = passwordInput.getValue() + + try { + loggedInUser = authenticateUser(username, password) + + form.reset() + + compo.remove() + + var home = new Home() + + page.add(home) + } catch (error) { + + passwordInput.setValue('') + + alert(error.message) + + console.error(error) + } + }) + + var registerLink = new Link('Register') + compo.add(registerLink) + + registerLink.addBehavior('click', function (event) { + event.preventDefault() + + compo.remove() + + var register = new Register() + + page.add(register) + }) +} + +Login.prototype = Object.create(Compo.prototype) +Login.prototype.constructor = Login + +/** + * Constructs Register instances + */ +function Register() { + Compo.call(this, document.createElement('section')) + + var compo = this + + var title = new Heading('Register', 2) + compo.add(title) + + var form = new Form() + compo.add(form) + + form.add(new Label('Name', 'name')) + var nameInput = new Input('text', 'name') + form.add(nameInput) + + form.add(new Label('E-mail', 'email')) + var emailInput = new Input('email', 'email') + form.add(emailInput) + + form.add(new Label('Username', 'username')) + var usernameInput = new Input('text', 'username') + form.add(usernameInput) + + form.add(new Label('Password', 'password')) + var passwordInput = new Input('password', 'password') + form.add(passwordInput) + + form.add(new Label('Repeat Password', 'password-repeat')) + var passwordRepeatInput = new Input('password', 'password-repeat') + form.add(passwordRepeatInput) + + var submitButton = new Button('Register', 'submit') + form.add(submitButton) + + form.addBehavior('submit', function (event) { + event.preventDefault() + + var name = nameInput.getValue() + var email = emailInput.getValue() + var username = usernameInput.getValue() + var password = passwordInput.getValue() + var passwordRepeat = passwordRepeatInput.getValue() + + try { + registerUser(name, email, username, password, passwordRepeat) + + form.reset() + + compo.remove() + + page.add(login) + } catch (error) { + alert(error.message) + + console.error(error) + } + + }) + + var loginLink = new Link('Login') + compo.add(loginLink) + + loginLink.addBehavior('click', function (event) { + event.preventDefault() + + compo.remove() + page.add(login) + }) +} +Register.prototype = Object.create(Compo.prototype) +Register.prototype.constructor = Register + +/** + * Constructs Home instances + */ +function Home() { + Compo.call(this, document.createElement('section')) + + var compo = this + + var title = new Heading('Home', 2) + compo.add(title) + + + var userTitle = new Heading('Hello, ' + loggedInUser.name + '!', 3) + compo.add(userTitle) + + var logoutButton = new Button('Logout', 'button') + compo.add(logoutButton) + + logoutButton.addBehavior('click', function (event) { + event.preventDefault() // Parar cargar la paguina web + + loggedInUser = null + + compo.remove() + + page.add(login)// LLamar al body a la login Section + }) +} + +Home.prototype = Object.create(Compo.prototype) +Home.prototype.constructor = Home \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial/compo.demo.html b/staff/carlos-tomas/unsocial/compo.demo.html new file mode 100644 index 00000000..f50451b0 --- /dev/null +++ b/staff/carlos-tomas/unsocial/compo.demo.html @@ -0,0 +1,19 @@ + + + + + + + Document + + + + + + + + + + + + \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial/compo.demo.js b/staff/carlos-tomas/unsocial/compo.demo.js new file mode 100644 index 00000000..e0c9320d --- /dev/null +++ b/staff/carlos-tomas/unsocial/compo.demo.js @@ -0,0 +1,31 @@ +var page = new Compo(document.body) + +var title = new Heading("Compo", 1) +page.add(title) + +{ + var inputTitle = new Heading("Input", 2) + page.add(inputTitle) + + var input = new Input("password", "password") + page.add(input) + var linkTitle = new Heading("Link", 2) + page.add(linkTitle) + +} + +{ + var passwordInputTitle = new Heading("PasswordInput") + page.add(passwordInputTitle) + + var link = new Link("Google") + page.add(link) +} + +{ + var passwordInputTitle = new Heading("PasswordInput", 2) + page.add(passwordInputTitle) + + var passwordInput = new passwordInput("password") + page.add(passwordInput) +} \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial/compo.js b/staff/carlos-tomas/unsocial/compo.js index 56a259c4..a1d33009 100644 --- a/staff/carlos-tomas/unsocial/compo.js +++ b/staff/carlos-tomas/unsocial/compo.js @@ -1,37 +1,41 @@ /** * Constructs Compo instances + * * @param {HTMLElement} container The DOM container of the Compo instance */ function Compo(container) { this.children = [] this.container = container -} - -Compo.prototype.add = function (child) { - this.children.push(child) // Par poder montar nuestro comcepto - this.container.appendChild(child.container) //Para poder montar el HTML -} -Compo.prototype.remove = function () { - this.container.remove() + this.parent = null } Compo.prototype.add = function (child) { this.children.push(child) + child.parent = this + this.container.appendChild(child.container) } Compo.prototype.remove = function () { + var index = this.parent.children.findIndex(function (child) { + return child === this + }.bind(this)) + + if (index > -1) + this.parent.children.splice(index, 1) + this.container.remove() } Compo.prototype.addBehavior = function (type, callback) { this.container.addEventListener(type, callback) } + /** - * Construcus Form instances + * Constructs Form instances */ function Form() { - Compo.call(this, document.createElement("form")) + Compo.call(this, document.createElement('form')) } Form.prototype = Object.create(Compo.prototype) @@ -43,11 +47,12 @@ Form.prototype.reset = function () { /** * Constructs Button instances + * * @param {string} text The text of the button - * @param {string} type The button type + * @param {string} type The button type */ function Button(text, type) { - Compo.call(this, document.createElement("button")) + Compo.call(this, document.createElement('button')) this.container.innerText = text this.container.type = type @@ -56,6 +61,7 @@ function Button(text, type) { Button.prototype = Object.create(Compo.prototype) Button.prototype.constructor = Button + /** * Constructs Label instances * @@ -63,7 +69,7 @@ Button.prototype.constructor = Button * @param {string} id The id of the input to relate with */ function Label(text, id) { - Compo.call(this, document.createElement("label")) + Compo.call(this, document.createElement('label')) this.container.innerText = text this.container.htmlFor = id @@ -72,6 +78,7 @@ function Label(text, id) { Label.prototype = Object.create(Compo.prototype) Label.prototype.constructor = Label + /** * Constructs Input instances * @@ -79,7 +86,9 @@ Label.prototype.constructor = Label * @param {string} id The input id */ function Input(type, id) { - Compo.call(this, document.createElement("input")) + Compo.call(this, document.createElement('input')) + this.container.style.width = '100%' + this.container.style.boxSizing = 'border-box' this.container.type = type this.container.id = id @@ -96,6 +105,14 @@ Input.prototype.setValue = function (value) { this.container.value = value } +Input.prototype.getType = function () { + return this.container.type +} + +Input.prototype.setType = function (type) { + this.container.type = type +} + /** * Constructs Heading instances * @@ -125,3 +142,142 @@ function Link(text) { Link.prototype = Object.create(Compo.prototype) Link.prototype.constructor = Link + +/** + * Constructs Span instances + * + * @param {string} text The text inside span + */ +function Span(text) { + Compo.call(this, document.createElement('span')) + + this.container.innerText = text +} + +Span.prototype = Object.create(Compo.prototype) +Span.prototype.constructor = Span + +Span.prototype.setText = function (text) { + this.container.innerText = text +} + +Span.prototype.getText = function () { + return this.container.innerText +} + +/** + * Constructs PasswordInput instances + * + * @param {string} id The input id + */ +function PasswordInput(id) { + Compo.call(this, document.createElement('div')) + this.container.style.display = 'flex' + + var input = new Input('password', id) + input.container.style.paddingRight = '18px' + this.add(input) + + var span = new Span('😌') + span.container.style.cursor = 'pointer' + span.container.style.position = 'absolute' + span.container.style.right = '10px' + this.add(span) + + span.addBehavior('click', function () { + if (span.getText() === '😌') { + input.setType('text') + span.setText('😳') + } else { + input.setType('password') + span.setText('😌') + } + }) +} + +PasswordInput.prototype = Object.create(Compo.prototype) +PasswordInput.prototype.constructor = PasswordInput + +PasswordInput.prototype.getValue = function () { + return this.children[0].container.value +} + + +PasswordInput.prototype.setValue = function (value) { + this.container.value = value +} + +/** + * + */ +function UnorderedList() { + Compo.call(this, document.createElement('ul')) +} + +UnorderedList.prototype = Object.create(Compo.prototype) +UnorderedList.prototype.constructor = UnorderedList + +/** + * + */ +function ListItem() { + Compo.call(this, document.createElement('li')) +} + +ListItem.prototype = Object.create(Compo.prototype) +ListItem.prototype.constructor = ListItem + +/** + * + */ +function Image(address) { + Compo.call(this, document.createElement('img')) + + this.container.src = address + this.container.style.width = '100%' +} + +Image.prototype = Object.create(Compo.prototype) +Image.prototype.constructor = Image + +/** + * + * @param {*} text + */ +function Paragraph(text) { + Compo.call(this, document.createElement('p')) + + this.container.innerText = text +} + +Paragraph.prototype = Object.create(Compo.prototype) +Paragraph.prototype.constructor = Paragraph + +Paragraph.prototype.setText = function (text) { + this.container.innerText = text +} + +Paragraph.prototype.getText = function () { + return this.container.innerText +} + +/** + * + * @param {*} text + */ +function Time(text) { + Compo.call(this, document.createElement('time')) + + this.container.innerText = text +} + +Time.prototype = Object.create(Compo.prototype) +Time.prototype.constructor = Time + +Time.prototype.setText = function (text) { + this.container.innerText = text +} + +Time.prototype.getText = function () { + return this.container.innerText +} \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial/data.js b/staff/carlos-tomas/unsocial/data.js index 7478bdcb..b6ba264d 100644 --- a/staff/carlos-tomas/unsocial/data.js +++ b/staff/carlos-tomas/unsocial/data.js @@ -1,4 +1,19 @@ var users = [ { name: 'Peter Pan', email: 'peter@pan.com', username: 'peterpan', password: '123123123' }, { name: 'Wendy Darling', email: 'wendy@darling.com', username: 'wendydarling', password: '123123123' } +] + +var posts = [ + { + image: 'https://i.pinimg.com/originals/8c/60/1a/8c601a25311a1a5098896f751a784b54.jpg', + text: 'here we are', + username: 'peterpan', + date: new Date + }, + { + image: 'https://pm1.aminoapps.com/8360/ad07e2d2cdf6e1733328d6e7b7848b87db38a2bbr1-1536-2048v2_hq.jpg', + text: 'here i am', + username: 'wendydarling', + date: new Date + } ] \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial/logic.js b/staff/carlos-tomas/unsocial/logic.js index edb64111..e9c0c201 100644 --- a/staff/carlos-tomas/unsocial/logic.js +++ b/staff/carlos-tomas/unsocial/logic.js @@ -41,4 +41,24 @@ function authenticateUser(username, password) { throw new Error('wrong credentials') return user +} + +function createPost(username, image, text) { + if (username.length < 4 || username.length > 12) + throw new Error('invalid username') + + // TODO input validation (and throw error) + + var post = { + image: image, + text: text, + username: username, + date: new Date + } + + posts.push(post) +} + +function getPosts() { + return posts } \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial/main.js b/staff/carlos-tomas/unsocial/main.js index 8f119fcc..266e3f38 100644 --- a/staff/carlos-tomas/unsocial/main.js +++ b/staff/carlos-tomas/unsocial/main.js @@ -7,3 +7,6 @@ page.add(title) var login = new Login() page.add(login) + + +var home \ No newline at end of file diff --git a/staff/carlos-tomas/unsocial/style.css b/staff/carlos-tomas/unsocial/style.css index 8b8fe271..a584c865 100644 --- a/staff/carlos-tomas/unsocial/style.css +++ b/staff/carlos-tomas/unsocial/style.css @@ -30,7 +30,6 @@ input { width: 20px; max-width: 500px; min-width: 300px; - margin: 15px auto; border-radius: 10px; } diff --git a/staff/carlos-tomas/unsocial/view.js b/staff/carlos-tomas/unsocial/view.js index 823b0b87..2b5a94bc 100644 --- a/staff/carlos-tomas/unsocial/view.js +++ b/staff/carlos-tomas/unsocial/view.js @@ -2,25 +2,23 @@ * Constructs Login instances */ function Login() { - Compo.call(this, document.createElement("Section")) - - var compo = this + Compo.call(this, document.createElement('section')) - var title = new Heading("Login", 2) - compo.add(title) + var title = new Heading('Login', 2) + this.add(title) var form = new Form() - compo.add(form) + this.add(form) - form.add(new Label("Username", "username")) - var usernameInput = new Input("text", ' username') + form.add(new Label('Username', 'username')) + var usernameInput = new Input('text', 'username') form.add(usernameInput) form.add(new Label('Password', 'password')) - var passwordInput = new Input('password', 'password') + var passwordInput = new PasswordInput('password') form.add(passwordInput) - var submitButton = new Button("Login", "submit") + var submitButton = new Button('Login', 'submit') form.add(submitButton) form.addBehavior('submit', function (event) { @@ -34,33 +32,33 @@ function Login() { form.reset() - compo.remove() + this.remove() - var home = new Home() + home = new Home() page.add(home) } catch (error) { - passwordInput.setValue('') alert(error.message) console.error(error) } - }) + }.bind(this)) + var registerLink = new Link('Register') - compo.add(registerLink) + this.add(registerLink) registerLink.addBehavior('click', function (event) { event.preventDefault() - compo.remove() + this.remove() var register = new Register() page.add(register) - }) + }.bind(this)) } Login.prototype = Object.create(Compo.prototype) @@ -72,13 +70,11 @@ Login.prototype.constructor = Login function Register() { Compo.call(this, document.createElement('section')) - var compo = this - var title = new Heading('Register', 2) - compo.add(title) + this.add(title) var form = new Form() - compo.add(form) + this.add(form) form.add(new Label('Name', 'name')) var nameInput = new Input('text', 'name') @@ -93,11 +89,11 @@ function Register() { form.add(usernameInput) form.add(new Label('Password', 'password')) - var passwordInput = new Input('password', 'password') + var passwordInput = new PasswordInput('password') form.add(passwordInput) form.add(new Label('Repeat Password', 'password-repeat')) - var passwordRepeatInput = new Input('password', 'password-repeat') + var passwordRepeatInput = new PasswordInput('password-repeat') form.add(passwordRepeatInput) var submitButton = new Button('Register', 'submit') @@ -117,7 +113,7 @@ function Register() { form.reset() - compo.remove() + this.remove() page.add(login) } catch (error) { @@ -125,19 +121,19 @@ function Register() { console.error(error) } - - }) + }.bind(this)) var loginLink = new Link('Login') - compo.add(loginLink) + this.add(loginLink) loginLink.addBehavior('click', function (event) { event.preventDefault() - compo.remove() + this.remove() page.add(login) - }) + }.bind(this)) } + Register.prototype = Object.create(Compo.prototype) Register.prototype.constructor = Register @@ -147,28 +143,131 @@ Register.prototype.constructor = Register function Home() { Compo.call(this, document.createElement('section')) - var compo = this - var title = new Heading('Home', 2) - compo.add(title) - + this.add(title) var userTitle = new Heading('Hello, ' + loggedInUser.name + '!', 3) - compo.add(userTitle) + this.add(userTitle) var logoutButton = new Button('Logout', 'button') - compo.add(logoutButton) + this.add(logoutButton) logoutButton.addBehavior('click', function (event) { - event.preventDefault() // Parar cargar la paguina web + event.preventDefault() loggedInUser = null - compo.remove() + this.remove() + + page.add(login) + }.bind(this)) + + var addPostButton = new Button('➕', 'button') + this.add(addPostButton) - page.add(login)// LLamar al body a la login Section - }) + addPostButton.addBehavior('click', function () { + var createPost = new CreatePost() + + //postList.remove() + this.children[this.children.length - 1].remove() + + this.add(createPost) + }.bind(this)) + + var postList = new PostList() + this.add(postList) } Home.prototype = Object.create(Compo.prototype) -Home.prototype.constructor = Home \ No newline at end of file +Home.prototype.constructor = Home + +function CreatePost() { + Compo.call(this, document.createElement('div')) + + var title = new Heading('Create Post', 3) + this.add(title) + + var form = new Form() + + var imageLabel = new Label('Image', 'image') + var imageInput = new Input('text', 'image') + form.add(imageLabel) + form.add(imageInput) + + var textLabel = new Label('Text', 'text') + var textInput = new Input('text', 'text') + form.add(textLabel) + form.add(textInput) + + var submitButton = new Button('Create', 'submit') + form.add(submitButton) + + this.add(form) + + form.addBehavior('submit', function (event) { + event.preventDefault() + + var image = imageInput.getValue() + var text = textInput.getValue() + + try { + createPost(loggedInUser.username, image, text) + + this.remove() + + var postList = new PostList() + home.add(postList) + } catch (error) { + alert(error.message) + + console.error(error) + } + + }.bind(this)) +} + +CreatePost.prototype = Object.create(Compo.prototype) +CreatePost.prototype.constructor = CreatePost + +function Post(username, image, text, date) { + Compo.call(this, document.createElement('div')) + + var userTitle = new Heading(username, 4) + this.add(userTitle) + + var picture = new Image(image) + this.add(picture) + + var comment = new Paragraph(text) + this.add(comment) + + var time = new Time(date) + this.add(time) +} + +Post.prototype = Object.create(Compo.prototype) +Post.prototype.constructor = Post + +function PostList() { + Compo.call(this, document.createElement('div')) + + var title = new Heading('Posts', 3) + this.add(title) + + try { + var posts = getPosts().toReversed() + + posts.forEach(function (post) { + var _post = new Post(post.username, post.image, post.text, post.date) + + this.add(_post) + }.bind(this)) + } catch (error) { + alert(error.message) + + console.error(error) + } +} + +PostList.prototype = Object.create(Compo.prototype) +PostList.prototype.constructor = PostList \ No newline at end of file