From b2d0f547ed5068e5be3c0e70b25ae0e13d1ff350 Mon Sep 17 00:00:00 2001 From: brianschnee Date: Sat, 11 Jun 2022 19:41:18 -0400 Subject: [PATCH 1/9] added matches.ejs, started keyword fetch from client-side code --- public/css/style.css | 30 +++++++++++++++-- public/js/main.js | 23 ++++++++----- server.js | 30 +++++++++++------ views/index.ejs | 14 +++++++- views/matches.ejs | 80 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 23 deletions(-) create mode 100644 views/matches.ejs diff --git a/public/css/style.css b/public/css/style.css index 0798297..1483b62 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,5 +1,18 @@ @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;800&display=swap'); +/* +================= Base Styles ================= +*/ + +ul { + margin: 0; + list-style: none; +} + +/* +================= Additional Styles ================= +*/ + /* html */ html { @@ -130,7 +143,7 @@ main { display: flex; flex-wrap: wrap; flex-direction: column; - justify-content: space-between; + justify-content: space-around; align-items: center; } @@ -192,9 +205,20 @@ main { .result { width: 90%; - height: 70%; + height: 300px; border: dashed lightgray 2px; - border-radius: 25px; + /* border-radius: 25px; */ + overflow-y: auto; + overflow-x: hidden; +} + +.json { + display: block; + white-space: pre-wrap; +} + +.indent { + padding-left: 1rem; } /* documentation */ diff --git a/public/js/main.js b/public/js/main.js index c43718c..65e2169 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,14 +1,19 @@ -let resources; -fetchResources(); +// let resources; +// fetchResources(); -async function fetchResources() { - const response = await fetch(`/api/`); - const data = await response.json(); - resources = data; -} +// async function fetchResources() { +// const response = await fetch(`/api/`); +// const data = await response.json(); +// resources = data; +// } document.getElementById('keyword-btn').addEventListener('click', async () => { const keyword = document.querySelector('input').value; - const matches = await resources.filter((obj) => obj.keywords.some(str => str.includes(keyword))); - const list = document.getElementById('result-list'); + + try { + const res = await fetch(`/api/${keyword}`); + const data = await res.json(); + } catch (err) { + console.error(err); + } }); diff --git a/server.js b/server.js index 7639721..c308661 100644 --- a/server.js +++ b/server.js @@ -10,10 +10,14 @@ app.use(express.static(__dirname + '/public')); app.use('/public', express.static(__dirname + '/public')); app.get('/', (req, res) => { - if (resources) { - res.render('index.ejs', { resources }); - } else { - console.error('no resources found'); + try { + if (resources) { + res.render('index.ejs', { resources }); + } else { + throw new Error('Resources not found.') + } + } catch (err) { + console.error(err); } }); @@ -23,14 +27,20 @@ app.get('/api', (req, res) => { app.get('/api/:keyword', (req, res) => { const keyword = req.params.keyword.toLowerCase(); - + // filter resources array, return items that match query; tag. - const matches = resources.filter((obj) => obj.keywords.includes(keyword)); + const matches = resources.filter((obj) => obj.keywords.some(str => str.includes(keyword))); - if (matches.length > 0) { - res.json(matches); - } else { - throw new Error('Resource not found.'); + try { + // if matches were found, render matches.ejs / response with json else throw error + if (matches.length) { + res.render('matches.ejs', { matches }); + res.json(matches); + } else { + throw new Error('No resources found.'); + } + } catch(err) { + console.error(err); } }); diff --git a/views/index.ejs b/views/index.ejs index 88844cc..b5e994e 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -52,7 +52,19 @@
- +
diff --git a/views/matches.ejs b/views/matches.ejs new file mode 100644 index 0000000..a9ae817 --- /dev/null +++ b/views/matches.ejs @@ -0,0 +1,80 @@ + + + + + + + Resources API + + + + + + + + + + +
+ +
+
+

Coding Resources API-

+

+ Search for coding resources by relevant keywords. + This API serves educational content for a wide + variety of computer science topics, languages and + technologies relevant to web development. +

+
+
+
+ + +
+
+
    + <% for(let i = 0; i < matches.length; i++) { %> +
  • +
    +                                        
    +                                        {
    +                                        
    + name: <%= matches[i].name %>, + url: <%= matches[i].url %>, + keywords: [<%= matches[i].keywords %>] +
    + }
    +
    +
  • + <% } %> +
+
+
+
+
+

Documentation

