From cda0c320071a976cbb2de470cd9f9980e818a2c4 Mon Sep 17 00:00:00 2001 From: Piotr Brudny Date: Sun, 10 Sep 2023 20:11:12 +0200 Subject: [PATCH] Refactored server.js based on feedback. Refer to ChatGPT session: https://chat.openai.com/share/186b240c-7246-4719-975c-75c42e23ca90 --- server/package.json | 1 + server/server.js | 90 ++++++++++++++++++++++++--------------------- server/yarn.lock | 5 +++ 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/server/package.json b/server/package.json index 2dd66c8..9752225 100644 --- a/server/package.json +++ b/server/package.json @@ -11,6 +11,7 @@ "compression": "^1.7.4", "contentful": "^7.14.8", "contentful-management": "^6.1.2", + "dotenv": "^16.3.1", "express": "4.17.1", "nodemon": "^2.0.4" } diff --git a/server/server.js b/server/server.js index f76acb9..93d8e21 100644 --- a/server/server.js +++ b/server/server.js @@ -1,72 +1,80 @@ +require('dotenv').config(); + const express = require('express'); -const app = express(); -const port = process.env.PORT || 5000; const path = require('path'); -const fs = require('fs') -const contentful = require("contentful"); +const fs = require('fs').promises; +const contentful = require('contentful'); const compression = require('compression'); +// Constants +const PORT = process.env.PORT || 5000; const SPACE_ID = process.env.REACT_APP_SPACE_ID; const ACCESS_TOKEN = process.env.REACT_APP_ACCESS_TOKEN; -const MANAGER_TOKEN = process.env.REACT_APP_MANAGER_TOKEN; -const ENVIRONMENT = process.env.REACT_APP_ENVIRONMENT || "master"; +const ENVIRONMENT = process.env.REACT_APP_ENVIRONMENT || 'master'; +const MAIN_TITLE = "IT jobs with salaries - Jobs For IT"; +const MAIN_DESCRIPTION = "Job offers for software developers, testers, UX designers, DevOps"; +const MAIN_IMAGE = "https://www.jobsforit.de/static/media/wiewior.4979dfde.png"; +const FILE_PATH = path.resolve(__dirname, '..', 'build', 'index.html'); +// Contentful client setup const client = contentful.createClient({ space: SPACE_ID, accessToken: ACCESS_TOKEN, environment: ENVIRONMENT }); -const getJob = (slug) => client.getEntries({ +const getJob = slug => client.getEntries({ content_type: 'job', 'fields.slug': slug, select: 'fields.ogTitle,fields.ogDescription,fields.ogImage,fields.position,fields.company,fields.city', limit: 1, }); -const mainTitle = "IT jobs with salaries - Jobs For IT"; -const mainDescription = "Job offers for software developers, testers, UX designers, DevOps"; -const mainImage = "https://www.jobsforit.de/static/media/wiewior.4979dfde.png"; +// Server setup +const app = express(); +// Middleware app.use(compression()); app.use(express.static(path.resolve(__dirname, '..', 'build'))); -const filePath = path.resolve(__dirname, '..', 'build', 'index.html'); -const filePathPolicy = path.resolve(__dirname, '..', 'build', 'privacy-policy.html'); - -app.get('/jobs/:id', function(request, response) { +// Routes +app.get('/jobs/:id', async (request, response) => { const id = request.params.id; - fs.readFile(filePath, 'utf8', (err,data) => { - if (err) { - return console.log(err); - } + let data; - getJob(id) - .then(entries => { - const { position, ogTitle, ogDescription, ogImage } = entries.items[0].fields; - const { name: company, logo } = entries.items[0].fields.company.fields; - const { name: city } = entries.items[0].fields.city.fields; - const title = ogTitle || `${position} Job - ${company} - ${city} - Jobs For IT`; - const description = ogDescription || `Working in IT: ${company} is looking for ${position}. Job ${city}.`; - const image = ogImage ? ogImage.fields.file.url : logo.fields.file.url; - data = data.replace(new RegExp(mainTitle,"g"), title); - data = data.replace(new RegExp(mainDescription,"g"), description); - data = data.replace(mainImage, "https:" + image); - response.send(data); - }).catch(err => { - console.error(err); + try { + data = await fs.readFile(FILE_PATH, 'utf8'); + const entries = await getJob(id); + const { position, ogTitle, ogDescription, ogImage } = entries.items[0].fields; + const { name: company, logo } = entries.items[0].fields.company.fields; + const { name: city } = entries.items[0].fields.city.fields; + + const title = ogTitle || `${position} Job - ${company} - ${city} - Jobs For IT`; + const description = ogDescription || `Working in IT: ${company} is looking for ${position}. Job ${city}.`; + const image = ogImage ? ogImage.fields.file.url : logo.fields.file.url; + + data = data.replace(new RegExp(MAIN_TITLE, "g"), title); + data = data.replace(new RegExp(MAIN_DESCRIPTION, "g"), description); + data = data.replace(MAIN_IMAGE, "https:" + image); + + response.send(data); + } catch (err) { + console.error(err); + if (data) { response.send(data); - }); - }); + } else { + response.status(500).send('Internal server error'); + } + } }); -// fixed client side urls: https://stackoverflow.com/questions/27928372/react-router-urls-dont-work-when-refreshing-or-writing-manually?page=2&tab=active#tab-top -app.get('/*', function(req, res) { - res.sendFile(filePath, function(err) { +app.get('/*', (req, res) => { + res.sendFile(FILE_PATH, function(err) { if (err) { - res.status(500).send(err) + res.status(500).send(err); } - }) -}) + }); +}); -app.listen(port, () => console.log(`Listening to you on port ${port}`)); +// Start the server +app.listen(PORT, () => console.log(`Listening on port ${PORT}`)); diff --git a/server/yarn.lock b/server/yarn.lock index 7ddb7d0..2e7baad 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -376,6 +376,11 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" +dotenv@^16.3.1: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"