diff --git a/projects/evaluate-news-nlp/src/server/index.js b/projects/evaluate-news-nlp/src/server/index.js index c4973aebb..0ea94a65d 100755 --- a/projects/evaluate-news-nlp/src/server/index.js +++ b/projects/evaluate-news-nlp/src/server/index.js @@ -1,23 +1,23 @@ -var path = require('path') -const express = require('express') -const mockAPIResponse = require('./mockAPI.js') + path = require('path') + const express = require('express') + const mockAPIResponse = require('./mockAPI.js') -const app = express() + const app = express() -app.use(express.static('dist')) + app.use(express.static('dist')) -console.log(__dirname) + console.log(__dirname) -app.get('/', function (req, res) { - // res.sendFile('dist/index.html') - res.sendFile(path.resolve('src/client/views/index.html')) -}) + app.get('/', function(req, res) { + // res.sendFile('dist/index.html') + res.sendFile(path.resolve('src/client/views/index.html')) + }) -// designates what port the app will listen to for incoming requests -app.listen(8080, function () { - console.log('Example app listening on port 8080!') -}) + // designates what port the app will listen to for incoming requests + app.listen(8080, function() { + console.log('Example app listening on port 8080!') + }) -app.get('/test', function (req, res) { - res.send(mockAPIResponse) -}) + app.get('/test', function(req, res) { + res.send(mockAPIResponse) + }) \ No newline at end of file diff --git a/projects/landing-page.zip b/projects/landing-page.zip new file mode 100644 index 000000000..2b7757f07 Binary files /dev/null and b/projects/landing-page.zip differ diff --git a/projects/landing-page/README.md b/projects/landing-page/README.md index 3282de7b9..9d4bb4bd7 100755 --- a/projects/landing-page/README.md +++ b/projects/landing-page/README.md @@ -1,13 +1,35 @@ # Landing Page Project +A landing page project that involes using the `js/app.js` file to covert the static version of the landing page project to a more interactive one. + ## Table of Contents -* [Instructions](#instructions) +* [Description](#Description) +* [Process](#Process) +* [Dependencies](#Dependencies) + +## Description + +The starter project has some HTML and CSS styling to display a static version of the Landing Page project. I converted this project from a static project to an interactive one. It required modifying the HTML and CSS files, but primarily the JavaScript file. + +To get started, open `js/app.js` and view the app's functionality + +For specific, detailed instructions linking to this project, look at the project instructions in the Udacity Classroom. + +## Process + +Firstly, I linked the `js/app.js` to the `index.html`. + +I created a **fourth** content section in the `index.html`. + +I created the helper functions to create the **list** for the nav-bar, then I created the **active class** scroll for the section and lastly for the helper function I created the **scrollTo** function for when you click a link. + +Then I worked on the main functions. I used the main functions to basically call the helper functions that work the same. -## Instructions +Finally, I begin events by calling the main functions. -The starter project has some HTML and CSS styling to display a static version of the Landing Page project. You'll need to convert this project from a static project to an interactive one. This will require modifying the HTML and CSS files, but primarily the JavaScript file. +In summary, I built the menu bar, created a **scrollTo** link to the **sections** and lastly I created an **active class** scroll function. -To get started, open `js/app.js` and start building out the app's functionality +## Dependencies +I used a starter-code from *[refresh-2019](https://github.com/udacity/fend/tree/refresh-2019/projects/landing-page)* -For specific, detailed instructions, look at the project instructions in the Udacity Classroom. diff --git a/projects/landing-page/css/styles.css b/projects/landing-page/css/styles.css index 16145e98c..7c048ca8c 100755 --- a/projects/landing-page/css/styles.css +++ b/projects/landing-page/css/styles.css @@ -1,4 +1,4 @@ -/* + /* * * CSS written based on SMACSS architecture. * To learn more, visit: http://smacss.com/ @@ -7,217 +7,226 @@ * To learn more, visit: https://css-tricks.com/reboot-resets-reasoning/ * */ - - -/* ---- Base Rules ---- */ -body { - background: rgb(136,203,171); - background: linear-gradient(0deg, rgba(136,203,171,1) 0%, rgba(0,13,60,1) 100%); - margin: 0; - font-family: 'Merriweather', serif; - color: #fff; -} - - -/* Typeography General*/ -h1 { - font-family: 'Fira Sans', sans-serif; - font-size: 3em; - margin: 2em 1rem; -} - -@media only screen and (min-width: 35em){ + /* ---- Base Rules ---- */ + + body { + background: rgb(136, 203, 171); + background: linear-gradient(0deg, rgba(136, 203, 171, 1) 0%, rgba(0, 13, 60, 1) 100%); + margin: 0; + font-family: 'Merriweather', serif; + color: #fff; + } + /* Typeography General*/ + h1 { - font-size: 7em; - margin: 2em 4rem 1em; - } -} - -h2 { - border-bottom: 1px solid #cc1; - font-family: 'Oxygen', Sans-Serif; - font-size: 3em; - color: #fff; -} - -p { - line-height: 1.6em; - color: #eee; -} - -/* ---- Layout Rules ---- */ -main { - margin: 10vh 1em 10vh; -} - -.main-hero { - min-height: 40vh; - padding-top: 3em; -} - -section { - position: relative; - min-height: 80vh; -} - - -/* ---- Module Rules ---- */ - -/* Navigation Styles*/ -.navbar__menu ul { - padding-left: 0; - margin: 0; - text-align: right; -} - -.navbar__menu li { - display: inline-block; -} - -.navbar__menu .menu__link { - display: block; - padding: 1em; - font-weight: bold; - text-decoration: none; - color: #000; -} - -.navbar__menu .menu__link:hover { - background: #333; - color: #fff; - transition: ease 0.3s all; -} - -/* Header Styles */ -.page__header { - background: #fff; - position: fixed; - top: 0; - width: 100%; - z-index: 5; -} - -/* Footer Styles */ -.page__footer { - background: #000; - padding: 3em; - color: #fff; -} - -.page__footer p{ - color: #fff; -} - - -/* ---- Theme Rules ---- */ -/* Landing Container Styles */ -.landing__container { - padding: 1em; - text-align: left; -} - -@media only screen and (min-width: 35em){ + font-family: 'Fira Sans', sans-serif; + font-size: 3em; + margin: 2em 1rem; + } + + @media only screen and (min-width: 35em) { + h1 { + font-size: 7em; + margin: 2em 4rem 1em; + } + } + + h2 { + border-bottom: 1px solid #cc1; + font-family: 'Oxygen', Sans-Serif; + font-size: 3em; + color: #fff; + } + + p { + line-height: 1.6em; + color: #eee; + } + /* ---- Layout Rules ---- */ + + main { + margin: 10vh 1em 10vh; + } + + .main-hero { + min-height: 40vh; + padding-top: 3em; + } + + section { + position: relative; + min-height: 80vh; + } + /* ---- Module Rules ---- */ + /* Navigation Styles*/ + + .navbar__menu ul { + padding-left: 0; + margin: 0; + text-align: right; + } + + .navbar__menu li { + display: inline-block; + } + + .navbar__menu .menu__link { + /* display: block; */ + padding: 1em; + font-weight: bold; + text-decoration: none; + color: #000; + } + + .navbar__menu .menu__link-active { + background: #333; + color: #fff; + transition: ease 0.3s all; + } + /* Header Styles */ + + .page__header { + background: #fff; + position: fixed; + top: 0; + width: 100%; + z-index: 5; + } + /* Footer Styles */ + + .page__footer { + background: #000; + padding: 3em; + color: #fff; + } + + .page__footer p { + color: #fff; + } + /* ---- Theme Rules ---- */ + /* Landing Container Styles */ + .landing__container { - max-width: 50em; - padding: 4em; - } -} - -section:nth-of-type(even) .landing__container { - margin-right: 0; - margin-left: auto; - text-align: right; -} - -/* Background Circles */ -/* Note that background circles are created with psuedo elements before and after */ -/* Circles appear to be random do to use of :nth-of-type psuedo class */ -section:nth-of-type(odd) .landing__container::before { - content: ''; - background: rgba(255, 255, 255, 0.187); - position: absolute; - z-index: -5; - width: 20vh; - height: 20vh; - border-radius: 50%; - opacity: 0; - transition: ease 0.5s all; -} - -section:nth-of-type(even) .landing__container::before { - content: ''; - background: rgb(255,255,255); - background: linear-gradient(0deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.2) 100%); - position: absolute; - top: 3em; - right: 3em; - z-index: -5; - width: 10vh; - height: 10vh; - border-radius: 50%; - opacity: 0; - transition: ease 0.5s all; -} - -section:nth-of-type(3n) .landing__container::after { - content: ''; - background: rgb(255,255,255); - background: linear-gradient(0deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.2) 100%); - position: absolute; - right: 0; - bottom: 0; - z-index: -5; - width: 10vh; - height: 10vh; - border-radius: 50%; - opacity: 0; - transition: ease 0.5s all; -} - -section:nth-of-type(3n + 1) .landing__container::after { - content: ''; - background: rgb(255,255,255); - background: linear-gradient(0deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.2) 100%); - position: absolute; - right: 20vw; - bottom: -5em; - z-index: -5; - width: 15vh; - height: 15vh; - border-radius: 50%; - opacity: 0; - transition: ease 0.5s all; -} - - -/* ---- Theme State Rules ---- */ -/* Section Active Styles */ -/* Note: your-active-class class is applied through javascript. You should update the class here and in the index.html to what you set in your javascript file. */ -section.your-active-class { - background: rgb(0, 0, 0); - background: linear-gradient(0deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 100%); -} - -section.your-active-class .landing__container::before { - opacity: 1; - animation: rotate 4s linear 0s infinite forwards; -} - -section.your-active-class .landing__container::after { - opacity: 1; - animation: rotate 5s linear 0s infinite forwards reverse; -} - -/* Section Active Styles Keyframe Animations */ -@keyframes rotate { - from { - transform: rotate(0deg) - translate(-1em) - rotate(0deg); - } - to { - transform: rotate(360deg) - translate(-1em) - rotate(-360deg); - } -} \ No newline at end of file + padding: 1em; + text-align: left; + } + + @media only screen and (min-width: 35em) { + .landing__container { + max-width: 50em; + padding: 4em; + } + } + + section:nth-of-type(even) .landing__container { + margin-right: 0; + margin-left: auto; + text-align: right; + } + /* Background Circles */ + /* Note that background circles are created with psuedo elements before and after */ + /* Circles appear to be random do to use of :nth-of-type psuedo class */ + + section:nth-of-type(odd) .landing__container::before { + content: ''; + background: rgba(255, 255, 255, 0.187); + position: absolute; + z-index: -5; + width: 20vh; + height: 20vh; + border-radius: 50%; + opacity: 0; + transition: ease 0.5s all; + } + + section:nth-of-type(even) .landing__container::before { + content: ''; + background: rgb(255, 255, 255); + background: linear-gradient(0deg, rgba(255, 255, 255, .1) 0%, rgba(255, 255, 255, .2) 100%); + position: absolute; + top: 3em; + right: 3em; + z-index: -5; + width: 10vh; + height: 10vh; + border-radius: 50%; + opacity: 0; + transition: ease 0.5s all; + } + + section:nth-of-type(3n) .landing__container::after { + content: ''; + background: rgb(255, 255, 255); + background: linear-gradient(0deg, rgba(255, 255, 255, .1) 0%, rgba(255, 255, 255, .2) 100%); + position: absolute; + right: 0; + bottom: 0; + z-index: -5; + width: 10vh; + height: 10vh; + border-radius: 50%; + opacity: 0; + transition: ease 0.5s all; + } + + section:nth-of-type(3n + 1) .landing__container::after { + content: ''; + background: rgb(255, 255, 255); + background: linear-gradient(0deg, rgba(255, 255, 255, .1) 0%, rgba(255, 255, 255, .2) 100%); + position: absolute; + right: 20vw; + bottom: -5em; + z-index: -5; + width: 15vh; + height: 15vh; + border-radius: 50%; + opacity: 0; + transition: ease 0.5s all; + } + /* ---- Theme State Rules ---- */ + /* Section Active Styles */ + /* Note: your-active-class class is applied through javascript. You should update the class here and in the index.html to what you set in your javascript file. */ + + section.your-active-class { + background: rgb(0, 0, 0); + background: linear-gradient(0deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 100%); + } + + section.your-active-class .landing__container::before { + opacity: 1; + animation: rotate 4s linear 0s infinite forwards; + } + + section.your-active-class .landing__container::after { + opacity: 1; + animation: rotate 5s linear 0s infinite forwards reverse; + } + /* Section Active Styles Keyframe Animations */ + + @keyframes rotate { + from { + transform: rotate(0deg) translate(-1em) rotate(0deg); + } + to { + transform: rotate(360deg) translate(-1em) rotate(-360deg); + } + } + /* Responsive class for the nav-bar */ + + @media (max-width: 600px) { + .navbar__menu ul { + text-align: center; + } + .navbar__menu .menu__link { + font-size: 13px; + } + } + + @media (max-width: 280px) { + .navbar__menu .menu__link { + font-size: 10px; + } + .navbar__menu .menu__link { + padding: 0.5em; + } + } \ No newline at end of file diff --git a/projects/landing-page/index.html b/projects/landing-page/index.html index baadb068a..c7026824d 100755 --- a/projects/landing-page/index.html +++ b/projects/landing-page/index.html @@ -1,59 +1,83 @@ + - - - - Manipulating the DOM - - - + + + + Manipulating the DOM + + + + + - - -
-
-

Landing Page

+ - -
-
-

Section 1

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.

+
+
+

Section 1

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci + eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam + in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.

-

Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet porttitor tortor, eget elementum tortor mollis non.

-
-
-
-
-

Section 2

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.

+

Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet + porttitor tortor, eget elementum tortor mollis non.

+
+
+
+
+

Section 2

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci + eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam + in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.

-

Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet porttitor tortor, eget elementum tortor mollis non.

-
-
-
-
-

Section 3

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.

+

Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet + porttitor tortor, eget elementum tortor mollis non.

+
+
+
+
+

Section 3

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci + eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam + in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.

-

Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet porttitor tortor, eget elementum tortor mollis non.

-
-
-
- +

Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet + porttitor tortor, eget elementum tortor mollis non.

+ + +
+
+

Section 4

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi fermentum metus faucibus lectus pharetra dapibus. Suspendisse potenti. Aenean aliquam elementum mi, ac euismod augue. Donec eget lacinia ex. Phasellus imperdiet porta orci + eget mollis. Sed convallis sollicitudin mauris ac tincidunt. Donec bibendum, nulla eget bibendum consectetur, sem nisi aliquam leo, ut pulvinar quam nunc eu augue. Pellentesque maximus imperdiet elit a pharetra. Duis lectus mi, aliquam + in mi quis, aliquam porttitor lacus. Morbi a tincidunt felis. Sed leo nunc, pharetra et elementum non, faucibus vitae elit. Integer nec libero venenatis libero ultricies molestie semper in tellus. Sed congue et odio sed euismod.

+

Aliquam a convallis justo. Vivamus venenatis, erat eget pulvinar gravida, ipsum lacus aliquet velit, vel luctus diam ipsum a diam. Cras eu tincidunt arcu, vitae rhoncus purus. Vestibulum fermentum consectetur porttitor. Suspendisse imperdiet + porttitor tortor, eget elementum tortor mollis non.

+
+
+ + + - + + \ No newline at end of file diff --git a/projects/landing-page/js/app.js b/projects/landing-page/js/app.js index f52ee8672..2e547b3a5 100755 --- a/projects/landing-page/js/app.js +++ b/projects/landing-page/js/app.js @@ -11,24 +11,59 @@ * * JS Standard: ESlint * -*/ + */ /** * Comments should be present at the beginning of each procedure and class. * Great to have comments before crucial code sections within the procedure. -*/ + */ /** * Define Global Variables * -*/ - + */ +const ul = document.querySelector('#navbar__list'); +const sections = Array.from(document.getElementsByTagName("section")); /** * End Global Variables * Start Helper Functions * -*/ + */ + +const link = function() { + for (let section of sections) { + const li = document.createElement('li'); + const a = document.createElement('a'); + // use the section data-nav to fill the tag + a.innerHTML = section.dataset.nav; + li.append(a); + li.classList.add('menu__link'); + ul.appendChild(li); + } +} + +/** + * @desc Loop over an li in the document and remove it's active class + * @param $items - All the li in the document + */ +function removeSelected(items) { + for (let i = 0; i < items.length; i++) { + items[i].classList.remove('menu__link-active'); + } +} + +/** + * @desc Loop over the sections in the document and remove it's active class + * @param $items - All the sections in the document + */ +function removeSectionClass(items) { + for (let i = 0; i < items.length; i++) { + if (items[i].className == 'your-active-class') { + items[i].classList.remove('your-active-class'); + } + } +} @@ -36,27 +71,61 @@ * End Helper Functions * Begin Main Functions * -*/ - -// build the nav - + */ + + +// build the nav and add Scroll to anchor ID using scrollTO event +link() +const li = document.querySelectorAll('li') +const menu = () => { + + li.forEach((item) => { + item.addEventListener('click', function(e) { + e.preventDefault(); + removeSelected(li); + this.classList.add('menu__link-active'); + for (let section of sections) { + if (item.innerText == section.dataset.nav) { + window.scrollTo({ + // top: num.getBoundingClientRect().top, + top: section.offsetTop, + behavior: 'smooth' + }) + } + } + }); + }); +} // Add class 'active' to section when near top of viewport +const scrollY = function() { + document.addEventListener('scroll', function() { + for (let section of sections) { + if (section.getBoundingClientRect().top <= 443) { + removeSectionClass(sections) + section.classList.add('your-active-class'); + + li.forEach((item) => { + if (item.innerText == section.dataset.nav) { + removeSelected(li); + item.classList.add('menu__link-active'); + } + }) + } + } + }) +} -// Scroll to anchor ID using scrollTO event /** * End Main Functions * Begin Events * -*/ - -// Build menu - -// Scroll to section on link click - -// Set sections as active - + */ +// Build menu and Scroll to section on link click +menu() + // Set sections as active +scrollY() \ No newline at end of file diff --git a/projects/weather-journal-app.zip b/projects/weather-journal-app.zip new file mode 100644 index 000000000..2710031c5 Binary files /dev/null and b/projects/weather-journal-app.zip differ diff --git a/projects/weather-journal-app/commentsOnlyJS/app.js b/projects/weather-journal-app/commentsOnlyJS/app.js deleted file mode 100644 index fa3603825..000000000 --- a/projects/weather-journal-app/commentsOnlyJS/app.js +++ /dev/null @@ -1,12 +0,0 @@ -// Personal API Key for OpenWeatherMap API - -// Event listener to add function to existing HTML DOM element - -/* Function called by event listener */ - -/* Function to GET Web API Data*/ - -/* Function to POST data */ - - -/* Function to GET Project Data */ diff --git a/projects/weather-journal-app/commentsOnlyJS/server.js b/projects/weather-journal-app/commentsOnlyJS/server.js deleted file mode 100644 index 57288119e..000000000 --- a/projects/weather-journal-app/commentsOnlyJS/server.js +++ /dev/null @@ -1,22 +0,0 @@ -// Setup empty JS object to act as endpoint for all routes -// Express to run server and routes - -// Start up an instance of app - -/* Dependencies */ -/* Middleware*/ - -//Here we are configuring express to use body-parser as middle-ware. -// Cors for cross origin allowance - -// Initialize the main project folder - -// Spin up the server -// Callback to debug - -// Initialize all route with a callback function - -// Callback function to complete GET '/all' - -// Post Route - \ No newline at end of file diff --git a/projects/weather-journal-app/package.json b/projects/weather-journal-app/package.json new file mode 100644 index 000000000..148b2c99a --- /dev/null +++ b/projects/weather-journal-app/package.json @@ -0,0 +1,17 @@ +{ + "name": "weather-journal-app", + "version": "1.0.0", + "description": "An app to get temperature using id code", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "author": "Richard Tamnunotonye", + "license": "ISC", + "dependencies": { + "body-parser": "^1.20.0", + "cors": "^2.8.5", + "express": "^4.18.1" + } +} \ No newline at end of file diff --git a/projects/weather-journal-app/server.js b/projects/weather-journal-app/server.js index 4ac0e2b2c..19b648a13 100644 --- a/projects/weather-journal-app/server.js +++ b/projects/weather-journal-app/server.js @@ -1,9 +1,14 @@ // Setup empty JS object to act as endpoint for all routes projectData = {}; -// Require Express to run server and routes +/* Express to run server and routes */ +const express = require('express'); -// Start up an instance of app +/* Start up an instance of app */ +const app = express(); + +/* Dependencies */ +const bodyParser = require('body-parser'); /* Middleware*/ //Here we are configuring express to use body-parser as middle-ware. @@ -11,9 +16,35 @@ app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); // Cors for cross origin allowance +const cors = require('cors'); +app.use(cors()); // Initialize the main project folder app.use(express.static('website')); +const port = 3000; +// Spin up the server +const server = app.listen(port, listening); + +function listening() { + console.log(`running on localhost: ${port}`); +}; + +// Callback function to complete GET '/all' +app.get('/all', sendData); + +function sendData(req, res) { + res.send(projectData); + console.log(projectData) +}; +// Post Route +app.post('/addData', addData); -// Setup Server \ No newline at end of file +function addData(req, res) { + newData = req.body; + projectData['temperature'] = newData.temperature; + projectData['date'] = newData.date; + projectData['res'] = newData.feel; + res.send(projectData); + console.log('This is your data retrieved' + projectData); +} \ No newline at end of file diff --git a/projects/weather-journal-app/website/app.js b/projects/weather-journal-app/website/app.js index f638db000..98ca2ae2f 100644 --- a/projects/weather-journal-app/website/app.js +++ b/projects/weather-journal-app/website/app.js @@ -1,5 +1,78 @@ -/* Global Variables */ +// Api url for Open weather map +const url = 'https://api.openweathermap.org/data/2.5/weather?zip='; +// Personal API Key for OpenWeatherMap API +const apiKey = ',{country code}&appid={API key}&units=imperial'; -// Create a new date instance dynamically with JS -let d = new Date(); -let newDate = d.getMonth()+'.'+ d.getDate()+'.'+ d.getFullYear(); \ No newline at end of file +// Event listener to add function to existing HTML DOM element +document.getElementById('generate').addEventListener('click', performAction); + +/* Function called by event listener */ +function performAction(e) { + const zip = document.getElementById('zip').value; + const response = document.getElementById('feelings').value; + if (zip && validateZipCode(zip)) { + getZip(url, zip, apiKey) + .then(function(data) { + // Add data + postData('/addData', { temperature: data.main.temp, date: data.dt, feel: response }) + .then(function() { + updateUI() + }); + }) + } else { + alert('zip code is invalid or not found, input a valid zip code') + } +}; + +// function to check if zip code is valid +const validateZipCode = function(elementValue) { + var zipCodePattern = /^\d{5}$|^\d{5}-\d{4}$/; + return zipCodePattern.test(elementValue); +} + +/* Function to GET Web API Data*/ +const getZip = async(url, zip, key) => { + const res = await fetch(url + zip + key); + + try { + const newData = await res.json(); + return newData + } catch (error) { + console.log('error', error); + } + } + /* Function to POST data */ +const postData = async(url = '', data = {}) => { + const response = await fetch(url, { + method: 'POST', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + // Body data type must match "Content-Type" header + body: JSON.stringify(data), + }); + + try { + const newData = await response.json(); + console.log(newData); + return newData; + } catch (error) { + console.log("error", error); + } +} + +/* Function to Update UI */ +const updateUI = async() => { + const request = await fetch('/all'); + try { + const allData = await request.json(); + let d = new Date(allData.date); + let newDate = d.getMonth() + 1 + '.' + d.getDate() + '.' + d.getFullYear(); + document.getElementById('temp').innerHTML = Math.round(allData.temperature) + 'degrees'; + document.getElementById('date').innerHTML = newDate + document.getElementById('content').innerHTML = allData.res; + } catch (error) { + console.log("error", error); + } +} \ No newline at end of file diff --git a/projects/weather-journal-app/website/index.html b/projects/weather-journal-app/website/index.html index 3649e0f73..bcd63d9ba 100644 --- a/projects/weather-journal-app/website/index.html +++ b/projects/weather-journal-app/website/index.html @@ -1,35 +1,41 @@ + - -Weather Journal - - + + Weather Journal + + - -
-
- Weather Journal App -
-
- - -
-
- - - -
-
-
Most Recent Entry
-
-
-
-
-
-
-
- + + +
+
+ Weather Journal App +
+
+ + +
+
+ +
+ + +
+ +
+
+
Most Recent Entry
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/projects/weather-journal-app/website/style.css b/projects/weather-journal-app/website/style.css index 0523ebd24..4362447bc 100644 --- a/projects/weather-journal-app/website/style.css +++ b/projects/weather-journal-app/website/style.css @@ -1,70 +1,71 @@ -body{ +body { background: #fffff8; font-family: -apple-system, BlinkMacSystemFont, sans-serif; } -#app{ +#app { display: grid; grid-auto-rows: minmax(150px, auto); /* grid-template-columns: */ - height:100vh; background: #f23557; color: #f0d43a; justify-content: center; - grid-gap: 1em; + grid-gap: 2em; font-size: 20px; font-family: 'Oswald', sans-serif; } -.holder{ +.holder {} -} - -.entry{ +.entry { background: rgba(59, 74, 107, .4); } -#entryHolder{ +#entryHolder {} -} +#date {} -#date{ +#temp {} +#flex { + display: flex; + flex-wrap: wrap; + position: relative; + width: 900px; } -#temp{ - +#generate { + position: absolute; + right: 0; + bottom: 0; } -#content{ +#content {} -} +.headline {} -.headline { +.title {} -} -.title{ - -} /* Basic Styling To Override Default For Basic HTML Elements */ -label{ - display:block; + +label { + display: block; font-size: 27px; } -input{ - display:block; +input { + display: block; height: 60px; width: 320px; - background:#22b2da; + background: #22b2da; color: #f0d43a; font-size: 20px; font-family: 'Oswald', sans-serif; border: none; } -button{ +button { width: 400px; height: 100px; background: #3b4a6b; @@ -74,38 +75,45 @@ button{ border: none; box-shadow: 2px 4px 5px #444; } -h1{ + +h1 { font-size: 36px; } -textarea{ - background:#22b2da; +textarea { + background: #22b2da; color: #f0d43a; font-size: 20px; font-family: 'Oswald', sans-serif; } + + /* Reset style for HTML element on active to have no border*/ + input:focus, select:focus, textarea:focus, button:focus { outline: none; } + + /* Style for Placeholder Text*/ -::placeholder { /* Firefox, Chrome, Opera */ - color: #f0d43a; - font-family: 'Oswald', sans-serif; -} - -:-ms-input-placeholder { /* Internet Explorer 10-11 */ - color: #f0d43a; +::placeholder { + /* Firefox, Chrome, Opera */ + color: #f0d43a; font-family: 'Oswald', sans-serif; +} -} - -::-ms-input-placeholder { /* Microsoft Edge */ - color: #f0d43a; +:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: #f0d43a; font-family: 'Oswald', sans-serif; +} -} \ No newline at end of file +::-ms-input-placeholder { + /* Microsoft Edge */ + color: #f0d43a; + font-family: 'Oswald', sans-serif; +} \ No newline at end of file