+
+
+ + + From 7194f22bc62d522c19bf9b9df657b99ebbb7b65c Mon Sep 17 00:00:00 2001 From: Jacob Asper Date: Sat, 11 Jun 2022 19:50:20 -0400 Subject: [PATCH 2/9] fixed styling of code blocks --- views/index.ejs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views/index.ejs b/views/index.ejs index b5e994e..909f144 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -56,7 +56,8 @@ <% for(let i = 0; i < resources.length; i++) { %>
  • -										{
    + + {
    name: <%= resources[i].name %>, url: <%= resources[i].url %>, keywords: [<%= resources[i].keywords %>]
    From ac8544c3b9a55a61e8cc8fa87d581818c7236ec9 Mon Sep 17 00:00:00 2001 From: Jacob Asper Date: Sat, 11 Jun 2022 20:00:55 -0400 Subject: [PATCH 3/9] changed button type to button --- views/index.ejs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views/index.ejs b/views/index.ejs index 909f144..0be33bb 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -47,9 +47,10 @@ value="" placeholder="/api/'keyword'" /> - +
      From 67449fd38723790354b24bc1b5892ef4c17a6efd Mon Sep 17 00:00:00 2001 From: Jacob Asper Date: Sat, 11 Jun 2022 20:49:25 -0400 Subject: [PATCH 4/9] formatted strings in code block --- views/index.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/index.ejs b/views/index.ejs index 0be33bb..08b878c 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -61,7 +61,7 @@ {
      name: <%= resources[i].name %>, url: <%= resources[i].url %>, - keywords: [<%= resources[i].keywords %>]
      + keywords: [<%= resources[i].keywords.map(resource => `'${resource}'`).join(", ") %>]
    }
  • From 1a541aab739e928be91233309e4d966bc77e8fd3 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sat, 11 Jun 2022 19:51:44 -0500 Subject: [PATCH 5/9] chnaged scroll bar styling of the result div, and changed some color tones --- public/assets/logo.svg | 15 +++++++------- public/css/style.css | 44 +++++++++++++++++++++++++++++++----------- views/index.ejs | 30 +++++++++++++++------------- views/matches.ejs | 34 +++++++++++++++++--------------- 4 files changed, 75 insertions(+), 48 deletions(-) diff --git a/public/assets/logo.svg b/public/assets/logo.svg index 0aac8d9..daeca1d 100644 --- a/public/assets/logo.svg +++ b/public/assets/logo.svg @@ -3,7 +3,7 @@ + c0-5.1,0-10.2-0.1-15.4c-0.1-2.4,0.6-3.5,3.2-3.5c6.5,0,6.4-0.1,6.3,6.4C188.2,247.2,188.3,256.1,188.3,265L188.3,265z"/> + C242.5,247,242.5,255.9,242.6,264.8L242.6,264.8z"/> + C417.3,247.2,417.2,256.1,417.3,265L417.3,265z"/> diff --git a/public/css/style.css b/public/css/style.css index 1483b62..72294c5 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -17,7 +17,7 @@ ul { html { font-family: 'Montserrat', sans-serif; - color: #141414; + color: rgb(30, 30, 30); } html * { @@ -29,7 +29,7 @@ html * { .frame { padding: 0; margin: 0; - border: solid 8px #141414; + border: solid 8px rgb(30, 30, 30); margin: 2rem; border-radius: 4rem; overflow: hidden; @@ -63,7 +63,8 @@ nav > img { /* contributors */ .contributors { - --color: #141414; + --color: rgb(30, 30, 30); + background-color: #fff; position: relative; overflow: hidden; border: 3px solid var(--color); @@ -100,7 +101,7 @@ nav > img { } .contributors:active:before { - background: #141414; + background: rgb(30, 30, 30); transition: background 0s; } @@ -156,13 +157,12 @@ main { .api-test form input { width: 65%; - padding: 0 0; border-radius: 15px 0px 0px 15px; font-size: 0.8rem; padding-left: 1rem; transition: width 500ms ease; - border: solid 2px #141414; + border: solid 3px rgb(30, 30, 30); font-size: 1rem; font-weight: 600; } @@ -183,8 +183,8 @@ main { .api-test form button { width: 10%; - background-color: #141414; - border: solid 2px #141414; + background-color: rgb(30, 30, 30); + border: solid 2px rgb(30, 30, 30); border-radius: 0 15px 15px 0; font-size: 20px; } @@ -204,12 +204,34 @@ main { /* result */ .result { + overflow: hidden; + border-radius: 25px; width: 90%; +} + + +.scroll-container { + overflow-y: scroll; + overflow-x: hidden; + width: 100%; height: 300px; border: dashed lightgray 2px; - /* border-radius: 25px; */ - overflow-y: auto; - overflow-x: hidden; + border-radius: 25px; +} + +.scroll-container::-webkit-scrollbar { + width: 12px; + background-color: #F5F5F5; +} + +.scroll-container::-webkit-scrollbar-thumb { + border-radius: 10px; + background-color: rgb(177, 177, 177); +} + +.scroll-container::-webkit-scrollbar-track { + border-radius: 10px; + background-color: #dbdbdb; } .json { diff --git a/views/index.ejs b/views/index.ejs index b5e994e..a2a75ac 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -52,19 +52,23 @@
    -
      - <% for(let i = 0; i < resources.length; i++) { %> -
    • -
      -										{
      - name: <%= resources[i].name %>, - url: <%= resources[i].url %>, - keywords: [<%= resources[i].keywords %>]
      - }
      -
      -
    • - <% } %> -
    +
    +
      + <% for(let i = 0; i < resources.length; i++) { %> +
    • +
      +											
      +												{
      + name: <%= resources[i].name %>, + url: <%= resources[i].url %>, + keywords: [<%= resources[i].keywords %>]
      + } +
      +
      +
    • + <% } %> +
    +
    diff --git a/views/matches.ejs b/views/matches.ejs index a9ae817..00b85a4 100644 --- a/views/matches.ejs +++ b/views/matches.ejs @@ -52,22 +52,24 @@
    -
      - <% for(let i = 0; i < matches.length; i++) { %> -
    • -
      -                                        
      -                                        {
      -                                        
      - name: <%= matches[i].name %>, - url: <%= matches[i].url %>, - keywords: [<%= matches[i].keywords %>] -
      - }
      -
      -
    • - <% } %> -
    +
    +
      + <% for(let i = 0; i < matches.length; i++) { %> +
    • +
      +											
      +											{
      +											
      + name: <%= matches[i].name %>, + url: <%= matches[i].url %>, + keywords: [<%= matches[i].keywords %>] +
      + }
      +
      +
    • + <% } %> +
    +
    From 2d78225ae3de75d3b8bf205d9fb2b2c29e270a13 Mon Sep 17 00:00:00 2001 From: Jacob Asper Date: Sat, 11 Jun 2022 20:59:52 -0400 Subject: [PATCH 6/9] formatted code blocks with map function --- views/matches.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/matches.ejs b/views/matches.ejs index 00b85a4..2133747 100644 --- a/views/matches.ejs +++ b/views/matches.ejs @@ -62,7 +62,7 @@
    name: <%= matches[i].name %>, url: <%= matches[i].url %>, - keywords: [<%= matches[i].keywords %>] + keywords: [<%= matches[i].keywords.map(resource => `'${resource}'`).join(", ") %>]
    }
    From f9d0399c3c0230a0fcf9e67003aba002020d7266 Mon Sep 17 00:00:00 2001 From: brianschnee Date: Sat, 11 Jun 2022 21:26:04 -0400 Subject: [PATCH 7/9] fixed object render to DOM --- public/css/style.css | 4 ++++ views/index.ejs | 7 +------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/public/css/style.css b/public/css/style.css index 72294c5..1d42e56 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -9,6 +9,10 @@ ul { list-style: none; } +.middle-br { + margin: .5rem 0; +} + /* ================= Additional Styles ================= */ diff --git a/views/index.ejs b/views/index.ejs index 45adb6b..fb6c74d 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -58,12 +58,7 @@ <% for(let i = 0; i < resources.length; i++) { %>
  • -											
    -												{
    - name: <%= resources[i].name %>, - url: <%= resources[i].url %>, - keywords: [<%= resources[i].keywords.map(resource => `'${resource}'`).join(", ") %>]
    - }
    + {

    name: <%= resources[i].name %>,
    url: <%= resources[i].url %>,
    keywords: [<%= resources[i].keywords.map(resource => `'${resource}'`).join(", ") %>]

    }
  • <% } %> From e8e9fae319d1038e19f44e11f71072bea93bebc3 Mon Sep 17 00:00:00 2001 From: brianschnee Date: Sat, 11 Jun 2022 21:46:58 -0400 Subject: [PATCH 8/9] fully functional api search --- public/js/main.js | 31 +++++++++++------- server.js | 3 +- views/index.ejs | 2 +- views/matches.ejs | 82 ----------------------------------------------- 4 files changed, 22 insertions(+), 96 deletions(-) delete mode 100644 views/matches.ejs diff --git a/public/js/main.js b/public/js/main.js index 65e2169..fbae544 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,19 +1,28 @@ -// let resources; -// fetchResources(); - -// async function fetchResources() { -// const response = await fetch(`/api/`); -// const data = await response.json(); -// resources = data; -// } - document.getElementById('keyword-btn').addEventListener('click', async () => { const keyword = document.querySelector('input').value; + const list = document.getElementById('result-list'); + list.innerHTML = ''; try { - const res = await fetch(`/api/${keyword}`); + const res = await fetch('/api'); const data = await res.json(); - } catch (err) { + const matches = data.filter(resource => resource.keywords.some(str => str.includes(keyword))); + + console.log(matches); + + matches.forEach(match => { + const li = document.createElement('li'); + + li.innerHTML = ` +
    {

    name: ${match.name},
    url: ${match.url},
    keywords: [${match.keywords.map(keyword => `'${keyword}'`).join(", ")}]

    }
    +
    + `; + + list.appendChild(li); + }); + + console.log('here') + } catch(err) { console.error(err); } }); diff --git a/server.js b/server.js index c308661..707c260 100644 --- a/server.js +++ b/server.js @@ -32,9 +32,8 @@ app.get('/api/:keyword', (req, res) => { const matches = resources.filter((obj) => obj.keywords.some(str => str.includes(keyword))); try { - // if matches were found, render matches.ejs / response with json else throw error + // if matches were found respond with json else throw error if (matches.length) { - res.render('matches.ejs', { matches }); res.json(matches); } else { throw new Error('No resources found.'); diff --git a/views/index.ejs b/views/index.ejs index fb6c74d..d4aae88 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -58,7 +58,7 @@ <% for(let i = 0; i < resources.length; i++) { %>
  • -											{

    name: <%= resources[i].name %>,
    url: <%= resources[i].url %>,
    keywords: [<%= resources[i].keywords.map(resource => `'${resource}'`).join(", ") %>]

    }
    + {

    name: <%= resources[i].name %>,
    url: <%= resources[i].url %>,
    keywords: [<%= resources[i].keywords.map(keyword => `'${keyword}'`).join(", ") %>]

    }
  • <% } %> diff --git a/views/matches.ejs b/views/matches.ejs deleted file mode 100644 index 2133747..0000000 --- a/views/matches.ejs +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - Resources API - - - - - - - - - - -
    - -
    -
    -

    Coding Resources API-

    -

    - Search for coding resources by relevant keywords. - This API serves educational content for a wide - variety of computer science topics, languages and - technologies relevant to web development. -

    -
    -
    -
    - - -
    -
    -
    -
      - <% for(let i = 0; i < matches.length; i++) { %> -
    • -
      -											
      -											{
      -											
      - name: <%= matches[i].name %>, - url: <%= matches[i].url %>, - keywords: [<%= matches[i].keywords.map(resource => `'${resource}'`).join(", ") %>] -
      - }
      -
      -
    • - <% } %> -
    -
    -
    -
    -
    -
    -

    Documentation

    -
    -
    - - - From 8edbd9f42d4774c174957664dde1d902f8f75beb Mon Sep 17 00:00:00 2001 From: brianschnee Date: Sat, 11 Jun 2022 22:05:37 -0400 Subject: [PATCH 9/9] separated main.js into separate functions, need event listener for enter keypress --- public/js/main.js | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/public/js/main.js b/public/js/main.js index fbae544..d2821b1 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,28 +1,31 @@ -document.getElementById('keyword-btn').addEventListener('click', async () => { +const btn = document.getElementById('keyword-btn'); +btn.addEventListener('click', getMatches); + +async function getMatches() { const keyword = document.querySelector('input').value; - const list = document.getElementById('result-list'); - list.innerHTML = ''; try { const res = await fetch('/api'); const data = await res.json(); const matches = data.filter(resource => resource.keywords.some(str => str.includes(keyword))); + renderMatches(matches); + } catch(err) { + console.error(err); + } +} - console.log(matches); - - matches.forEach(match => { - const li = document.createElement('li'); +function renderMatches(matches) { + const list = document.getElementById('result-list'); + list.innerHTML = ''; - li.innerHTML = ` -
    {

    name: ${match.name},
    url: ${match.url},
    keywords: [${match.keywords.map(keyword => `'${keyword}'`).join(", ")}]

    }
    -
    - `; + matches.forEach(match => { + const li = document.createElement('li'); - list.appendChild(li); - }); + li.innerHTML = ` +
    {

    name: ${match.name},
    url: ${match.url},
    keywords: [${match.keywords.map(keyword => `'${keyword}'`).join(", ")}]

    }
    +
    + `; - console.log('here') - } catch(err) { - console.error(err); - } -}); + list.appendChild(li); + }); +} \ No newline at end of file