Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 101 additions & 3 deletions src/createServer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,106 @@
'use strict';
const fs = require('node:fs');
const http = require('node:http');

const htmlForm = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Add expense</title>
</head>
<body>
<h1>Add expense</h1>
<form action="/add-expense" method="POST">
<label for="date">Select a date: </label>
<input id="date" name="date" type="date" required><br><br>
<label for="title">Select a title: </label>
<input id="title" name="title" type="text" required><br><br>
<label for="amount">Select an amount: </label>
<input id="amount" name="amount" type="number" required><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
`;

function getData(text, contentType) {
switch (contentType) {
case 'application/json':
return JSON.parse(text);

case 'application/x-www-form-urlencoded':
return text
.split('&')
.map((v) => v.split('='))
.reduce((acc, [key, value]) => {
acc[key] = decodeURIComponent(value);

return acc;
}, {});
}
}

function createServer() {
/* Write your code here */
// Return instance of http.Server class
return http.createServer((req, res) => {
if (req.url === '/') {
res.writeHead(200, 'OK', { 'content-type': 'text/html' });

return res.end(htmlForm);
}

if (['/add-expense', '/submit-expense'].includes(req.url)) {
if (req.method !== 'POST') {
res.writeHead(400, 'Bad Request', { 'content-type': 'text/html' });

return res.end(`${req.method} not allowed for this path`);
}

const chunks = [];

req.on('data', (chunk) => chunks.push(chunk));

req.on('end', () => {
const text = Buffer.concat(chunks).toString('utf-8');
const data = getData(text, req.headers['content-type']);

const keys = Object.keys(data);

if (
keys.length !== 3 ||
!keys.includes('date') ||
!keys.includes('title') ||
!keys.includes('amount')
) {
res.writeHead(400, 'Bad Request', { 'content-type': 'text/plain' });

return res.end(
'The request must include exactly 3 keys: date, title, and amount.',
);
}

const responseData = JSON.stringify(data);

fs.writeFile('./db/expense.json', responseData, (err) => {
if (err) {
res.writeHead(500, 'Server Error', {
'content-type': 'text/plain',
});

return res.end('Something went wrong. Please try again later.');
}

res.writeHead(200, 'OK', { 'content-type': 'application/json' });

res.end(responseData);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task description states that the server should return an HTML page with well-formatted JSON, but the current implementation returns JSON data with the content type set to application/json.

You should generate an HTML page with the JSON data embedded within it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test write exactly application/json

});
});

return;
}

res.writeHead(404, 'Not Found', { 'content-type': 'text/plain' });
res.end('Not Found');
});
}

module.exports = {
Expand Down