diff --git a/1server.js b/1server.js deleted file mode 100644 index 5f3f439..0000000 --- a/1server.js +++ /dev/null @@ -1,29 +0,0 @@ -const express = require('express'); -const favicon = require('serve-favicon'); -const path = require('path'); -const methodOverride = require('method-override'); - -const articleRoute = require('./backend/routes/articles'); -const { readController } = require('./backend/controllers/articles'); - -const app = express(); - -app.use(favicon(path.join(__dirname, 'backend', 'favicon.ico'))); -app.set('views', path.join(__dirname, 'frontend/views')); -app.set('view engine','ejs'); - -app.use(express.urlencoded({ extended: "false" })); // parse data sent thru html form -app.use(express.json({ limit: "1mb" })); // parse json data coming from frontend -app.use(methodOverride('_method')); - -app.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -app.use('/articles',articleRoute); - -app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files - -app.all('*', (_,res) => res.send('

404!
Page not found...

')); - -const { HOST:host='localhost', PORT:port=5000 } = process.env; -app.listen(port, () => console.log(`Connection is established at \nhttp://${host}:${port} OR \nhttps://devtrek.herokuapp.com\n`)); - diff --git a/3server.js b/3server.js deleted file mode 100644 index 3a3aae2..0000000 --- a/3server.js +++ /dev/null @@ -1,61 +0,0 @@ -const express = require('express'); -const mongoose = require('mongoose'); -require('dotenv').config(); - -const favicon = require('serve-favicon'); -const path = require('path'); -const methodOverride = require('method-override'); - -const articleRoute = require('./backend/routes/articles'); -// const { readController } = require('./backend/controllers/articles'); - -const app = express(); - -// frontend -app.set('view engine','ejs'); -app.set('views', path.join(__dirname, 'frontend/views')); // set default views directory -// app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files -// app.use(methodOverride('_method')); // for calling request methods other than get and post thru form - -// app.use(express.json({ limit: "1mb" })); // parse json data coming from frontend -app.use(express.urlencoded({ extended: "false" })); // parse data sent thru html form - -app.use(favicon(path.join(__dirname, 'backend', 'favicon.ico'))); // serve req: '/favicon.ico' & set favicon for all pgs - -app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files -app.use(methodOverride('_method')); // for calling request methods other than get and post thru form - -// app.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -// app.use('/articles',articleRoute); -app.use('/',articleRoute); - -// app.all('*', (_,res) => res.send('

404!
Page not found...

')); - -// app.use((err, req, res, next) => { // express err handler, global err format for printing user defined errs -// const errFormat = { -// statusCode: err.statusCode || 500, -// message: err.message, -// stack: err.stack -// }; -// }); - -// const { HOST:host='localhost', PORT:port=5000 } = process.env; -const { HOST:host, PORT:port=5000, DB_CON:dbUrl } = process.env; - -// app.listen(port, () => console.log(`Connection is established at \nhttp://${host}:${port} OR \nhttps://devtrek.herokuapp.com\n`)); -// console.log(host,port,dbUrl); -mongoose.connect( - dbUrl, - { - useNewUrlParser: true, - useUnifiedTopology: true, - useCreateIndex: true - } -).then(() => { - app.listen(port); - console.log(`Connection is established at \nhttp://${host}:${port} OR \nhttps://devtrek.herokuapp.com\n`); -}).catch(err => console.error(err.message)); - -// mongoose.set('useFindAndModify',false); - diff --git a/4server.js b/4server.js deleted file mode 100644 index 30fcd59..0000000 --- a/4server.js +++ /dev/null @@ -1,40 +0,0 @@ -const express = require('express'); -const mongoose = require('mongoose'); -require('dotenv').config(); -// const favicon = require('serve-favicon'); -const path = require('path'); -// const methodOverride = require('method-override'); - -const articleRoute = require('./backend/routes/articles'); - -const app = express(); - -// app.use(favicon(path.join(__dirname, 'backend', 'favicon.ico'))); -app.set('view engine','ejs'); -app.set('views', path.join(__dirname, 'frontend/views')); -// app.set('views', 'frontend/views'); -app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files - -// app.use(express.urlencoded({ extended: "false" })); // parse data sent thru html form -// app.use(express.json({ limit: "1mb" })); // parse json data coming from frontend -// app.use(methodOverride('_method')); - -app.use('/',articleRoute); - -// app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files - -const { HOST:host, PORT:port=5000, DB_CON:dbUrl } = process.env; - -mongoose.connect( - dbUrl, - { - useNewUrlParser: true, - useUnifiedTopology: true, - useCreateIndex: true - } -).then(() => { - app.listen(port); - console.log(`Connection is established at \nhttp://${host}:${port} OR \nhttps://devtrek.herokuapp.com\n`); -}).catch(err => console.error(err.message)); - - diff --git a/5server.js b/5server.js deleted file mode 100644 index f22af93..0000000 --- a/5server.js +++ /dev/null @@ -1,43 +0,0 @@ -const express = require('express'); -// const favicon = require('serve-favicon'); -const path = require('path'); -// const methodOverride = require('method-override'); -// require('dotenv').config(); - -const articleRoute = require('./backend/routes/articles'); -// const { readController } = require('./backend/controllers/articles'); - -const app = express(); -// export const app = express(); - -// app.use(favicon(path.join(__dirname, 'backend', 'favicon.ico'))); -// app.use(express.static(path.join(__dirname, 'frontend/assets'))); -app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files -// app.set('views', path.join(__dirname, 'frontend/views')); -app.set('views', 'frontend/views'); -app.set('view engine','ejs'); -// app.engine('html', require('ejs').renderFile); -// app.set('view engine', 'html'); -// console.log(app,app.settings.views,'\n',__dirname); -// app.settings.views = __dirname + "\\frontend\\views"; -// console.log(app.settings.views,app,app.set); -// app.use(express.urlencoded({ extended: "false" })); // parse data sent thru html form -// app.use(express.json({ limit: "1mb" })); // parse json data coming from frontend -// app.use(methodOverride('_method')); - -// app.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -// module.exports = app; -app.use('/',articleRoute); - -// app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files - -// app.all('*', (_,res) => res.send('

404!
Page not found...

')); - -const { HOST:host='localhost', PORT:port=5000 } = process.env; -app.listen(port, () => console.log(`Connection is established at \nhttp://${host}:${port} OR \nhttps://devtrek.herokuapp.com\n`)); - -// exports.module = app; -// module.exports = app; -// console.log(app); - diff --git a/README.md b/README.md index e3fdc86..80e82a2 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,5 @@ - - - - - # [devTrek](http://devtrek.herokuapp.com)   - A Blogging App
diff --git a/backend/1db.json b/backend/1db.json deleted file mode 100644 index 1ccd9cb..0000000 --- a/backend/1db.json +++ /dev/null @@ -1 +0,0 @@ -[{"name":"DOnt HaCk mE","title":"Public API's","originalDesc":"You can develop some great applications with the use of the following APIs.\n\n1. API Football\nIf you are a fan of a sport like a football, then it will be more fun and exciting to work on a project that deals with football data. API football provides tons of data including teams, fixtures, live scores, predictions, etc.\n\n2. Frankfurter\nFrankfurter provides current and historic foreign exchange rates. Rates are based on data published by the European Central Bank. It's totally free and does not require a key to fetch data.\n\n3. Poke API\nAll Pokémon data at one place with poke API. We all know about Pokémon, we used to watch the show in our childhood and many even today. This API shows data of individual Pokémon.","markdown":"# Now, Create frontend using online Api's","modifiedDesc":"You can develop some great applications with the use of the following APIs.

1. API Football
If you are a fan of a sport like a football, then it will be more fun and exciting to work on a project that deals with football data. API football provides tons of data including teams, fixtures, live scores, predictions, etc.

2. Frankfurter
Frankfurter provides current and historic foreign exchange rates. Rates are based on data published by the European Central Bank. It's totally free and does not require a key to fetch data.

3. Poke API
All Pokémon data at one place with poke API. We all know about Pokémon, we used to watch the show in our childhood and many even today. This API shows data of individual Pokémon.","updatedAt":"2021-08-20T20:54:07.126Z","slug":"public-apis","sanitizedHtml":"

Now, Create frontend using online Api's

\n","id":"3","createdAt":"2021-08-20T20:54:07.126Z","displayDate":"20/8/2021","likes":1},{"name":"ZoX","title":"CSS in JS","originalDesc":"Building web apps with React is not just about composing components together and making sure that the logic works correctly. That arguably is the most important part, where at least it's the biggest reason for using React. But building react apps is also about styling those apps.\n\nWe want to make sure that our web applications look good and styling is also an important part of building components.\n\nStyled-components is a CSS-in-JS styling library that uses tagged template literals in JavaScript and CSS rules to provide pre-styled components where the styling is scoped to that react component only.\n\nThe button as a JavaScript variable and the styles defined in backticks are plain old CSS styles. We can also see the nested style property with plain CSS styles.\n\nThis is how styled-components renders CSS in JavaScript.\n\nStyling React components\nThere are primarly two ways to style a React component.\n\n1. Inline Styling:\nconst style = {\ncolor: 'blue',\n};\n\nInline styling has one of the highest specificity value which will override any other CSS rule. This method is highly discouraged, as it is neither sustainable nor scalable.\n\n2. External Styling:\nThere’s this more traditional way of using CSS in external CSS files, which is then passed as a string to the className prop\n\nAs the component tree grows, CSS files begin to get bulky, clumsy, and complex. One great alternative solution to this is the usage of SASS. Although SASS helps, you’ll eventually deal with the same issue due to the sheer number of SCSS files a project can have.\n\nFinally, CSS-in-JS is a technique where JavaScript is used to style components. When this JavaScript is parsed by the browser, CSS is generated as a style element and attached inside of the HTML document.","markdown":"# Efficiently write CSS in JS","modifiedDesc":"Building web apps with React is not just about composing components together and making sure that the logic works correctly. That arguably is the most important part, where at least it's the biggest reason for using React. But building react apps is also about styling those apps.

We want to make sure that our web applications look good and styling is also an important part of building components.

Styled-components is a CSS-in-JS styling library that uses tagged template literals in JavaScript and CSS rules to provide pre-styled components where the styling is scoped to that react component only.

The button as a JavaScript variable and the styles defined in backticks are plain old CSS styles. We can also see the nested style property with plain CSS styles.

This is how styled-components renders CSS in JavaScript.

Styling React components
There are primarly two ways to style a React component.

1. Inline Styling:
const style = {
color: 'blue',
};

Inline styling has one of the highest specificity value which will override any other CSS rule. This method is highly discouraged, as it is neither sustainable nor scalable.

2. External Styling:
There’s this more traditional way of using CSS in external CSS files, which is then passed as a string to the className prop

As the component tree grows, CSS files begin to get bulky, clumsy, and complex. One great alternative solution to this is the usage of SASS. Although SASS helps, you’ll eventually deal with the same issue due to the sheer number of SCSS files a project can have.

Finally, CSS-in-JS is a technique where JavaScript is used to style components. When this JavaScript is parsed by the browser, CSS is generated as a style element and attached inside of the HTML document.","updatedAt":"2021-08-20T20:53:53.191Z","slug":"css-in-js","sanitizedHtml":"

Efficiently write CSS in JS

\n","id":"4","createdAt":"2021-08-20T20:53:53.191Z","displayDate":"20/8/2021","likes":3},{"name":"Bot","title":"Machine Learning","originalDesc":"Pre-requisites:\n\nFirst things first, what are the pre-requisites of learning Machine Learning? Just knowing the programming languages are not enough; you must know the mathematics behind each algorithm too. The important topics one must familiarize themselves with are:\n\n1. For Linear Algebra\n2. For Statistics\n3. For Calculus\n\nCoding fundamentals:\nMany languages are used for writing Machine Learning programs, like Python, R, Java and so on. However, python is the most recommended because of its several libraries and frameworks that have simplified the task of writing complex code. Another reason I would recommend Python is because there are far more Machine Learning tutorials written in python than there are in R. Thus, it is easier for a python programmer to get help from the data science community than an R programmer. However, R is also known for its various data visualization libraries. Thus, there is no harm in learning both languages and utilizing their best features. You can always learn one and move to the next. For a beginner, I would recommend python.","markdown":"# RoadMap for Machine Learning","modifiedDesc":"Pre-requisites:

First things first, what are the pre-requisites of learning Machine Learning? Just knowing the programming languages are not enough; you must know the mathematics behind each algorithm too. The important topics one must familiarize themselves with are:

1. For Linear Algebra
2. For Statistics
3. For Calculus

Coding fundamentals:
Many languages are used for writing Machine Learning programs, like Python, R, Java and so on. However, python is the most recommended because of its several libraries and frameworks that have simplified the task of writing complex code. Another reason I would recommend Python is because there are far more Machine Learning tutorials written in python than there are in R. Thus, it is easier for a python programmer to get help from the data science community than an R programmer. However, R is also known for its various data visualization libraries. Thus, there is no harm in learning both languages and utilizing their best features. You can always learn one and move to the next. For a beginner, I would recommend python.","updatedAt":"2021-08-21T20:53:44.978Z","slug":"machine-learning","sanitizedHtml":"

RoadMap for Machine Learning

\n","id":"5","createdAt":"2021-08-21T20:53:44.978Z","displayDate":"21/8/2021","likes":1},{"name":"Sandeep","title":"Optimizing React Apps","originalDesc":"You've heard of minifying. You've heard of lazy-loading. You've heard of tree shaking. You've done it all. Or did you? Here are some optimizations you may have never heard of before. Until now!\n\n1. Enable \"loose\" transformations in @babel/preset-env:\nEnabling \"loose\" transformations may make your application considerably smaller. I shaved off roughly 230.9 KB, or 16.2% from my bundle!\n\nThis, however, comes at a price: your application may break, both when enabling, and disabling these transformations.\n\nIn my case, the only fix I needed to do was related to iterating over HTMLFormControlsCollection (form.elements). I was no longer able to do e.g. [...form.elements], I had to swap it out for Array.from(form.elements).\n\nStill tempted by the large savings? Give it a go by enabling loose flag in Babel config:\n\nbabel.config.json-\n\"presets\": [\n-\"@babel/preset-env\"\n+[\"@babel/preset-env\", {\n+\"loose\": true\n+}]\n]\n\n2. Remove prop-types from your production bundle:\nPropTypes are incredibly helpful during development, but they are of no use for your users. You can use babel-plugin-transform-react-remove-prop-types to remove PropTypes from your bundle.\n\nTo install, run:\nnpm install --save-dev babel-plugin-transform-react-remove-prop-types\nor\nyarn add -D babel-plugin-transform-react-remove-prop-types\nand add it to your Babel config like so:\n\nbabel.config.json-\n\"env\": {\n\"production\": {\n\"plugins\": [\n+\"transform-react-remove-prop-types\"\n]\n}\n}\n\nSavings will vary depending on the size of your app. In my case, I shaved off 16.5 KB or about 1.2% from my bundle.\n\n3. Consider unsafe-wrap mode:\nunsafe-wrap mode is, as the name states, a bit unsafe for the reasons well explained in plugin's docs.\n\nHowever, in my case, PropTypes were not accessed from anywhere and the application worked flawlessly.\n\nTo enable this mode, you need to change your Babel config like so:\n\nbabel.config.json-\n\"env\": {\n\"production\": {\n\"plugins\": [\n-\"transform-react-remove-prop-types\"\n+[\"transform-react-remove-prop-types\", {\n+\"mode\": \"unsafe-wrap\"\n+}]\n]\n}\n}\n\nThis way, I shaved off a total of 35.9 KB or about 2.5% from my bundle.\n\n4. Enable new JSX transform:\nEnabling new JSX transform will change the way Babel React preset transpiles JSX to pure JavaScript.\n\nI explained the benefits of enabling it in my other article: How to enable new JSX transform in React 17?.\n\nI highly recommend you to have a read. If that's TL;DR though, all you need to do for quick results is make sure that @babel/core and @babel/preset-env in your project are both on version 7.9.0 or newer, and change your Babel config like so:\n\nbabel.config.json\n\"presets\": [\n-\"@babel/preset-react\"\n+[\"@babel/preset-react\", {\n+\"runtime\": \"automatic\"\n+}]\n]\n\nAnd poof! Roughly 10.5 KB, or 0.7% of my bundle was gone.","markdown":"# Optimizing React apps: Hardcore edition","modifiedDesc":"You've heard of minifying. You've heard of lazy-loading. You've heard of tree shaking. You've done it all. Or did you? Here are some optimizations you may have never heard of before. Until now!

1. Enable \"loose\" transformations in @babel/preset-env:
Enabling \"loose\" transformations may make your application considerably smaller. I shaved off roughly 230.9 KB, or 16.2% from my bundle!

This, however, comes at a price: your application may break, both when enabling, and disabling these transformations.

In my case, the only fix I needed to do was related to iterating over HTMLFormControlsCollection (form.elements). I was no longer able to do e.g. [...form.elements], I had to swap it out for Array.from(form.elements).

Still tempted by the large savings? Give it a go by enabling loose flag in Babel config:

babel.config.json-
\"presets\": [
-\"@babel/preset-env\"
+[\"@babel/preset-env\", {
+\"loose\": true
+}]
]

2. Remove prop-types from your production bundle:
PropTypes are incredibly helpful during development, but they are of no use for your users. You can use babel-plugin-transform-react-remove-prop-types to remove PropTypes from your bundle.

To install, run:
npm install --save-dev babel-plugin-transform-react-remove-prop-types
or
yarn add -D babel-plugin-transform-react-remove-prop-types
and add it to your Babel config like so:

babel.config.json-
\"env\": {
\"production\": {
\"plugins\": [
+\"transform-react-remove-prop-types\"
]
}
}

Savings will vary depending on the size of your app. In my case, I shaved off 16.5 KB or about 1.2% from my bundle.

3. Consider unsafe-wrap mode:
unsafe-wrap mode is, as the name states, a bit unsafe for the reasons well explained in plugin's docs.

However, in my case, PropTypes were not accessed from anywhere and the application worked flawlessly.

To enable this mode, you need to change your Babel config like so:

babel.config.json-
\"env\": {
\"production\": {
\"plugins\": [
-\"transform-react-remove-prop-types\"
+[\"transform-react-remove-prop-types\", {
+\"mode\": \"unsafe-wrap\"
+}]
]
}
}

This way, I shaved off a total of 35.9 KB or about 2.5% from my bundle.

4. Enable new JSX transform:
Enabling new JSX transform will change the way Babel React preset transpiles JSX to pure JavaScript.

I explained the benefits of enabling it in my other article: How to enable new JSX transform in React 17?.

I highly recommend you to have a read. If that's TL;DR though, all you need to do for quick results is make sure that @babel/core and @babel/preset-env in your project are both on version 7.9.0 or newer, and change your Babel config like so:

babel.config.json
\"presets\": [
-\"@babel/preset-react\"
+[\"@babel/preset-react\", {
+\"runtime\": \"automatic\"
+}]
]

And poof! Roughly 10.5 KB, or 0.7% of my bundle was gone.","updatedAt":"2021-08-22T20:53:08.789Z","slug":"optimizing-react-apps","sanitizedHtml":"

Optimizing React apps: Hardcore edition

\n","id":"6","createdAt":"2021-08-22T20:53:08.789Z","displayDate":"22/8/2021","likes":1},{"name":"Tushar","title":"PHP Laravel","originalDesc":"Kubernetes is an excellent open-source container orchestration platform that brings automatic scaling, automatic recovery, observability, and many more features. Since it differs from traditional operations, it has changed the development and deployment workflows as well. Debugging an application on Kubernetes can be a challenge.\n\nDevSpace is a tool that helps you develop, deploy, troubleshoot simple or complex applications. We will use a Laravel project to demonstrate its features. \n\nLaravel is a popular framework used by the PHP community with great features like extensibility, inheritance, and reusability with high customization options.\n\nArchitecture:\nWe will look at ways to deploy a Laravel based application into a Kubernetes cluster for development and production environments. We will develop our application while the application is running in Kubernetes as if we are developing locally. And we will be able to troubleshoot our application in real-time with ease.\n\nThe desired setup uses four containers, in three pods:\n1. PHP-FPM container, which processes all the PHP assets.\n2. Nginx container, which serves static files and acts as a reverse proxy for the PHP assets.\n3. MySQL container, as the database.\n4. Redis container, as session and cache.","markdown":"# PHP Laravel Development with Kubernetes using DevSpace","modifiedDesc":"Kubernetes is an excellent open-source container orchestration platform that brings automatic scaling, automatic recovery, observability, and many more features. Since it differs from traditional operations, it has changed the development and deployment workflows as well. Debugging an application on Kubernetes can be a challenge.

DevSpace is a tool that helps you develop, deploy, troubleshoot simple or complex applications. We will use a Laravel project to demonstrate its features.

Laravel is a popular framework used by the PHP community with great features like extensibility, inheritance, and reusability with high customization options.

Architecture:
We will look at ways to deploy a Laravel based application into a Kubernetes cluster for development and production environments. We will develop our application while the application is running in Kubernetes as if we are developing locally. And we will be able to troubleshoot our application in real-time with ease.

The desired setup uses four containers, in three pods:
1. PHP-FPM container, which processes all the PHP assets.
2. Nginx container, which serves static files and acts as a reverse proxy for the PHP assets.
3. MySQL container, as the database.
4. Redis container, as session and cache.","updatedAt":"2021-08-22T20:52:19.267Z","slug":"php-laravel","sanitizedHtml":"

PHP Laravel Development with Kubernetes using DevSpace

\n","id":"7","createdAt":"2021-08-22T20:52:19.267Z","displayDate":"22/8/2021","likes":1}] \ No newline at end of file diff --git a/backend/2db.json b/backend/2db.json deleted file mode 100644 index 4ec34ab..0000000 --- a/backend/2db.json +++ /dev/null @@ -1 +0,0 @@ -[{"name":"DOnt HaCk mE","title":"Public API's","originalDesc":"You can develop some great applications with the use of the following APIs.\n\n1. API Football\nIf you are a fan of a sport like a football, then it will be more fun and exciting to work on a project that deals with football data. API football provides tons of data including teams, fixtures, live scores, predictions, etc.\n\n2. Frankfurter\nFrankfurter provides current and historic foreign exchange rates. Rates are based on data published by the European Central Bank. It's totally free and does not require a key to fetch data.\n\n3. Poke API\nAll Pokémon data at one place with poke API. We all know about Pokémon, we used to watch the show in our childhood and many even today. This API shows data of individual Pokémon.","markdown":"# Now, Create frontend using online Api's","modifiedDesc":"You can develop some great applications with the use of the following APIs.

1. API Football
If you are a fan of a sport like a football, then it will be more fun and exciting to work on a project that deals with football data. API football provides tons of data including teams, fixtures, live scores, predictions, etc.

2. Frankfurter
Frankfurter provides current and historic foreign exchange rates. Rates are based on data published by the European Central Bank. It's totally free and does not require a key to fetch data.

3. Poke API
All Pokémon data at one place with poke API. We all know about Pokémon, we used to watch the show in our childhood and many even today. This API shows data of individual Pokémon.","updatedAt":"2021-08-20T20:54:07.126Z","slug":"public-apis","sanitizedHtml":"

Now, Create frontend using online Api's

\n","id":"3","createdAt":"2021-08-20T20:54:07.126Z","displayDate":"20/8/2021","likes":1},{"name":"ZoX","title":"CSS in JS","originalDesc":"Building web apps with React is not just about composing components together and making sure that the logic works correctly. That arguably is the most important part, where at least it's the biggest reason for using React. But building react apps is also about styling those apps.\n\nWe want to make sure that our web applications look good and styling is also an important part of building components.\n\nStyled-components is a CSS-in-JS styling library that uses tagged template literals in JavaScript and CSS rules to provide pre-styled components where the styling is scoped to that react component only.\n\nThe button as a JavaScript variable and the styles defined in backticks are plain old CSS styles. We can also see the nested style property with plain CSS styles.\n\nThis is how styled-components renders CSS in JavaScript.\n\nStyling React components\nThere are primarly two ways to style a React component.\n\n1. Inline Styling:\nconst style = {\ncolor: 'blue',\n};\n\nInline styling has one of the highest specificity value which will override any other CSS rule. This method is highly discouraged, as it is neither sustainable nor scalable.\n\n2. External Styling:\nThere’s this more traditional way of using CSS in external CSS files, which is then passed as a string to the className prop\n\nAs the component tree grows, CSS files begin to get bulky, clumsy, and complex. One great alternative solution to this is the usage of SASS. Although SASS helps, you’ll eventually deal with the same issue due to the sheer number of SCSS files a project can have.\n\nFinally, CSS-in-JS is a technique where JavaScript is used to style components. When this JavaScript is parsed by the browser, CSS is generated as a style element and attached inside of the HTML document.","markdown":"# Efficiently write CSS in JS","modifiedDesc":"Building web apps with React is not just about composing components together and making sure that the logic works correctly. That arguably is the most important part, where at least it's the biggest reason for using React. But building react apps is also about styling those apps.

We want to make sure that our web applications look good and styling is also an important part of building components.

Styled-components is a CSS-in-JS styling library that uses tagged template literals in JavaScript and CSS rules to provide pre-styled components where the styling is scoped to that react component only.

The button as a JavaScript variable and the styles defined in backticks are plain old CSS styles. We can also see the nested style property with plain CSS styles.

This is how styled-components renders CSS in JavaScript.

Styling React components
There are primarly two ways to style a React component.

1. Inline Styling:
const style = {
color: 'blue',
};

Inline styling has one of the highest specificity value which will override any other CSS rule. This method is highly discouraged, as it is neither sustainable nor scalable.

2. External Styling:
There’s this more traditional way of using CSS in external CSS files, which is then passed as a string to the className prop

As the component tree grows, CSS files begin to get bulky, clumsy, and complex. One great alternative solution to this is the usage of SASS. Although SASS helps, you’ll eventually deal with the same issue due to the sheer number of SCSS files a project can have.

Finally, CSS-in-JS is a technique where JavaScript is used to style components. When this JavaScript is parsed by the browser, CSS is generated as a style element and attached inside of the HTML document.","updatedAt":"2021-08-20T20:53:53.191Z","slug":"css-in-js","sanitizedHtml":"

Efficiently write CSS in JS

\n","id":"4","createdAt":"2021-08-20T20:53:53.191Z","displayDate":"20/8/2021","likes":3},{"name":"Bot","title":"Machine Learning","originalDesc":"Pre-requisites:\n\nFirst things first, what are the pre-requisites of learning Machine Learning? Just knowing the programming languages are not enough; you must know the mathematics behind each algorithm too. The important topics one must familiarize themselves with are:\n\n1. For Linear Algebra\n2. For Statistics\n3. For Calculus\n\nCoding fundamentals:\nMany languages are used for writing Machine Learning programs, like Python, R, Java and so on. However, python is the most recommended because of its several libraries and frameworks that have simplified the task of writing complex code. Another reason I would recommend Python is because there are far more Machine Learning tutorials written in python than there are in R. Thus, it is easier for a python programmer to get help from the data science community than an R programmer. However, R is also known for its various data visualization libraries. Thus, there is no harm in learning both languages and utilizing their best features. You can always learn one and move to the next. For a beginner, I would recommend python.","markdown":"# RoadMap for Machine Learning","modifiedDesc":"Pre-requisites:

First things first, what are the pre-requisites of learning Machine Learning? Just knowing the programming languages are not enough; you must know the mathematics behind each algorithm too. The important topics one must familiarize themselves with are:

1. For Linear Algebra
2. For Statistics
3. For Calculus

Coding fundamentals:
Many languages are used for writing Machine Learning programs, like Python, R, Java and so on. However, python is the most recommended because of its several libraries and frameworks that have simplified the task of writing complex code. Another reason I would recommend Python is because there are far more Machine Learning tutorials written in python than there are in R. Thus, it is easier for a python programmer to get help from the data science community than an R programmer. However, R is also known for its various data visualization libraries. Thus, there is no harm in learning both languages and utilizing their best features. You can always learn one and move to the next. For a beginner, I would recommend python.","updatedAt":"2021-08-21T20:53:44.978Z","slug":"machine-learning","sanitizedHtml":"

RoadMap for Machine Learning

\n","id":"5","createdAt":"2021-08-21T20:53:44.978Z","displayDate":"21/8/2021","likes":1},{"name":"Sandeep","title":"Optimizing React Apps","originalDesc":"You've heard of minifying. You've heard of lazy-loading. You've heard of tree shaking. You've done it all. Or did you? Here are some optimizations you may have never heard of before. Until now!\n\n1. Enable \"loose\" transformations in @babel/preset-env:\nEnabling \"loose\" transformations may make your application considerably smaller. I shaved off roughly 230.9 KB, or 16.2% from my bundle!\n\nThis, however, comes at a price: your application may break, both when enabling, and disabling these transformations.\n\nIn my case, the only fix I needed to do was related to iterating over HTMLFormControlsCollection (form.elements). I was no longer able to do e.g. [...form.elements], I had to swap it out for Array.from(form.elements).\n\nStill tempted by the large savings? Give it a go by enabling loose flag in Babel config:\n\nbabel.config.json-\n\"presets\": [\n-\"@babel/preset-env\"\n+[\"@babel/preset-env\", {\n+\"loose\": true\n+}]\n]\n\n2. Remove prop-types from your production bundle:\nPropTypes are incredibly helpful during development, but they are of no use for your users. You can use babel-plugin-transform-react-remove-prop-types to remove PropTypes from your bundle.\n\nTo install, run:\nnpm install --save-dev babel-plugin-transform-react-remove-prop-types\nor\nyarn add -D babel-plugin-transform-react-remove-prop-types\nand add it to your Babel config like so:\n\nbabel.config.json-\n\"env\": {\n\"production\": {\n\"plugins\": [\n+\"transform-react-remove-prop-types\"\n]\n}\n}\n\nSavings will vary depending on the size of your app. In my case, I shaved off 16.5 KB or about 1.2% from my bundle.\n\n3. Consider unsafe-wrap mode:\nunsafe-wrap mode is, as the name states, a bit unsafe for the reasons well explained in plugin's docs.\n\nHowever, in my case, PropTypes were not accessed from anywhere and the application worked flawlessly.\n\nTo enable this mode, you need to change your Babel config like so:\n\nbabel.config.json-\n\"env\": {\n\"production\": {\n\"plugins\": [\n-\"transform-react-remove-prop-types\"\n+[\"transform-react-remove-prop-types\", {\n+\"mode\": \"unsafe-wrap\"\n+}]\n]\n}\n}\n\nThis way, I shaved off a total of 35.9 KB or about 2.5% from my bundle.\n\n4. Enable new JSX transform:\nEnabling new JSX transform will change the way Babel React preset transpiles JSX to pure JavaScript.\n\nI explained the benefits of enabling it in my other article: How to enable new JSX transform in React 17?.\n\nI highly recommend you to have a read. If that's TL;DR though, all you need to do for quick results is make sure that @babel/core and @babel/preset-env in your project are both on version 7.9.0 or newer, and change your Babel config like so:\n\nbabel.config.json\n\"presets\": [\n-\"@babel/preset-react\"\n+[\"@babel/preset-react\", {\n+\"runtime\": \"automatic\"\n+}]\n]\n\nAnd poof! Roughly 10.5 KB, or 0.7% of my bundle was gone.","markdown":"# Optimizing React apps: Hardcore edition","modifiedDesc":"You've heard of minifying. You've heard of lazy-loading. You've heard of tree shaking. You've done it all. Or did you? Here are some optimizations you may have never heard of before. Until now!

1. Enable \"loose\" transformations in @babel/preset-env:
Enabling \"loose\" transformations may make your application considerably smaller. I shaved off roughly 230.9 KB, or 16.2% from my bundle!

This, however, comes at a price: your application may break, both when enabling, and disabling these transformations.

In my case, the only fix I needed to do was related to iterating over HTMLFormControlsCollection (form.elements). I was no longer able to do e.g. [...form.elements], I had to swap it out for Array.from(form.elements).

Still tempted by the large savings? Give it a go by enabling loose flag in Babel config:

babel.config.json-
\"presets\": [
-\"@babel/preset-env\"
+[\"@babel/preset-env\", {
+\"loose\": true
+}]
]

2. Remove prop-types from your production bundle:
PropTypes are incredibly helpful during development, but they are of no use for your users. You can use babel-plugin-transform-react-remove-prop-types to remove PropTypes from your bundle.

To install, run:
npm install --save-dev babel-plugin-transform-react-remove-prop-types
or
yarn add -D babel-plugin-transform-react-remove-prop-types
and add it to your Babel config like so:

babel.config.json-
\"env\": {
\"production\": {
\"plugins\": [
+\"transform-react-remove-prop-types\"
]
}
}

Savings will vary depending on the size of your app. In my case, I shaved off 16.5 KB or about 1.2% from my bundle.

3. Consider unsafe-wrap mode:
unsafe-wrap mode is, as the name states, a bit unsafe for the reasons well explained in plugin's docs.

However, in my case, PropTypes were not accessed from anywhere and the application worked flawlessly.

To enable this mode, you need to change your Babel config like so:

babel.config.json-
\"env\": {
\"production\": {
\"plugins\": [
-\"transform-react-remove-prop-types\"
+[\"transform-react-remove-prop-types\", {
+\"mode\": \"unsafe-wrap\"
+}]
]
}
}

This way, I shaved off a total of 35.9 KB or about 2.5% from my bundle.

4. Enable new JSX transform:
Enabling new JSX transform will change the way Babel React preset transpiles JSX to pure JavaScript.

I explained the benefits of enabling it in my other article: How to enable new JSX transform in React 17?.

I highly recommend you to have a read. If that's TL;DR though, all you need to do for quick results is make sure that @babel/core and @babel/preset-env in your project are both on version 7.9.0 or newer, and change your Babel config like so:

babel.config.json
\"presets\": [
-\"@babel/preset-react\"
+[\"@babel/preset-react\", {
+\"runtime\": \"automatic\"
+}]
]

And poof! Roughly 10.5 KB, or 0.7% of my bundle was gone.","updatedAt":"2021-08-22T20:53:08.789Z","slug":"optimizing-react-apps","sanitizedHtml":"

Optimizing React apps: Hardcore edition

\n","id":"6","createdAt":"2021-08-22T20:53:08.789Z","displayDate":"22/8/2021","likes":1},{"name":"Tushar","title":"PHP Laravel","originalDesc":"Kubernetes is an excellent open-source container orchestration platform that brings automatic scaling, automatic recovery, observability, and many more features. Since it differs from traditional operations, it has changed the development and deployment workflows as well. Debugging an application on Kubernetes can be a challenge.\n\nDevSpace is a tool that helps you develop, deploy, troubleshoot simple or complex applications. We will use a Laravel project to demonstrate its features. \n\nLaravel is a popular framework used by the PHP community with great features like extensibility, inheritance, and reusability with high customization options.\n\nArchitecture:\nWe will look at ways to deploy a Laravel based application into a Kubernetes cluster for development and production environments. We will develop our application while the application is running in Kubernetes as if we are developing locally. And we will be able to troubleshoot our application in real-time with ease.\n\nThe desired setup uses four containers, in three pods:\n1. PHP-FPM container, which processes all the PHP assets.\n2. Nginx container, which serves static files and acts as a reverse proxy for the PHP assets.\n3. MySQL container, as the database.\n4. Redis container, as session and cache.","markdown":"# PHP Laravel Development with Kubernetes using DevSpace","modifiedDesc":"Kubernetes is an excellent open-source container orchestration platform that brings automatic scaling, automatic recovery, observability, and many more features. Since it differs from traditional operations, it has changed the development and deployment workflows as well. Debugging an application on Kubernetes can be a challenge.

DevSpace is a tool that helps you develop, deploy, troubleshoot simple or complex applications. We will use a Laravel project to demonstrate its features.

Laravel is a popular framework used by the PHP community with great features like extensibility, inheritance, and reusability with high customization options.

Architecture:
We will look at ways to deploy a Laravel based application into a Kubernetes cluster for development and production environments. We will develop our application while the application is running in Kubernetes as if we are developing locally. And we will be able to troubleshoot our application in real-time with ease.

The desired setup uses four containers, in three pods:
1. PHP-FPM container, which processes all the PHP assets.
2. Nginx container, which serves static files and acts as a reverse proxy for the PHP assets.
3. MySQL container, as the database.
4. Redis container, as session and cache.","updatedAt":"2021-08-22T20:52:19.267Z","slug":"php-laravel","sanitizedHtml":"

PHP Laravel Development with Kubernetes using DevSpace

\n","id":"7","createdAt":"2021-08-22T20:52:19.267Z","displayDate":"22/8/2021","likes":1},{"name":"asdasdkj","title":"kjdsksjdf","originalDesc":"
this is div
\n

this is h1

\n
this is br
\nthis is bold","markdown":"
this is div
\n

this is h1

\n
this is br
\nthis is bold\n# asdwewa\n# sdsfefkm","modifiedDesc":"<div>this is div</div>
<h1>this is h1</h1>
<br>this is br<br>
<b>this is bold</b>","updatedAt":"2021-08-27T14:33:21.125Z","slug":"kjdsksjdf","sanitizedHtml":"

<div>this is div</div>\n<h1>this is h1</h1>\n<br>this is br<br>\n<b>this is bold</b>

\n

asdwewa

\n

sdsfefkm

\n","id":"2867847303483","createdAt":"2021-08-27T12:59:06.346Z","displayDate":"27/8/2021","likes":0},{"name":"Anonymous","title":"asdasd","originalDesc":"asdads","markdown":"asdad","modifiedDesc":"asdads","createdAt":"2021-08-27T17:24:41.266Z","slug":"asdasd","sanitizedHtml":"

asdad

\n","id":"1377552136854","displayDate":"27/8/2021","likes":0}] \ No newline at end of file diff --git a/backend/controllers/1articles.js b/backend/controllers/1articles.js deleted file mode 100644 index 49e884d..0000000 --- a/backend/controllers/1articles.js +++ /dev/null @@ -1,139 +0,0 @@ -const fs = require('fs').promises; -const marked = require('marked'); -const createDomPurify = require('dompurify'); -const { JSDOM } = require('jsdom'); -const slugify = require('slugify'); - -const dompurify = createDomPurify(new JSDOM().window); - -let activeLikeBtns, srcPg; - -exports.preserveLikeBtnsStateController = (res, body) => { - [activeLikeBtns, srcPg] = [body.data,body.pg]; - res.sendStatus(200); -}; - -// exports.poweredbyController = res => res.render('powered-by'); -exports.newController = res => res.render('new', { article: {}, activeLikeBtns }); - -exports.readController = async (res, id, pg) => { - try { - const response = await fs.readFile('backend/db.json','utf8') || '[]'; // read from file - const articles = await JSON.parse(response); - - if(pg === 'index') { // [GET], index pg - articles.sort((a,b) => new Date(b.createdAt) - new Date(a.createdAt)); // sort objects inside array in descending order of created date - res.render('index', { articles, activeLikeBtns, srcPg }); // calling frontend pg - - [activeLikeBtns, srcPg] = [null,null]; - } else { // [GET], other pgs - show, edit - const article = articles.find(article => article.id === id); - if(!article) return res.sendStatus(500); - res.render(pg, { article, activeLikeBtns }); // calling frontend pg - } - } catch (err) { - console.log('err ->',err); - res.send(err); - } -}; - -exports.writeController = async (req, res, event, pg) => { - const { body:article, params:{ id }={} } = req; - - article.name = article.name || 'Anonymous'; - - const chars1 = { '<': '<', '>': '>' }; - const chars2 = { '<': '<', '>': '>' }; - - article.modifiedDesc = article.originalDesc // for display - .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/(\r\n){2,}/g,'

') - .replace(/\r\n/g,'
') - .replace(/\s{2,}/g,'') - .replace(/(
|\s)+$/,''); // remove n
s from end - // console.log('1 originalDesc',article.originalDesc,'\nmodifiedDesc',article.modifiedDesc); - article.originalDesc = article.modifiedDesc - .replace(/
/g,'\n') // for edit - .replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - // console.log('\n2 originalDesc',article.originalDesc,'\nmodifiedDesc',article.modifiedDesc); - - // console.log('\n1 markdown',article.markdown); //,'\nmodifiedDesc',article.modifiedDesc); - const modifiedMd = article.markdown - .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/\r\n/g,'<>') - .replace(/\s{2,}/g,'') - .replace(/<>/g,'\n') - .replace(/(\n|\s)+$/,''); - // console.log('\n2 markdown',modifiedMd); //,'\nmodifiedDesc',article.modifiedDesc); - - article[event] = new Date(); - - try { - article.slug = slugify(article.title, { lower: true, strict: true }); // generate string from article title to use as url - article.sanitizedHtml = dompurify.sanitize(marked(modifiedMd)); // convert markdown to html and purify the html - article.markdown = modifiedMd.replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - // console.log('\n3 markdown',article.markdown); - - const response = await fs.readFile('backend/db.json','utf8') || '[]'; // read from file - const articles = await JSON.parse(response); - - if(!id) { // [POST], new article - article.id = Math.trunc((Math.random() * 8735012) * (Math.random() * 1029456)) + ''; - const displayDate = article.createdAt.toLocaleDateString(); - const chkDate = /^\d\//; // check string starts with '[1-9]/' i.e. date 1 - 9 only - article.displayDate = chkDate.test(displayDate) ? '0'+displayDate : displayDate; - article.likes = 0; - articles.push(article); - } else { // [PUT], update article - article.id = id; - const i = articles.findIndex(article => article.id === id); - if(i === -1) return res.status(404).send('Unable to update article!'); - article.createdAt = articles[i].createdAt; - article.displayDate = articles[i].displayDate; - article.likes = articles[i].likes; - articles.splice(i,1,article); // replace old article with updated article - } - - await fs.writeFile('backend/db.json',JSON.stringify(articles)); // write to file - res.redirect(`/articles/${article.id}`); // api calling - } catch (err) { - console.log('err ->',err); - res.render(pg, { article }); // calling frontend pg - } -}; - -exports.deleteController = async (res, id) => { - try { - const response = await fs.readFile('backend/db.json','utf8') || '[]'; // read from file - const articles = await JSON.parse(response); - - const i = articles.findIndex(article => article.id === id); - if(i === -1) return res.status(404).send('Unable to delete article!'); - if(i < 5) return res.status(405).send("Can't delete first 5 articles currently!\nTry again later..."); - articles.splice(i,1); // delete requested article - - await fs.writeFile('backend/db.json',JSON.stringify(articles)); // write to file - res.redirect('/'); // api calling - } catch (err) { - console.log('err ->',err); - res.send(err); - } -}; - -exports.likeController = async (req, res) => { - const { body:{ data:likeBtnState }, params:{ id } } = req; - try { - const response = await fs.readFile('backend/db.json','utf8') || []; // read from file - const articles = await JSON.parse(response); - - const i = articles.findIndex(article => article.id === id); - if(i === -1) return res.sendStatus(500); - res.status(200).json({ likes: likeBtnState ? ++articles[i].likes : --articles[i].likes }); - - await fs.writeFile('backend/db.json', JSON.stringify(articles)); // write to file - } catch (err) { - console.log('err ->',err); - res.send(err); - } -}; - diff --git a/backend/controllers/2articles.js b/backend/controllers/2articles.js deleted file mode 100644 index 36b0d7b..0000000 --- a/backend/controllers/2articles.js +++ /dev/null @@ -1,285 +0,0 @@ -const mdToHtml = require('marked'); -const createDomPurify = require('dompurify'); -const { JSDOM } = require('jsdom'); -const { ObjectId } = require('mongodb'); // to convert from type string to ObjectId of _id - -const articleModel = require('../models/article'); - -const dompurify = createDomPurify(new JSDOM().window); - -// function tryCatch0(fn, res, next, id, pg) { -// return fn(res, next, id, pg).catch(next); - // return (res, next, id, pg) => fn(res, next).catch(next); - - /*try { - fn(res, next, id, pg); - } catch (err) { - next(err); - }*/ -// } -// const tryCatch1 = fn => (res, next) => { // works fine -// return fn(res, next).catch(next); - // return (res, next, id, pg) => fn(res, next).catch(next); - /*try { - fn(res, next, id, pg); - } catch (err) { - next(err); - }*/ -// }; - -// global try catch block to handle both user & system generated errs -function catchErr(fn) { - // return (res, next) => fn(res, next).catch(next); - // return (next, res) => fn(next, res).catch(res); // works fine - /*if(typeof b === 'function') - return (a, b, c, d) => fn(a, b, c, d).catch(b); - return (a, b, c, d) => fn(a, b, c, d).catch(c);*/ - return (a, b, c, d) => { - if(typeof b === 'function') fn(a, b, c, d).catch(b); - else fn(a, b, c, d).catch(c); - }; - // return fn => fn.catch; - // return fn => fn(a, b, c, d).catch(c); -} - -// global fn to initialize err object to be thrown to user -function createErrObj(msg, code) { - const err = new Error(msg); - err.statusCode = code; - return err; -} - -let activeLikeBtns, srcPg; - -exports.preserveLikeBtnsStateController = (res, body) => { - [activeLikeBtns, srcPg] = [body.data,body.pg]; - res.sendStatus(200); -}; - -exports.newController = res => res.render('new', { article: {}, activeLikeBtns }); - -// exports.readController = (res, next, id, pg) => tryCatch(async (res, next, id, pg) => { -/* exports.readController = tryCatch(async (res, next, id, pg) => { - // try { - // console.log(typeof id,id,typeof next,next,typeof res,res); - if(pg === 'index') { // [GET], index pg - const response = await articleModel.find().sort({ createdAt: -1 }).lean() || []; - // response.sort((a,b) => new Date(b.createdAt) - new Date(a.createdAt)); // sort objects inside array in descending order of created date - // console.log(response); - res.status(200).render('index', { articles: response, activeLikeBtns, srcPg }); // calling frontend pg - - [activeLikeBtns, srcPg] = [null,null]; - } else { // [GET], other pgs - show, edit - const response = await articleModel.findById(id).lean(); - // if(!response) return res.sendStatus(500); - if(!response) throw new Error('Something went wrong!\tPlease try again later...'); - - res.status(200).render(pg, { article: response, activeLikeBtns }); // calling frontend pg - } - // } catch (err) { - // // console.log(error); - // next(err); - // } - // res.send('its'+pg); -// }, res, next, id, pg); -});*/ - -exports.readController = catchErr(async (res, next, id, pg) => { - // try { - if(pg === 'index') { // [GET], index pg - const response = await articleModel.find().sort({ createdAt: -1 }).lean() || []; - // response.sort((a,b) => new Date(b.createdAt) - new Date(a.createdAt)); // sort objects inside array in descending order of created date - // console.log(response); - res.status(200).render('index', { articles: response, activeLikeBtns, srcPg }); // calling frontend pg - - [activeLikeBtns, srcPg] = [null,null]; - } else { // [GET], other pgs - show, edit - const response = await articleModel.findById(id).lean(); - // if(!response) return res.sendStatus(500); - if(!response) throw new Error('Something went wrong!\tPlease try again later...'); - - // res.status(200).render(pg, { article: response, activeLikeBtns }); // calling frontend pg - res.status(200).render(pg, { article: response, activeLikeBtns, srcPg }); // calling frontend pg, sending srcPg for edit pg - } - /*} catch (err) { - // console.log(error); - next(err); - }*/ - // res.send('its'+pg); -}); - -exports.writeController = catchErr(async (req, res, next, type) => { - // const { body:article, body:{ username='Anonymous', title, originalDesc, markdown }, params:{ id }={} } = req; - const { body:article, body:{ title, originalDesc, markdown }, params:{ id }={} } = req; - - const username = article.username || 'Anonymous'; - // console.log('username',username,article.username,req,username || false); - // article.username = article.username || 'Anonymous'; - /*if(username) { - // article.username = article.username.length < 3 ? ; - if(username.length < 3) {*/ - /*const err = new Error('Username must be at least 3 chars long!\tPlease insert appropriate name...'); - err.statusCode = 422; - throw err;*/ - /*throw createErrObj('Username must be at least 3 chars long!\tPlease insert appropriate name...',422); - } - } else article.username = 'Anonymous';*/ - - const chkSpclChars = /(?![\s-])\W|\n|\t|\r/g; // chk special chars but not spaces, -, _ - // if(username !== 'Anonymous' && chkSpclChars.test(username)) - // throw createErrObj('Invalid Name!\tPlease insert appropriate name...',422); - // const chkFields = /(?:\S){10,}/g; - // const chkFields = /(?:\S){10,}|(?!\s{1,2})/g; - // const chkFields = /\w/g; - const chkAlphabets = /[a-zA-Z]/g; // count no. of chars[a-zA-Z] in the string containing all type of chars - // const [chkSpclChars1, chkAlphabets1] = [/(?![\s-])\W/g, /[a-zA-Z]/g]; - // const chkStringLength = (string, minlen, maxlen) => { - function chkStringLength(string, minlen, maxlen) { - const no_of_alphabets = (string.match(chkAlphabets) || []).length; - // console.log(len < 3 || len > 10); - return no_of_alphabets < minlen || no_of_alphabets > maxlen; - } - - const errmsg = field => createErrObj(`Invalid or smaller ${field}!\tPlease insert appropriate ${field}...`,422); - /*if(username) { - if((username.match(chkAlphabets) || []).length < 3) - throw createErrObj('Invalid Name!\tPlease insert appropriate name...',422); - } else article.username = 'Anonymous';*/ - // if(username !== 'Anonymous' && (username.match(chkAlphabets) || []).length < 3) - /*if(username !== 'Anonymous' && - (chkSpclChars.test(username) || - (username.match(chkAlphabets) || []).length < 3 || - (username.match(chkAlphabets) || []).length > 10))*/ - if(username !== 'Anonymous' && (chkStringLength(username,3,15) || chkSpclChars.test(username))) - // throw createErrObj('Invalid or smaller name!\tPlease insert appropriate name...',422); - // throw createErrObj(errmsg('name'),422); - throw errmsg('name'); - // if(!article.title || !/(?:\S)+/g.test(article.title)) - // if(!title || (title.match(chkAlphabets) || []).length < 5) - // if(!title || chkSpclChars.test(title) || (title.match(chkAlphabets) || []).length < 5) - if(!title || chkStringLength(title,5,20) || chkSpclChars.test(title)) - // throw createErrObj('Invalid or smaller title!\tPlease insert appropriate title...',422); - // throw createErrObj(errmsg('title'),422); - throw errmsg('title'); - // if(!article.originalDesc || !chkFields.test(article.originalDesc)) - // if(!originalDesc || (originalDesc.match(chkAlphabets) || []).length < 50) - if(!originalDesc || chkStringLength(originalDesc,50,200)) - // throw createErrObj('Invalid or smaller description!\tPlease insert appropriate description...',422); - // throw createErrObj(errmsg('description'),422); - throw errmsg('description'); - // console.log(article.originalDesc); - // if(!markdown || (markdown.match(chkAlphabets) || []).length < 20) - if(!markdown || chkStringLength(markdown,20,70)) - // throw createErrObj('Invalid or smaller markdown!\tPlease insert appropriate markdown...',422); - // throw createErrObj(errmsg('markdown'),422); - throw errmsg('markdown'); - - // console.log(article); - // try { - - article.username = username.replace(/\s{2,}/g,' '); - article.title = title.replace(/\s{2,}/g,' '); - - const chars1 = { '<': '<', '>': '>' }; - const chars2 = { '<': '<', '>': '>' }; - - article.modifiedDesc = originalDesc // for display - // .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) - .replace(/(\r\n){2,}/g,'

') - .replace(/\r\n/g,'
') - .replace(/\s{2,}/g,'') - .replace(/(
|\s)+$/,''); // remove n
s from end - article.originalDesc = article.modifiedDesc - .replace(/
/g,'\n') // for edit - .replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - - const modifiedMd = markdown - // .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) - .replace(/\r\n/g,'<>') - .replace(/\s{2,}/g,'') - .replace(/<>/g,'\n') - .replace(/(\n|\s)+$/,''); - - // try { - article.sanitizedHtml = dompurify.sanitize(mdToHtml(modifiedMd)); // convert markdown to html and purify the html - article.markdown = modifiedMd.replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - - let response; - if(!id) { // [POST], new article - const displayDate = new Date().toLocaleDateString(); - // const chkDate = /^\d\//; // check string starts with '[1-9]/' i.e. date 1 - 9 only - // article.displayDate = chkDate.test(displayDate) ? '0'+displayDate : displayDate; - article.displayDate = displayDate[1] === '/' ? '0'+displayDate : displayDate; - - response = await articleModel.create(article); - // if(!response) throw new Error('Unable to post article!\tPlease try again later...'); - } else { // [PUT], update article - // console.log('update article',article); - response = await articleModel.findByIdAndUpdate(id, article, { new: true }).lean(); - // if(!response) throw new Error('Unable to update article!\tPlease try again later...'); - } - if(!response) throw new Error(`Unable to ${type} article!\tPlease try again later...`); - - // if(type === 'post') statusCode = 201; - // else statusCode = 200; - const statusCode = type === 'post' ? 201 : 200; - res.status(statusCode).redirect(`/articles/${response._id}`); // api calling - /*} catch (err) { - next(err); - }*/ -}); - -exports.deleteController = catchErr(async (res, next, id) => { - // console.log('id',_id,typeof _id); - // try { - // disabling deleting first 5 articles - const { _id } = (await articleModel.aggregate([ - { $sort: { createdAt: 1 } }, - { $skip: 5 }, - { $match: { _id: ObjectId(id) } }, - { $project: { _id: 1 } } - ]))[0] || {}; - // console.log('_id',_id); - if(!_id) { - /*const err = new Error("Can't delete this article!\tTry again later..."); - err.statusCode = 401; - throw err;*/ - throw createErrObj("Can't delete this article!\tTry again later...",401); - } - - // deleting article remaining of others - const { deletedCount } = await articleModel.deleteOne({ _id }).lean(); - if(!deletedCount) { - /*const err = new Error('Unable to delete article!\tPlease try again later...'); - err.statusCode = 404; - throw err;*/ - throw createErrObj('Unable to delete article!\tPlease try again later...',404); - } - - res.status(204).redirect('/'); // api calling - /*} catch (err) { - next(err); - }*/ -}); - -exports.likeController = catchErr(async (req, res, next) => { - const { body:{ data:likeBtnState }, params:{ id } } = req; - // try { - const { likes:oldLikes } = await articleModel.findById(id).select('likes -_id').lean() || {}; - // console.log(oldLikes); - if(!oldLikes) throw new Error('Something went wrong!\tPlease try again later...'); - - const { likes:newLikes } = await articleModel.findByIdAndUpdate(id, - { likes: likeBtnState ? oldLikes+1 : oldLikes-1 }, - { new: true }).select('likes -_id').lean() || {}; - // console.log(newLikes); - if(!newLikes) throw new Error('Something went wrong!\tPlease try again later...'); - - res.status(200).json({ likes: newLikes }); - /*} catch (err) { - next(err); - }*/ -}); - diff --git a/backend/controllers/3articles.js b/backend/controllers/3articles.js deleted file mode 100644 index 199efb0..0000000 --- a/backend/controllers/3articles.js +++ /dev/null @@ -1,287 +0,0 @@ -const mdToHtml = require('marked'); -const createDomPurify = require('dompurify'); -const { JSDOM } = require('jsdom'); -const { ObjectId } = require('mongodb'); // to convert from type string to ObjectId of _id - -const articleModel = require('../models/article'); - -const dompurify = createDomPurify(new JSDOM().window); - -// function tryCatch0(fn, res, next, id, pg) { -// return fn(res, next, id, pg).catch(next); - // return (res, next, id, pg) => fn(res, next).catch(next); - - /*try { - fn(res, next, id, pg); - } catch (err) { - next(err); - }*/ -// } -// const tryCatch1 = fn => (res, next) => { // works fine -// return fn(res, next).catch(next); - // return (res, next, id, pg) => fn(res, next).catch(next); - /*try { - fn(res, next, id, pg); - } catch (err) { - next(err); - }*/ -// }; - -// global try catch block to handle both user & system generated errs -function catchErr(fn) { - // return (res, next) => fn(res, next).catch(next); - // return (next, res) => fn(next, res).catch(res); // works fine - /*if(typeof b === 'function') - return (a, b, c, d) => fn(a, b, c, d).catch(b); - return (a, b, c, d) => fn(a, b, c, d).catch(c);*/ - return (a, b, c, d) => { - if(typeof b === 'function') fn(a, b, c, d).catch(b); - else fn(a, b, c, d).catch(c); - }; - // return fn => fn.catch; - // return fn => fn(a, b, c, d).catch(c); -} - -// global fn to initialize err object to be thrown to user -function createErrObj(msg, code) { - const err = new Error(msg); - err.statusCode = code; - return err; -} - -let activeLikeBtns, srcPg; - -exports.preserveLikeBtnsStateController = (res, body) => { - [activeLikeBtns, srcPg] = [body.data,body.pg]; - res.sendStatus(200); -}; - -exports.newController = res => res.render('new', { article: {}, activeLikeBtns }); - -// exports.readController = (res, next, id, pg) => tryCatch(async (res, next, id, pg) => { -/* exports.readController = tryCatch(async (res, next, id, pg) => { - // try { - // console.log(typeof id,id,typeof next,next,typeof res,res); - if(pg === 'index') { // [GET], index pg - const response = await articleModel.find().sort({ createdAt: -1 }).lean() || []; - // response.sort((a,b) => new Date(b.createdAt) - new Date(a.createdAt)); // sort objects inside array in descending order of created date - // console.log(response); - res.status(200).render('index', { articles: response, activeLikeBtns, srcPg }); // calling frontend pg - - [activeLikeBtns, srcPg] = [null,null]; - } else { // [GET], other pgs - show, edit - const response = await articleModel.findById(id).lean(); - // if(!response) return res.sendStatus(500); - if(!response) throw new Error('Something went wrong!\tPlease try again later...'); - - res.status(200).render(pg, { article: response, activeLikeBtns }); // calling frontend pg - } - // } catch (err) { - // // console.log(error); - // next(err); - // } - // res.send('its'+pg); -// }, res, next, id, pg); -});*/ - -exports.readController = catchErr(async (res, next, id, pg) => { - // try { - if(pg === 'index') { // [GET], index pg - const response = await articleModel.find().sort({ createdAt: -1 }).lean() || []; - // response.sort((a,b) => new Date(b.createdAt) - new Date(a.createdAt)); // sort objects inside array in descending order of created date - // console.log(response); - res.status(200).render('index', { articles: response, activeLikeBtns, srcPg }); // calling frontend pg - - [activeLikeBtns, srcPg] = [null,null]; - } else { // [GET], other pgs - show, edit - const response = await articleModel.findById(id).lean(); - // if(!response) return res.sendStatus(500); - if(!response) throw new Error('Something went wrong!\tPlease try again later...'); - - // res.status(200).render(pg, { article: response, activeLikeBtns }); // calling frontend pg - res.status(200).render(pg, { article: response, activeLikeBtns, srcPg }); // calling frontend pg, sending srcPg for edit pg - } - /*} catch (err) { - // console.log(error); - next(err); - }*/ - // res.send('its'+pg); -}); - -exports.writeController = catchErr(async (req, res, next, type) => { - // const { body:article, body:{ username='Anonymous', title, originalDesc, markdown }, params:{ id }={} } = req; - const { body:article, body:{ title, originalDesc, markdown }, params:{ id }={} } = req; - - const username = article.username || 'Anonymous'; - // console.log('username',username,article.username,req,username || false); - // article.username = article.username || 'Anonymous'; - /*if(username) { - // article.username = article.username.length < 3 ? ; - if(username.length < 3) {*/ - /*const err = new Error('Username must be at least 3 chars long!\tPlease insert appropriate name...'); - err.statusCode = 422; - throw err;*/ - /*throw createErrObj('Username must be at least 3 chars long!\tPlease insert appropriate name...',422); - } - } else article.username = 'Anonymous';*/ - - const chkSpclChars = /(?![\s-])\W|\n|\t|\r/g; // chk special chars but not spaces, -, _ - // if(username !== 'Anonymous' && chkSpclChars.test(username)) - // throw createErrObj('Invalid Name!\tPlease insert appropriate name...',422); - // const chkFields = /(?:\S){10,}/g; - // const chkFields = /(?:\S){10,}|(?!\s{1,2})/g; - // const chkFields = /\w/g; - const chkAlphabets = /[a-zA-Z]/g; // count no. of chars[a-zA-Z] in the string containing all type of chars - // const [chkSpclChars1, chkAlphabets1] = [/(?![\s-])\W/g, /[a-zA-Z]/g]; - // const chkStringLength = (string, minlen, maxlen) => { - function chkStringLength(string, minlen, maxlen) { - const no_of_alphabets = (string.match(chkAlphabets) || []).length; - // console.log(len < 3 || len > 10); - return no_of_alphabets < minlen || no_of_alphabets > maxlen; - } - - const errmsg = field => createErrObj(`Invalid or smaller ${field}!\tPlease insert appropriate ${field}...`,422); - /*if(username) { - if((username.match(chkAlphabets) || []).length < 3) - throw createErrObj('Invalid Name!\tPlease insert appropriate name...',422); - } else article.username = 'Anonymous';*/ - // if(username !== 'Anonymous' && (username.match(chkAlphabets) || []).length < 3) - /*if(username !== 'Anonymous' && - (chkSpclChars.test(username) || - (username.match(chkAlphabets) || []).length < 3 || - (username.match(chkAlphabets) || []).length > 10))*/ - if(username !== 'Anonymous' && (chkStringLength(username,3,15) || chkSpclChars.test(username))) - // throw createErrObj('Invalid or smaller name!\tPlease insert appropriate name...',422); - // throw createErrObj(errmsg('name'),422); - throw errmsg('name'); - // if(!article.title || !/(?:\S)+/g.test(article.title)) - // if(!title || (title.match(chkAlphabets) || []).length < 5) - // if(!title || chkSpclChars.test(title) || (title.match(chkAlphabets) || []).length < 5) - if(!title || chkStringLength(title,5,20) || chkSpclChars.test(title)) - // throw createErrObj('Invalid or smaller title!\tPlease insert appropriate title...',422); - // throw createErrObj(errmsg('title'),422); - throw errmsg('title'); - // if(!article.originalDesc || !chkFields.test(article.originalDesc)) - // if(!originalDesc || (originalDesc.match(chkAlphabets) || []).length < 50) - if(!originalDesc || chkStringLength(originalDesc,50,200)) - // throw createErrObj('Invalid or smaller description!\tPlease insert appropriate description...',422); - // throw createErrObj(errmsg('description'),422); - throw errmsg('description'); - // console.log(article.originalDesc); - // if(!markdown || (markdown.match(chkAlphabets) || []).length < 20) - if(!markdown || chkStringLength(markdown,20,70)) - // throw createErrObj('Invalid or smaller markdown!\tPlease insert appropriate markdown...',422); - // throw createErrObj(errmsg('markdown'),422); - throw errmsg('markdown'); - - // console.log(article); - // try { - - article.username = username.replace(/\s{2,}/g,' '); - article.title = title.replace(/\s{2,}/g,' '); - - const chars1 = { '<': '<', '>': '>' }; - const chars2 = { '<': '<', '>': '>' }; - - article.modifiedDesc = originalDesc // for display - // .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) - .replace(/(\r\n){2,}/g,'

') - .replace(/\r\n/g,'
') - .replace(/\s{2,}/g,'') - .replace(/(
|\s)+$/,''); // remove n
s from end - article.originalDesc = article.modifiedDesc - .replace(/
/g,'\n') // for edit - .replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - - const modifiedMd = markdown - // .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) - .replace(/\r\n/g,'<>') - .replace(/\s{2,}/g,'') - .replace(/<>/g,'\n') - .replace(/(\n|\s)+$/,''); - - // try { - article.sanitizedHtml = dompurify.sanitize(mdToHtml(modifiedMd)); // convert markdown to html and purify the html - article.markdown = modifiedMd.replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - - let response; - if(!id) { // [POST], new article - const displayDate = new Date().toLocaleDateString(); - // const chkDate = /^\d\//; // check string starts with '[1-9]/' i.e. date 1 - 9 only - // article.displayDate = chkDate.test(displayDate) ? '0'+displayDate : displayDate; - article.displayDate = displayDate[1] === '/' ? '0'+displayDate : displayDate; - - response = await articleModel.create(article); - // if(!response) throw new Error('Unable to post article!\tPlease try again later...'); - } else { // [PUT], update article - // console.log('update article',article); - response = await articleModel.findByIdAndUpdate(id, article, { new: true }).lean(); - // if(!response) throw new Error('Unable to update article!\tPlease try again later...'); - } - if(!response) throw new Error(`Unable to ${type} article!\tPlease try again later...`); - - // if(type === 'post') statusCode = 201; - // else statusCode = 200; - const statusCode = type === 'post' ? 201 : 200; - res.status(statusCode).redirect(`/articles/${response._id}`); // api calling - /*} catch (err) { - next(err); - }*/ -}); - -exports.deleteController = catchErr(async (res, next, id) => { - // console.log('id',_id,typeof _id); - // try { - // disabling deleting first 5 articles - const { _id } = (await articleModel.aggregate([ - { $sort: { createdAt: 1 } }, - { $skip: 5 }, - { $match: { _id: ObjectId(id) } }, - { $project: { _id: 1 } } - ]))[0] || {}; - // console.log('_id',_id); - if(!_id) { - /*const err = new Error("Can't delete this article!\tTry again later..."); - err.statusCode = 401; - throw err;*/ - throw createErrObj("Can't delete this article!\tTry again later...",401); - } - - // deleting article remaining of others - const { deletedCount } = await articleModel.deleteOne({ _id }).lean(); - if(!deletedCount) { - /*const err = new Error('Unable to delete article!\tPlease try again later...'); - err.statusCode = 404; - throw err;*/ - throw createErrObj('Unable to delete article!\tPlease try again later...',404); - } - - res.status(204).redirect('/'); // api calling - /*} catch (err) { - next(err); - }*/ -}); - -exports.likeController = catchErr(async (req, res, next) => { -// exports.likeController = async (req, res, next) => { - const { body:{ data:likeBtnState }, params:{ id } } = req; - // try { - const { likes:oldLikes } = await articleModel.findById(id).select('likes -_id').lean() || {}; - // console.log(oldLikes,typeof oldLikes); - // if(!oldLikes) throw new Error('Something went wrong!\tPlease try again later...'); - if(!Number.isInteger(oldLikes)) throw new Error('Something went wrong!\tPlease try again later...'); - - const { likes:newLikes } = await articleModel.findByIdAndUpdate(id, - { likes: likeBtnState ? oldLikes+1 : oldLikes-1 }, - { new: true }).select('likes -_id').lean() || {}; - // console.log(newLikes,typeof newLikes); - if(!Number.isInteger(newLikes)) throw new Error('Something went wrong!\tPlease try again later...'); - - res.status(200).json({ likes: newLikes }); - /*} catch (err) { - next(err); - }*/ -}); - diff --git a/backend/controllers/articles.js b/backend/controllers/articles.js index 6a9955c..4541b93 100644 --- a/backend/controllers/articles.js +++ b/backend/controllers/articles.js @@ -7,39 +7,12 @@ const articleModel = require('../models/article'); const dompurify = createDomPurify(new JSDOM().window); -// function tryCatch0(fn, res, next, id, pg) { -// return fn(res, next, id, pg).catch(next); - // return (res, next, id, pg) => fn(res, next).catch(next); - - /*try { - fn(res, next, id, pg); - } catch (err) { - next(err); - }*/ -// } -// const tryCatch1 = fn => (res, next) => { // works fine -// return fn(res, next).catch(next); - // return (res, next, id, pg) => fn(res, next).catch(next); - /*try { - fn(res, next, id, pg); - } catch (err) { - next(err); - }*/ -// }; - -// global try catch block to handle both user & system generated errs +// global try catch block to handle both system & user generated errs function catchErr(fn) { - // return (res, next) => fn(res, next).catch(next); - // return (next, res) => fn(next, res).catch(res); // works fine - /*if(typeof b === 'function') - return (a, b, c, d) => fn(a, b, c, d).catch(b); - return (a, b, c, d) => fn(a, b, c, d).catch(c);*/ return (a, b, c, d) => { if(typeof b === 'function') fn(a, b, c, d).catch(b); else fn(a, b, c, d).catch(c); }; - // return fn => fn.catch; - // return fn => fn(a, b, c, d).catch(c); } // global fn to initialize err object to be thrown to user @@ -56,282 +29,123 @@ exports.preserveLikeBtnsStateController = (res, body) => { res.sendStatus(200); }; -exports.newController = res => res.render('new', { article: {}, activeLikeBtns, srcPg }); - -// exports.readController = (res, next, id, pg) => tryCatch(async (res, next, id, pg) => { -/* exports.readController = tryCatch(async (res, next, id, pg) => { - // try { - // console.log(typeof id,id,typeof next,next,typeof res,res); - if(pg === 'index') { // [GET], index pg - const response = await articleModel.find().sort({ createdAt: -1 }).lean() || []; - // response.sort((a,b) => new Date(b.createdAt) - new Date(a.createdAt)); // sort objects inside array in descending order of created date - // console.log(response); - res.status(200).render('index', { articles: response, activeLikeBtns, srcPg }); // calling frontend pg - - [activeLikeBtns, srcPg] = [null,null]; - } else { // [GET], other pgs - show, edit - const response = await articleModel.findById(id).lean(); - // if(!response) return res.sendStatus(500); - if(!response) throw new Error('Something went wrong!\tPlease try again later...'); - - res.status(200).render(pg, { article: response, activeLikeBtns }); // calling frontend pg - } - // } catch (err) { - // // console.log(error); - // next(err); - // } - // res.send('its'+pg); -// }, res, next, id, pg); -});*/ +exports.newController = res => res.render('new', { article: {}, activeLikeBtns, srcPg }); // calling frontend pg exports.readController = catchErr(async (res, next, id, pg) => { - // try { - if(pg === 'index') { // [GET], index pg - const response = await articleModel.find().sort({ createdAt: -1 }).lean() || []; - // response.sort((a,b) => new Date(b.createdAt) - new Date(a.createdAt)); // sort objects inside array in descending order of created date - // console.log(response); - res.status(200).render('index', { articles: response, activeLikeBtns, srcPg }); // calling frontend pg - - [activeLikeBtns, srcPg] = [null,null]; - } else { // [GET], other pgs - show, edit - const response = await articleModel.findById(id).lean(); - // if(!response) return res.sendStatus(500); - if(!response) throw new Error('Something went wrong!\tPlease try again later...'); - - // res.status(200).render(pg, { article: response, activeLikeBtns }); // calling frontend pg - res.status(200).render(pg, { article: response, activeLikeBtns, srcPg }); // calling frontend pg, sending srcPg for edit pg - } - /*} catch (err) { - // console.log(error); - next(err); - }*/ - // res.send('its'+pg); + if(pg === 'index') { // [GET], index pg + const response = await articleModel.find().sort({ createdAt: -1 }).lean() || []; + res.status(200).render('index', { articles: response, activeLikeBtns, srcPg }); // calling frontend pg + + [activeLikeBtns, srcPg] = [null,null]; + } else { // [GET], other pgs - show, edit + const response = await articleModel.findById(id).lean(); + if(!response) throw new Error('Something went wrong!\tPlease try again later...'); + + res.status(200).render(pg, { article: response, activeLikeBtns, srcPg }); // calling frontend pg, sending srcPg for edit pg + } }); exports.writeController = catchErr(async (req, res, next, type) => { - // const { body:article, body:{ username='Anonymous', title, originalDesc, markdown }, params:{ id }={} } = req; - // const { body:article, body:{ title, originalDesc, markdown }, params:{ id }={} } = req; const { body:article, params:{ id }={} } = req; - // const [username, title, originalDesc, markdown] = [article.username.trim() || 'Anonymous', article.title.trim(), article.originalDesc.trim(), article.markdown.trim()]; const username = article.username.trim() || 'Anonymous'; const title = article.title.trim(); const originalDesc = article.originalDesc.trim(); const markdown = article.markdown.trim(); - // username = username || 'Anonymous'; - // console.log('username',username,article.username,req,username || false); - // article.username = article.username || 'Anonymous'; - /*if(username) { - // article.username = article.username.length < 3 ? ; - if(username.length < 3) {*/ - /*const err = new Error('Username must be at least 3 chars long!\tPlease insert appropriate name...'); - err.statusCode = 422; - throw err;*/ - /*throw createErrObj('Username must be at least 3 chars long!\tPlease insert appropriate name...',422); - } - } else article.username = 'Anonymous';*/ + // checking fields const errmsg = field => createErrObj(`Invalid or smaller ${field}!\tPlease insert appropriate ${field}...`,422); - // const chkSpclChars = /(?![\s-])\W|\n|\t|\r/g; // chk special chars but not spaces, -, _ - // if(username !== 'Anonymous' && chkSpclChars.test(username)) - // throw createErrObj('Invalid Name!\tPlease insert appropriate name...',422); - // const chkFields = /(?:\S){10,}/g; - // const chkFields = /(?:\S){10,}|(?!\s{1,2})/g; - // const chkFields = /\w/g; - const chkAlphabets = /[a-zA-Z]/g; // count no. of chars[a-zA-Z] in the string containing all type of chars - // const [chkSpclChars1, chkAlphabets1] = [/(?![\s-])\W/g, /[a-zA-Z]/g]; - // const chkStringLength = (string, minlen, maxlen) => { - // function chkStringLength(string, minlen, maxlen) { + const chkAlphabets = /[a-zA-Z]/g; // count no. of chars[a-zA-Z] in the string containing all types of chars function chkStringLength(string, minAlphabets, maxlen) { const no_of_alphabets = (string.match(chkAlphabets) || []).length; - // console.log(len < 3 || len > 10); - // return no_of_alphabets < minlen || no_of_alphabets > maxlen; return no_of_alphabets < minAlphabets || string.length > maxlen; } - /* const errmsg = field => createErrObj(`Invalid or smaller ${field}!\tPlease insert appropriate ${field}...`,422); - if(username) { - if((username.match(chkAlphabets) || []).length < 3) - throw createErrObj('Invalid Name!\tPlease insert appropriate name...',422); - } else article.username = 'Anonymous';*/ - - // const chkSpclChars = /(?![\s-])\W|\n|\t|\r/g; // chk special chars but not spaces, -, _ const chkSpclChars = /(?![\s\.-])\W/g; // chk special chars but not spaces, -, _, ., \n, \t, \r - // if(username !== 'Anonymous' && (username.match(chkAlphabets) || []).length < 3) - /*if(username !== 'Anonymous' && - (chkSpclChars.test(username) || - (username.match(chkAlphabets) || []).length < 3 || - (username.match(chkAlphabets) || []).length > 10))*/ - // if(username !== 'Anonymous' && (chkStringLength(username,3,15) || chkSpclChars.test(username))) + if(username !== 'Anonymous' && (chkStringLength(username,3,20) || chkSpclChars.test(username))) - // throw createErrObj('Invalid or smaller name!\tPlease insert appropriate name...',422); - // throw createErrObj(errmsg('name'),422); throw errmsg('name'); - // if(!article.title || !/(?:\S)+/g.test(article.title)) - // if(!title || (title.match(chkAlphabets) || []).length < 5) - // if(!title || chkSpclChars.test(title) || (title.match(chkAlphabets) || []).length < 5) - // if(!title || chkStringLength(title,5,20) || chkSpclChars.test(title)) if(!title || chkStringLength(title,5,25) || chkSpclChars.test(title)) - // throw createErrObj('Invalid or smaller title!\tPlease insert appropriate title...',422); - // throw createErrObj(errmsg('title'),422); throw errmsg('title'); - // if(!article.originalDesc || !chkFields.test(article.originalDesc)) - // if(!originalDesc || (originalDesc.match(chkAlphabets) || []).length < 50) - // if(!originalDesc || chkStringLength(originalDesc,50,200)) - // if(!originalDesc || chkStringLength(originalDesc,50,250)) if(!originalDesc || chkStringLength(originalDesc,500,4000)) - // throw createErrObj('Invalid or smaller description!\tPlease insert appropriate description...',422); - // throw createErrObj(errmsg('description'),422); throw errmsg('description'); - // console.log(article.originalDesc); - // if(!markdown || (markdown.match(chkAlphabets) || []).length < 20) - // if(!markdown || chkStringLength(markdown,20,70)) - // if(!markdown || chkStringLength(markdown,20,120)) if(!markdown || chkStringLength(markdown,20,2000)) - // throw createErrObj('Invalid or smaller markdown!\tPlease insert appropriate markdown...',422); - // throw createErrObj(errmsg('markdown'),422); throw errmsg('markdown'); - // console.log(article); - // try { - - function allowedSpclChars(string) { - // const chars = { '\s': ' ', '\.': '.', '-': '-', '_': '_' }; - // const chars = { '\s{2,}': ' ', '\.{2,}': '.', '-{2,}': '-', '_{2,}': '_' }; - // const chars = { /\s{2,}/: ' ', /\.{2,}/: '.', '-{2,}': '-', '_{2,}': '_' }; - return string - .replace(/\n|\t|\r/g,'') - .replace(/\s{2,}/g,' ') // it can cover \n{2,} | \t{2,} | \r{2,} - .replace(/\.{2,}/g,'.') - .replace(/-{2,}/g,'-') - .replace(/_{2,}/g,'_'); - - // return string.replace(/\s{2,}|\.{2,}|-{2,}|_{2,}/g, c => chars[c]); - } - // article.username = username.replace(/\s{2,}/g,' '); - // article.title = title.replace(/\s{2,}/g,' '); - // article.username = username - // .replace(/\s{2,}/g,' ') - // .replace(/\.{2,}/g,'.') - // .replace(/-{2,}/g,'-') - // .replace(/_{2,}/g,'_'); - - // console.log('1',article); - article.username = allowedSpclChars(username); - article.title = allowedSpclChars(title); - // console.log('2',article); - // return res.sendStatus(200); - - const chars1 = { '<': '<', '>': '>' }; - const chars2 = { '<': '<', '>': '>' }; - - // console.log('0', article); - article.modifiedDesc = originalDesc // for display - // .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) - // .replace(/(\r\n){2,}/g,'

') // \r is not appearing - // .replace(/\r\n/g,'
') // \r is not appearing - .replace(/\n{2,}/g,'

') - .replace(/\n/g,'
') - .replace(/\s{2,}/g,''); - // .replace(/(
|\s)+$/,''); // remove n
s and spaces from the end; used trim() instead - article.originalDesc = article.modifiedDesc - .replace(/
/g,'\n') // for edit - .replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - - // console.log('1', article,'\n2',markdown); - const modifiedMd = markdown - // .replace(/[<>]/g, c => chars1[c]) // replace < > with < > (to nullify html scripts) - .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) - // .replace(/\r\n/g,'<>') - // .replace(/\n/g,'<>') // \r is not appearing - // .replace(/\s{2,}/g,'') - // .replace(/<>/g,'\n'); - // .replace(/(\n|\s)+$/,''); // remove n
s and spaces from the end; used trim() instead - .replace(/(?!\n)\s{2,}/g,''); - // console.log('3', modifiedMd); - - // try { - article.sanitizedHtml = dompurify.sanitize(mdToHtml(modifiedMd)); // convert markdown to html and purify the html - article.markdown = modifiedMd.replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > - - let response; - if(!id) { // [POST], new article - const displayDate = new Date().toLocaleDateString(); - // const chkDate = /^\d\//; // check string starts with '[1-9]/' i.e. date 1 - 9 only - // article.displayDate = chkDate.test(displayDate) ? '0'+displayDate : displayDate; - article.displayDate = displayDate[1] === '/' ? '0'+displayDate : displayDate; - - response = await articleModel.create(article); - // if(!response) throw new Error('Unable to post article!\tPlease try again later...'); - } else // { // [PUT], update article - // console.log('update article',article); - response = await articleModel.findByIdAndUpdate(id, article, { new: true }).lean(); - // if(!response) throw new Error('Unable to update article!\tPlease try again later...'); - // } - if(!response) throw new Error(`Unable to ${type} article!\tPlease try again later...`); - - // if(type === 'post') statusCode = 201; - // else statusCode = 200; - const statusCode = type === 'post' ? 201 : 200; - res.status(statusCode).redirect(`/articles/${response._id}`); // api calling - /*} catch (err) { - next(err); - }*/ + // correcting fields after passing above test + function allowedSpclChars(string) { + return string + .replace(/\n|\t|\r/g,'') + .replace(/\s{2,}/g,' ') // it can cover \n{2,} | \t{2,} | \r{2,} + .replace(/\.{2,}/g,'.') + .replace(/-{2,}/g,'-') + .replace(/_{2,}/g,'_'); + } + article.username = allowedSpclChars(username); + article.title = allowedSpclChars(title); + + const chars1 = { '<': '<', '>': '>' }; + const chars2 = { '<': '<', '>': '>' }; + + article.modifiedDesc = originalDesc // for display + .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) + .replace(/\n{2,}/g,'

') + .replace(/\n/g,'
') + .replace(/\s{2,}/g,''); + article.originalDesc = article.modifiedDesc + .replace(/
/g,'\n') // for edit + .replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > + + const modifiedMd = markdown + .replace(/<|>/g, c => chars1[c]) // replace < > with < > (to disable html scripts) + .replace(/(?!\n)\s{2,}/g,''); + article.sanitizedHtml = dompurify.sanitize(mdToHtml(modifiedMd)); // convert markdown to html and purify the html + article.markdown = modifiedMd.replace(/(<)|(>)/g, c => chars2[c]); // replace < > with < > + + let response; + if(!id) { // [POST], new article + const displayDate = new Date().toLocaleDateString(); + article.displayDate = displayDate[1] === '/' ? '0'+displayDate : displayDate; + + response = await articleModel.create(article); + } else // [PUT], update article + response = await articleModel.findByIdAndUpdate(id, article, { new: true }).lean(); + + if(!response) throw new Error(`Unable to ${type} article!\tPlease try again later...`); + + const statusCode = type === 'post' ? 201 : 200; + res.status(statusCode).redirect(`/articles/${response._id}`); // api calling }); exports.deleteController = catchErr(async (res, next, id) => { - // console.log('id',_id,typeof _id); - // try { - // disabling deleting first 5 articles - const { _id } = (await articleModel.aggregate([ - { $sort: { createdAt: 1 } }, - { $skip: 5 }, - { $match: { _id: ObjectId(id) } }, - { $project: { _id: 1 } } - ]))[0] || {}; - // console.log('_id',_id); - if(!_id) { - /*const err = new Error("Can't delete this article!\tTry again later..."); - err.statusCode = 401; - throw err;*/ - throw createErrObj("Can't delete this article!\tTry again later...",401); - } - - // deleting article remaining of others - const { deletedCount } = await articleModel.deleteOne({ _id }).lean(); - if(!deletedCount) { - /*const err = new Error('Unable to delete article!\tPlease try again later...'); - err.statusCode = 404; - throw err;*/ - throw createErrObj('Unable to delete article!\tPlease try again later...',404); - } - - res.status(204).redirect('/'); // api calling - /*} catch (err) { - next(err); - }*/ + // disabling deletion of first 5 articles + const { _id } = (await articleModel.aggregate([ + { $sort: { createdAt: 1 } }, + { $skip: 5 }, + { $match: { _id: ObjectId(id) } }, + { $project: { _id: 1 } } + ]))[0] || {}; + if(!_id) throw createErrObj("Can't delete this article!\tTry again later...",401); + + // deleting article remaining of others + const { deletedCount } = await articleModel.deleteOne({ _id }).lean(); + if(!deletedCount) throw createErrObj('Unable to delete article!\tPlease try again later...',404); + + res.status(204).redirect('/'); // api calling }); exports.likeController = catchErr(async (req, res, next) => { -// exports.likeController = async (req, res, next) => { const { body:{ data:likeBtnState }, params:{ id } } = req; - // try { - const { likes:oldLikes } = await articleModel.findById(id).select('likes -_id').lean() || {}; - // console.log(oldLikes,typeof oldLikes); - // if(!oldLikes) throw new Error('Something went wrong!\tPlease try again later...'); - if(!Number.isInteger(oldLikes)) throw new Error('Something went wrong!\tPlease try again later...'); - - const { likes:newLikes } = await articleModel.findByIdAndUpdate(id, - { likes: likeBtnState ? oldLikes+1 : oldLikes-1 }, - { new: true }).select('likes -_id').lean() || {}; - // console.log(newLikes,typeof newLikes); - if(!Number.isInteger(newLikes)) throw new Error('Something went wrong!\tPlease try again later...'); - - res.status(200).json({ likes: newLikes }); - /*} catch (err) { - next(err); - }*/ + + const { likes:oldLikes } = await articleModel.findById(id).select('likes -_id').lean() || {}; + if(!Number.isInteger(oldLikes)) throw new Error('Something went wrong!\tPlease try again later...'); + + const { likes:newLikes } = await articleModel.findByIdAndUpdate(id, + { likes: likeBtnState ? oldLikes+1 : oldLikes-1 }, + { new: true }).select('likes -_id').lean() || {}; + if(!Number.isInteger(newLikes)) throw new Error('Something went wrong!\tPlease try again later...'); + + res.status(200).json({ likes: newLikes }); }); diff --git a/backend/models/1article.js b/backend/models/1article.js deleted file mode 100644 index cddcbef..0000000 --- a/backend/models/1article.js +++ /dev/null @@ -1,45 +0,0 @@ -const mongoose = require('mongoose'); -// const uniqueValidator = require('mongoose-unique-validator'); - -function chkOtherChars(string) { - // console.log('string',string); - // const chkSpclChars = /(?![\s-])\W|\n|\t|\r/g; - const chkSpclChars = /(?![\s-])\W/g; // \n,\t,\r will be covered in \s in below regexp - const chkSpaces = /\s{2,}/g; - // if((chkSpclChars.test(string)) || (chkSpaces.test(string))) return false; - return !(chkSpclChars.test(string) || chkSpaces.test(string)); -} - -function chkStringLength(string, minlen, maxlen) { - const chkAlphabets = /[a-zA-Z]/g; - const no_of_alphabets = (string.match(chkAlphabets) || []).length; - return !(no_of_alphabets < minlen || no_of_alphabets > maxlen); -} - -const articleSchema = mongoose.Schema({ - // username: { type: String, minLength: 3, maxLength: 20, trim: true, validate: value => validator(value) }, - // title: { type: String, minLength: 5, maxLength: 25, trim: true, validate: value => validator(value) }, - // originalDesc: { type: String, minLength: 50, maxLength: 250, trim: true }, - // markdown: { type: String, minLength: 20, maxLength: 120, trim: true }, - // username: { type: String, trim: true, validate: data => chkOtherChars(data) && chkStringLength(data,3,15) }, - // title: { type: String, trim: true, validate: data => chkOtherChars(data) && chkStringLength(data,20,5) }, - // originalDesc: { type: String, trim: true, validate: data => chkStringLength(data,50,200) }, - // markdown: { type: String, trim: true, validate: data => chkStringLength(data,20,70) }, - - username: { type: String, trim: true, validate: data => chkStringLength(data,3,15) && chkOtherChars(data) }, - title: { type: String, trim: true, validate: data => chkStringLength(data,5,20) && chkOtherChars(data) }, - originalDesc: { type: String, trim: true, validate: data => chkStringLength(data,50,200) }, - markdown: { type: String, trim: true, validate: data => chkStringLength(data,20,70) }, - - modifiedDesc: { type: String, required: true }, - sanitizedHtml: { type: String, required: true }, - displayDate: { type: String, required: true }, - likes: { type: Number, default: 0 }, - -}, { timestamps: true } ); - -// articleSchema.plugin(uniqueValidator); - -// export default mongoose.model('product',productSchema); -module.exports = mongoose.model('article',articleSchema); - diff --git a/backend/models/article.js b/backend/models/article.js index c911647..4ca44ac 100644 --- a/backend/models/article.js +++ b/backend/models/article.js @@ -1,47 +1,20 @@ const mongoose = require('mongoose'); -// const uniqueValidator = require('mongoose-unique-validator'); -// function chkStringLength(string, minlen, maxlen) { function chkStringLength(string, minAlphabets) { - // console.log('string',string); const chkAlphabets = /[a-zA-Z]/g; - // const no_of_alphabets = (string.match(chkAlphabets) || []).length; - // return !(no_of_alphabets < minlen || no_of_alphabets > maxlen); const no_of_alphabets = (string.match(chkAlphabets) || []).length; return no_of_alphabets > minAlphabets; } function chkOtherChars(string) { - // console.log('string',string); - // const chkSpclChars = /(?![\s-])\W|\n|\t|\r/g; - // const chkSpclChars = /(?![\s-])\W/g; // \n,\t,\r will be covered in \s in below regexp - // const chkSpaces = /\s{2,}/g; - // const chkSpclChars = /(?![\s\.-])\W|\n/g; // \t,\r will be covered in \s in below regexp const chkSpclChars = /(?![\s\.-])\W|\n|\t|\r/g; // it wont chk spaces, -, _, . const chkAllowedSpclChars = /\s{2,}|\.{2,}|-{2,}|_{2,}/g; - // const chkSpaces = /\s{2,}|\.{2,}|-{2,}|_{2,}|\n|\t|\r/g; - // if((chkSpclChars.test(string)) || (chkSpaces.test(string))) return false; return !(chkSpclChars.test(string) || chkAllowedSpclChars.test(string)); } const articleSchema = mongoose.Schema({ - // username: { type: String, minLength: 3, maxLength: 20, trim: true, validate: value => validator(value) }, - // title: { type: String, minLength: 5, maxLength: 25, trim: true, validate: value => validator(value) }, - // originalDesc: { type: String, minLength: 50, maxLength: 250, trim: true }, - // markdown: { type: String, minLength: 20, maxLength: 120, trim: true }, - // username: { type: String, trim: true, validate: data => chkOtherChars(data) && chkStringLength(data,3,15) }, - // title: { type: String, trim: true, validate: data => chkOtherChars(data) && chkStringLength(data,20,5) }, - // originalDesc: { type: String, trim: true, validate: data => chkStringLength(data,50,200) }, - // markdown: { type: String, trim: true, validate: data => chkStringLength(data,20,70) }, - // username: { type: String, trim: true, validate: data => chkStringLength(data,3,15) && chkOtherChars(data) }, - // title: { type: String, trim: true, validate: data => chkStringLength(data,5,20) && chkOtherChars(data) }, - // originalDesc: { type: String, trim: true, validate: data => chkStringLength(data,50,200) }, - // markdown: { type: String, trim: true, validate: data => chkStringLength(data,20,70) }, - username: { type: String, trim: true, maxLength: 20, validate: data => chkStringLength(data,3) && chkOtherChars(data) }, - // username: { type: String, trim: true, maxLength: 20 }, title: { type: String, trim: true, maxLength: 25, validate: data => chkStringLength(data,5) && chkOtherChars(data) }, - // title: { type: String, trim: true, maxLength: 25 }, originalDesc: { type: String, trim: true, maxLength: 4000, validate: data => chkStringLength(data,500) }, markdown: { type: String, trim: true, maxLength: 2000, validate: data => chkStringLength(data,20) }, @@ -52,8 +25,5 @@ const articleSchema = mongoose.Schema({ }, { timestamps: true } ); -// articleSchema.plugin(uniqueValidator); - -// export default mongoose.model('product',productSchema); module.exports = mongoose.model('article',articleSchema); diff --git a/backend/routes/1articles.js b/backend/routes/1articles.js deleted file mode 100644 index 7bcf178..0000000 --- a/backend/routes/1articles.js +++ /dev/null @@ -1,57 +0,0 @@ -const express = require('express'); - -const { - // poweredbyController, - newController, - readController, - preserveLikeBtnsStateController, - writeController, - deleteController, - likeController -} = require('../controllers/articles'); - -// const app = express(); -// const { app } = require('../../server'); -let router1, router2; -router1 = router2 = express.Router(); - -app.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -// app.get('/powered-by', (_, res) => res.render('powered-by')); // wont work for like btns -// router.get('/powered-by', (_, res) => poweredbyController(res)); // no need for like btns - -// router.route('/articles') -app.use('/articles', router); - -// router.route('/articles') -router.get('/new', (_, res) => newController(res)); - -router.post('/:id', (req, res) => preserveLikeBtnsStateController(res,req.body)); - -router.get('/:id', (req, res) => readController(res,req.params.id,'show')); - -router.post('/', (req, res) => writeController(req,res,'createdAt','new')); - -router.get('/edit/:id', (req, res) => readController(res,req.params.id,'edit')); - -router.put('/:id', (req, res) => writeController(req,res,'updatedAt','edit')); - -// router.delete('/:id', (req, res) => deleteController(res,req.params.id)); -router.delete('/:id', ({ params: { id } }, res) => deleteController(res,id)); - -router.patch('/like/:id', likeController); - -// router.get('/powered-by', (_, res) => res.render('articles/powered-by')); // not working -app.get('/powered-by', (_, res) => res.render('powered-by')); // not working - -app.all('*', (_,res) => res.send('

404!
Page not found...

')); - -app.use((err, req, res, next) => { // express err handler, global err format for printing user defined errs - const { statusCode=500, message, stack } = err; - const error = { statusCode, message, stack }; - // console.log('1',errFormat); - console.error({ error }); -}); - -module.exports = app; - diff --git a/backend/routes/2articles.js b/backend/routes/2articles.js deleted file mode 100644 index 565a0c9..0000000 --- a/backend/routes/2articles.js +++ /dev/null @@ -1,57 +0,0 @@ -const express = require('express'); - -const { - // poweredbyController, - newController, - readController, - preserveLikeBtnsStateController, - writeController, - deleteController, - likeController -} = require('../controllers/articles'); - -// const app = express(); -// const router = express.Router(); -let router1, router2; -router1 = router2 = express.Router(); - -router1.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -// app.get('/powered-by', (_, res) => res.render('powered-by')); // wont work for like btns -// router.get('/powered-by', (_, res) => poweredbyController(res)); // no need for like btns - -// router.route('/articles') -router1.use('/articles', router2); - -// router.route('/articles') -router2.get('/new', (_, res) => newController(res)); - -router2.post('/:id[0-9]', (req, res) => preserveLikeBtnsStateController(res,req.body)); - -router2.get('/:id[0-9]', (req, res) => readController(res,req.params.id,'show')); - -router2.post('/', (req, res) => writeController(req,res,'createdAt','new')); - -router2.get('/edit/:id[0-9]', (req, res) => readController(res,req.params.id,'edit')); - -router2.put('/:id[0-9]', (req, res) => writeController(req,res,'updatedAt','edit')); - -// router.delete('/:id', (req, res) => deleteController(res,req.params.id)); -router2.delete('/:id[0-9]', ({ params: { id } }, res) => deleteController(res,id)); - -router2.patch('/like/:id[0-9]', likeController); - -// router.get('/powered-by', (_, res) => res.render('articles/powered-by')); // not working -router1.get('/powered-by', (_, res) => res.render('powered-by')); // not working - -router1.all('*', (_,res) => res.send('

404!
Page not found...

')); - -router1.use((err, req, res, next) => { // express err handler, global err format for printing user defined errs - const { statusCode=500, message, stack } = err; - const error = { statusCode, message, stack }; - // console.log('1',errFormat); - console.error({ error }); -}); - -module.exports = router1; - diff --git a/backend/routes/3articles.js b/backend/routes/3articles.js deleted file mode 100644 index dfdf49e..0000000 --- a/backend/routes/3articles.js +++ /dev/null @@ -1,66 +0,0 @@ -const express = require('express'); - -const { - // poweredbyController, - newController, - readController, - preserveLikeBtnsStateController, - writeController, - deleteController, - likeController -} = require('../controllers/articles'); - -// const app = express(); -const router = express.Router(); -// let router1, router2; -// router1 = router2 = express.Router(); - -// router1.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -// app.get('/powered-by', (_, res) => res.render('powered-by')); // wont work for like btns -// router.get('/powered-by', (_, res) => poweredbyController(res)); // no need for like btns - -// router.route('/articles') -// router1.use('/articles', router2); -// router.patch('/like/:id', likeController); - -// router.route('/articles') -// router.get('/new', (_, res) => newController(res)); - -// router.post('/:id', ({ body }, res) => preserveLikeBtnsStateController(res,body)); - -// router.get('/:id', ({ params: { id } }, res, next) => readController(res,next,id,'show')); - -// router.post('/', (req, res, next) => writeController(req,res,next,'createdAt','new')); -// router.post('/', (req, res, next) => writeController(req,res,next,'new')); -// router.post('/', (req, res, next) => writeController(req,res,next,'post')); - -// router.get('/edit/:id', ({ params: { id } }, res, next) => readController(res,next,id,'edit')); - -// router.put('/:id', (req, res, next) => writeController(req,res,next,'updatedAt','edit')); -// router.put('/:id', (req, res, next) => writeController(req,res,next,'edit')); -// router.put('/:id', (req, res, next) => writeController(req,res,next,'update')); - -// router.delete('/:id', (req, res) => deleteController(res,req.params.id)); -// router.delete('/:id', ({ params: { id } }, res, next) => deleteController(res,next,id)); -// console.log('routes'); -// router.patch('/like/:id', likeController); -// router.patch('/like/:id([a-z0-9]{24})', () => console.log('like'),likeController); -// router.patch('/like/:id', (q,s,next) => {console.log('like'); next();},likeController); -router.patch('/like/:id', (req, res, next) => likeController(req, res, next)); -// console.log('routes'); - -// router.get('/powered-by', (_, res) => res.render('articles/powered-by')); // not working -// router1.get('/powered-by', (_, res) => res.render('powered-by')); // not working - -// router1.all('*', (_,res) => res.send('

404!
Page not found...

')); - -// router1.use((err, req, res, next) => { // express err handler, global err format for printing user defined errs -// const { statusCode=500, message, stack } = err; -// const error = { statusCode, message, stack }; -// // console.log('1',errFormat); -// console.error({ error }); -// }); - -module.exports = router; - diff --git a/backend/routes/articles.js b/backend/routes/articles.js index 5457e93..a074b83 100644 --- a/backend/routes/articles.js +++ b/backend/routes/articles.js @@ -1,7 +1,6 @@ const express = require('express'); const { - // poweredbyController, newController, readController, preserveLikeBtnsStateController, @@ -10,54 +9,23 @@ const { likeController } = require('../controllers/articles'); -// const app = express(); const router = express.Router(); -// let router1, router2; -// router1 = router2 = express.Router(); -// router1.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -// app.get('/powered-by', (_, res) => res.render('powered-by')); // wont work for like btns -// router.get('/powered-by', (_, res) => poweredbyController(res)); // no need for like btns - -// router.route('/articles') -// router1.use('/articles', router2); -// router.patch('/like/:id', likeController); - -// router.route('/articles') router.get('/new', (_, res) => newController(res)); router.post('/:id', ({ body }, res) => preserveLikeBtnsStateController(res,body)); router.get('/:id', ({ params: { id } }, res, next) => readController(res,next,id,'show')); -// router.post('/', (req, res, next) => writeController(req,res,next,'createdAt','new')); -// router.post('/', (req, res, next) => writeController(req,res,next,'new')); router.post('/', (req, res, next) => writeController(req,res,next,'post')); router.get('/edit/:id', ({ params: { id } }, res, next) => readController(res,next,id,'edit')); -// router.put('/:id', (req, res, next) => writeController(req,res,next,'updatedAt','edit')); -// router.put('/:id', (req, res, next) => writeController(req,res,next,'edit')); router.put('/:id', (req, res, next) => writeController(req,res,next,'update')); -// router.delete('/:id', (req, res) => deleteController(res,req.params.id)); router.delete('/:id', ({ params: { id } }, res, next) => deleteController(res,next,id)); -// router.patch('/like/:id', likeController); router.patch('/like/:id', (req, res, next) => likeController(req, res, next)); -// router.get('/powered-by', (_, res) => res.render('articles/powered-by')); // not working -// router1.get('/powered-by', (_, res) => res.render('powered-by')); // not working - -// router1.all('*', (_,res) => res.send('

404!
Page not found...

')); - -// router1.use((err, req, res, next) => { // express err handler, global err format for printing user defined errs -// const { statusCode=500, message, stack } = err; -// const error = { statusCode, message, stack }; -// // console.log('1',errFormat); -// console.error({ error }); -// }); - module.exports = router; diff --git a/backend/routes/index.js b/backend/routes/index.js index ffb6cef..93f1a0d 100644 --- a/backend/routes/index.js +++ b/backend/routes/index.js @@ -15,19 +15,14 @@ router.get('/powered-by', (_, res) => res.render('powered-by')); router.all('*', (req, res) => { res.status(404).send('

404!
Page not found...

'); console.log(`404..\nRequested url: [${req.method}] ${req.headers.host + req.originalUrl} doesn't exist!`); - // const err = new Error('Invalid URL'); - // err.statusCode = 404; - // next(err); //,statusCode=404); - // console.log('\nnext',next); }); -router.use((err, req, res, next) => { // express err handler, global err format for printing user defined errs +// express err handler, global err format for printing both system generated & user defined errs +router.use((err, req, res, next) => { const { statusCode=500, message, stack } = err; const error = { statusCode, message, stack }; res.status(statusCode).json(error); console.error('error:',error); - // console.log('s',s); - // res.send('abcd'); }); module.exports = router; diff --git a/frontend/assets/graphics/backgrounds/giphy.gif b/frontend/assets/graphics/backgrounds/giphy.gif deleted file mode 100644 index 8f0b8a6..0000000 Binary files a/frontend/assets/graphics/backgrounds/giphy.gif and /dev/null differ diff --git a/frontend/assets/graphics/logos/Bitmap in Untitled-1.cpt b/frontend/assets/graphics/logos/Bitmap in Untitled-1.cpt deleted file mode 100644 index c2f44cc..0000000 Binary files a/frontend/assets/graphics/logos/Bitmap in Untitled-1.cpt and /dev/null differ diff --git a/frontend/assets/graphics/logos/x.png b/frontend/assets/graphics/logos/x.png deleted file mode 100644 index f58d923..0000000 Binary files a/frontend/assets/graphics/logos/x.png and /dev/null differ diff --git a/frontend/assets/scripts/1form.js b/frontend/assets/scripts/1form.js deleted file mode 100644 index 80c03bf..0000000 --- a/frontend/assets/scripts/1form.js +++ /dev/null @@ -1,14 +0,0 @@ -async function callApi(data, id, pg) { - try { - await fetch(`/articles/${id || 0}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ data, pg }) - }); - } catch (err) { - console.log('err ->',err); - } -} -const mouseClickIndex = (activeLikeBtns, id) => callApi(activeLikeBtns,id,'edit/new'); -const mouseMoveShow = callApi; - diff --git a/frontend/assets/scripts/form.js b/frontend/assets/scripts/form.js index bd8b28a..9a0b8a6 100644 --- a/frontend/assets/scripts/form.js +++ b/frontend/assets/scripts/form.js @@ -9,33 +9,14 @@ async function callApi(data, id, pg) { console.log('err ->',err); } } -// const mouseClickIndex = (activeLikeBtns, id) => callApi(activeLikeBtns,id,'edit/new'); -const mouseClickCancel = (activeLikeBtns, id, srcPg) => - // srcPg ? callApi(activeLikeBtns,id) : callApi(activeLikeBtns,id,'edit/new'); - callApi(activeLikeBtns,id,srcPg ? undefined : 'edit/new'); -/*const mouseClickCancel = (activeLikeBtns, id, srcPg) => { - if(srcPg) callApi(activeLikeBtns,id); - else callApi(activeLikeBtns,id,'edit/new'); -};*/ -// const mouseMoveShow = callApi; -// const mouseClickShow = callApi; +const mouseClickCancel = (activeLikeBtns, id, srcPg) => callApi(activeLikeBtns,id,srcPg ? undefined : 'edit/new'); -/*function removeSpaces(desc, md) { - document.getElementById('description').defaultValue = desc || ''; - document.getElementById('markdown').defaultValue = md || ''; - // document.getElementById('description').defaultValue = ''; - // document.getElementById('markdown').defaultValue = ''; - // document.getElementById('description').defaultValue = desc; - // document.getElementById('markdown').defaultValue = md; -}*/ -// const chkSpclChars = /(?![\s-])\W|\n|\t|\r/g; // chk special chars but not spaces, -, _ -const chkSpclChars = /(?![\s\.-])\W/g; // it wont chk spaces, -, _, . const chkAlphabets = /[a-zA-Z]/g; // count no. of chars[a-zA-Z] in the string containing all type of chars +const chkSpclChars = /(?![\s\.-])\W/g; // it wont chk spaces, -, _, . function chkStringLength(string, minAlphabets, maxlen) { const no_of_alphabets = (string.match(chkAlphabets) || []).length; - // return no_of_alphabets < minlen || no_of_alphabets > maxlen; return no_of_alphabets < minAlphabets || string.length > maxlen; } @@ -60,21 +41,6 @@ function deactivateTextAreaErr(err,ele,string) { err.display = 'none'; ele.value = string; } -/*function x(a, b, c, e, f) { - if(c.id === 'name') { - if(a && (chkStringLength(a,e,f) || chkSpclChars.test(a))) return y(b); - else z(a,b,c); - } else if(c.id === 'title') { - if(!a || chkStringLength(a,e,f) || chkSpclChars.test(a)) return y(b); - else z(a,b,c); - } else if(c.id === 'description') { - if(!a || chkStringLength(a,e,f)) return y(b); - else z(a,b,c); - } else if(c.id === 'markdown') { - if(!a || chkStringLength(a,e,f)) return y(b); - else z(a,b,c); - } -}*/ function validation(activeLikeBtns, id) { const eleName = document.getElementById('name'); @@ -93,169 +59,27 @@ function validation(activeLikeBtns, id) { const mdString = eleMd.value.trim(); const mdErr = document.getElementById('md-err').style; - // console.log(titleErr.style,'s -', titleString,'d -',titleErr.style.display); - // console.log(name.trim(),name.trim().length); - // const name = eleName.value.trim(); - try { - if(nameString && (chkStringLength(nameString,3,20) || chkSpclChars.test(nameString))) // { - // alert('invalid or smaller name'); - // visible err msg - // document.getElementById('name-err').style.display = "inline"; - // document.getElementById('name-err').style.visibility = visible; - // nameErr.display = 'inline'; - // return false; + if(nameString && (chkStringLength(nameString,3,20) || chkSpclChars.test(nameString))) return activateErr(nameErr); - // if(!activateErr(nameErr)) return false; - // } else { - // document.getElementById('name-err').style.display = "none"; - // nameErr.display = 'none'; - // eleName.value = nameString.replace(/\s{2,}/g,' '); - // eleName.value = allowedSpclChars(nameString); - /*.replace(/\n|\t|\r/g,'') - .replace(/\s{2,}/g,' ') // it can cover \n{2,} | \t{2,} | \r{2,} - .replace(/\.{2,}/g,'.') - .replace(/-{2,}/g,'-') - .replace(/_{2,}/g,'_');*/ - deactivateTextBoxErr(nameErr,eleName,nameString); - // } - // x(nameString,nameErr,eleName,3,20); + deactivateTextBoxErr(nameErr,eleName,nameString); - if(!titleString || chkStringLength(titleString,5,25) || chkSpclChars.test(titleString)) // { - // alert('invalid or smaller title'); - // visible err msg - // console.log(title); - // document.getElementById('title-err').style.display = "inline"; - // document.getElementById('title-err').style.visibility = visible; - // titleErr.style.display = 'inline'; - // titleErr.display = 'inline'; - // return false; + if(!titleString || chkStringLength(titleString,5,25) || chkSpclChars.test(titleString)) return activateErr(titleErr); - // if(!activateErr(titleErr)) return false; - // } else { - // document.getElementById('title-err').style.display = "none"; - // titleErr.style.display = 'none'; - // titleErr.display = 'none'; - // eleTitle.value = titleString.replace(/\s{2,}/g,' '); - /*eleTitle.value = titleString - .replace(/\n|\t|\r/g,'') - .replace(/\s{2,}/g,' ') // it can cover \n{2,} | \t{2,} | \r{2,} - .replace(/\.{2,}/g,'.') - .replace(/-{2,}/g,'-') - .replace(/_{2,}/g,'_');*/ - // eleName.value = allowedSpclChars(nameString); - deactivateTextBoxErr(titleErr,eleTitle,titleString); - // } - // x(titleString,titleErr,eleTitle,5,25); + deactivateTextBoxErr(titleErr,eleTitle,titleString); - // if(!descString || chkStringLength(descString,50,250)) { - if(!descString || chkStringLength(descString,500,4000)) // { - // alert('invalid or smaller description'); - // visible err msg - // document.getElementById('desc-err').style.display = "inline"; - // document.getElementById('desc-err').style.visibility = visible; - // descErr.display = 'inline'; - // return false; + if(!descString || chkStringLength(descString,500,4000)) return activateErr(descErr); - // if(!activateErr(descErr)) return false; - // } else { - // descErr.display = 'none'; - // eleDesc.value = descString; - deactivateTextAreaErr(descErr,eleDesc,descString); - // } - // x(descString,descErr,eleDesc,500,4000); + deactivateTextAreaErr(descErr,eleDesc,descString); - // if(!mdString || chkStringLength(mdString,20,120)) { - if(!mdString || chkStringLength(mdString,20,2000)) // { - // alert('invalid or smaller markdown'); - // visible err msg - // document.getElementById('md-err').style.display = "inline"; - // document.getElementById('md-err').style.visibility = visible; - // mdErr.display = 'inline'; - // return false; + if(!mdString || chkStringLength(mdString,20,2000)) return activateErr(mdErr); - // if(!activateErr(mdErr)) return false; - // } else { - // mdErr.display = 'none'; - // eleMd.value = mdString; - deactivateTextAreaErr(mdErr,eleMd,mdString); - // } - // x(mdString,mdErr,eleMd,20,2000); - + deactivateTextAreaErr(mdErr,eleMd,mdString); } catch (err) { console.log('err ->',err); - return false; // prevent api calling & form submission + return false; // prevent api calling & form submission } - // return false; - - callApi(activeLikeBtns,id); - // return true; // its automatic } -/*function validation() { - if(!0) return false; -}*/ - -/*const form = document.getElementById('form'); -form.addEventListener('submit', event => { - event.preventDefault(); - const eleName = document.getElementById('name'); - const name = eleName.value.trim(); - const eleTitle = document.getElementById('title'); - const title = eleTitle.value.trim(); - const eleDesc = document.getElementById('description'); - const desc = eleDesc.value.trim(); - const eleMd = document.getElementById('markdown'); - const md = eleMd.value.trim(); - - // console.log(name,name.length); - // console.log(name.trim(),name.trim().length); - // const name = eleName.value.trim(); - if(name && (chkStringLength(name,3,20) || chkSpclChars.test(name))) { - alert('invalid or smaller name'); - // visible err msg - document.getElementById('name-err').style.display = "inline"; - // document.getElementById('name-err').style.visibility = visible; - // event.preventDefault(); - // return false; - } else eleName.value = name.replace(/\s{2,}/g,' '); - - if(!title || chkStringLength(title,5,25) || chkSpclChars.test(title)) { - alert('invalid or smaller title'); - // visible err msg - // console.log(title); - document.getElementById('title-err').style.display = "inline"; - // document.getElementById('title-err').style.visibility = visible; - // event.preventDefault(); - // return false; - } else eleTitle.value = title.replace(/\s{2,}/g,' '); - - if(!desc || chkStringLength(desc,50,250)) { - alert('invalid or smaller description'); - // visible err msg - document.getElementById('desc-err').style.display = "inline"; - // document.getElementById('desc-err').style.visibility = visible; - // event.preventDefault(); - // return false; - } else eleDesc.value = desc; - - if(!md || chkStringLength(md,20,120)) { - alert('invalid or smaller markdown'); - // visible err msg - document.getElementById('md-err').style.display = "inline"; - // document.getElementById('md-err').style.visibility = visible; - // event.preventDefault(); - // return false; - } else eleMd.value = md; - - - - // return false; - - - // callApi(activeLikeBtns,id); - // return true; // its automatic -});*/ - diff --git a/frontend/assets/scripts/index.js b/frontend/assets/scripts/index.js index 0b27267..e30a96f 100644 --- a/frontend/assets/scripts/index.js +++ b/frontend/assets/scripts/index.js @@ -50,24 +50,11 @@ async function mouseClickLike(btn, activeLikeBtns) { } const response = await callApi(`/articles/like/${id}`,'PATCH',likeBtnState); // stores no. of likes in db - // console.log(response.status,typeof response.status); - // console.log(response.body,typeof response.body); - // console.log(response.json()); - // console.log(response.body,typeof response.body); - // const { likes } = await response.json(); - // const { likes } = 1; // await response.json(); - // if(likes) document.getElementById(id + id).innerText = likes; - // else { - // alert('something went wrong!'); - - // } if(response.status !== 200) return alert('something went wrong!'); - // else const { likes } = await response.json(); // invalid declaration else { const { likes } = await response.json(); document.getElementById(id + id).innerText = likes; } - // console.log('after alert'); await callApi(`/articles/${id}`,'POST',activeLikeBtnsCache); // stores active like btns in memory(preserved until home pg is not refresh) diff --git a/frontend/assets/scripts/show.js b/frontend/assets/scripts/show.js index ef3f010..1cca3f3 100644 --- a/frontend/assets/scripts/show.js +++ b/frontend/assets/scripts/show.js @@ -15,7 +15,6 @@ const mouseOverLike = () => common('heart-empty','heart-fill2'); const mouseOutLike = () => common('heart-fill2','heart-empty'); -// const callApi = (api, method, data, pg) => fetch(api, { const callApi = (api, method, data) => fetch(api, { method, headers: { 'Content-Type': 'application/json' }, @@ -28,7 +27,6 @@ let likeBtn; async function mouseClickLike(activeLikeBtns, id) { event.preventDefault(); // prevent pg from default reloading, default submitting, or default redirecting - // likeBtn = 'clicked'; try { let likeBtnState; activeLikeBtnsCache = activeLikeBtns ? activeLikeBtns.split(',') : activeLikeBtnsCache; @@ -63,14 +61,12 @@ async function mouseClickLike(activeLikeBtns, id) { } -async function apiConfig(activeLikeBtns, id) { // , pg) { +async function apiConfig(activeLikeBtns, id) { try { - await callApi(`/articles/${id}`,'POST',likeBtn ? activeLikeBtnsCache : activeLikeBtns); // ,pg); // stores active like btns in memory to transfer to another pg + await callApi(`/articles/${id}`,'POST',likeBtn ? activeLikeBtnsCache : activeLikeBtns); // stores active like btns in memory to transfer to another pg } catch (err) { console.log('err ->',err); } } -// const mouseClickIndex = (activeLikeBtns, id) => apiConfig(activeLikeBtns,id,'show'); -// const mouseClickEdit = (activeLikeBtns, id) => apiConfig(activeLikeBtns,id,'show'); const [mouseClickIndex, mouseClickEdit] = [apiConfig,apiConfig]; diff --git a/frontend/assets/stylesheets/1form.css b/frontend/assets/stylesheets/1form.css deleted file mode 100644 index 0022c99..0000000 --- a/frontend/assets/stylesheets/1form.css +++ /dev/null @@ -1,43 +0,0 @@ -body { - background-image: url("/graphics/backgrounds/b.jpg"); - backdrop-filter: blur(5px); - min-height: 100vh; /* set body height minimum 100% to fix footer at the bottom if content is less also */ -} - -h1 { color: white; } - -#description { height: 180px; } - -#markdown { height: 135px; } - -#description, #markdown { - overflow: scroll; - overflow-x: hidden; -} - -#description::-webkit-scrollbar, #markdown::-webkit-scrollbar { - width: 8.5px; -} - -#description::-webkit-scrollbar-corner, #markdown::-webkit-scrollbar-corner { - background: transparent; -} - -.form-group label { - color: black; - text-shadow: - 0 0 5px silver; - font-size: 13px; - font-weight: 600; -} - -.form-control, .form-control:focus { - background: transparent; - border: 2px solid rgb(46, 140, 177); - color: white; -} - -.form-control:focus { - box-shadow: inset 0px 0px 5px 0px rgba(0, 0, 0, 0.432); -} - diff --git a/frontend/assets/stylesheets/1powered-by.css b/frontend/assets/stylesheets/1powered-by.css deleted file mode 100644 index ae3319a..0000000 --- a/frontend/assets/stylesheets/1powered-by.css +++ /dev/null @@ -1,120 +0,0 @@ -body { - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-family: "proxima-nova-soft", sans-serif; - -webkit-user-select: none; - overflow: hidden; - } - body .vertical-centered-box { - position: absolute; - width: 100%; - height: 100%; - text-align: center; - } - body .vertical-centered-box:after { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; - margin-right: -0.25em; - } - body .vertical-centered-box .content { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - display: inline-block; - vertical-align: middle; - text-align: left; - font-size: 0; - } - * { - -webkit-transition: all 0.3s; - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - transition: all 0.3s; - } - body { - background: #2c2d44; - } - .loader-circle { - position: absolute; - left: 50%; - top: 50%; - width: 120px; - height: 120px; - border-radius: 50%; - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); - margin-left: -60px; - margin-top: -60px; - } - .loader-line-mask { - position: absolute; - left: 50%; - top: 50%; - width: 60px; - height: 120px; - margin-left: -60px; - margin-top: -60px; - overflow: hidden; - -webkit-transform-origin: 60px 60px; - -moz-transform-origin: 60px 60px; - -ms-transform-origin: 60px 60px; - -o-transform-origin: 60px 60px; - transform-origin: 60px 60px; - -webkit-mask-image: -webkit-linear-gradient(top, #000000, rgba(0, 0, 0, 0)); - -webkit-animation: rotate 1.2s infinite linear; - -moz-animation: rotate 1.2s infinite linear; - -o-animation: rotate 1.2s infinite linear; - animation: rotate 1.2s infinite linear; - } - .loader-line-mask .loader-line { - width: 120px; - height: 120px; - border-radius: 50%; - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5); - } - #particles-background, - #particles-foreground { - left: -51%; - top: -51%; - width: 202%; - height: 202%; - -webkit-transform: scale3d(0.5, 0.5, 1); - -moz-transform: scale3d(0.5, 0.5, 1); - -ms-transform: scale3d(0.5, 0.5, 1); - -o-transform: scale3d(0.5, 0.5, 1); - transform: scale3d(0.5, 0.5, 1); - } - #particles-background { - background: #2c2d44; - background-image: -moz-linear-gradient(45deg, #3f3251 2%, #002025 100%); - background-image: -webkit-linear-gradient(45deg, #3f3251 2%, #002025 100%); - background-image: linear-gradient(45deg, #3f3251 2%, #002025 100%); - } - lesshat-selector { - -lh-property: 0; } - @-webkit-keyframes rotate{ 0% { -webkit-transform: rotate(0deg);} 100% { -webkit-transform: rotate(360deg);}} - @-moz-keyframes rotate{ 0% { -moz-transform: rotate(0deg);} 100% { -moz-transform: rotate(360deg);}} - @-o-keyframes rotate{ 0% { -o-transform: rotate(0deg);} 100% { -o-transform: rotate(360deg);}} - @keyframes rotate{ 0% {-webkit-transform: rotate(0deg);-moz-transform: rotate(0deg);-ms-transform: rotate(0deg);transform: rotate(0deg);} 100% {-webkit-transform: rotate(360deg);-moz-transform: rotate(360deg);-ms-transform: rotate(360deg);transform: rotate(360deg);}} - [not-existing] { - zoom: 1; - } - lesshat-selector { - -lh-property: 0; } - @-webkit-keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - @-moz-keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - @-o-keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - @keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - [not-existing] { - zoom: 1; - } - lesshat-selector { - -lh-property: 0; } - @-webkit-keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - @-moz-keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - @-o-keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - @keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - [not-existing] { - zoom: 1; - } \ No newline at end of file diff --git a/frontend/assets/stylesheets/1powered-by.less b/frontend/assets/stylesheets/1powered-by.less deleted file mode 100644 index 08e72eb..0000000 --- a/frontend/assets/stylesheets/1powered-by.less +++ /dev/null @@ -1,111 +0,0 @@ -@import "lesshat"; - -// START: TEMPLATE -@blue: #26bbf0; -@green: #c2d5a0; -@red: #cf6a6d; -@yellow: #ffbc0d; - -@black: #343536; -@black-2: #424950; -@grey: #89949b; -@grey-2: #9aa8b1; -@light-grey: #c4c9cd ; -@light-grey-2: #dbdfe1; -@white: #f3f4f5; - -body { - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-family: "proxima-nova-soft", sans-serif; - -webkit-user-select: none; - overflow: hidden; - - .vertical-centered-box { - position: absolute; - .size(100%); - text-align: center; - &:after { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; - margin-right: -0.25em; - } - .content { - .box-sizing(border-box); - display: inline-block; - vertical-align: middle; - text-align: left; - font-size: 0; - } - } -} - -* { - .transition(all .3s); -} -// END: TEMPLATE - - -body { - background: mix(#3f3251, #002025, 70%); -} - -#prism-logo { - path { - // fill: #20293b; - // stroke: rgba(255,255,255,1); - // stroke-width: 1px; - } -} - -.loader-circle { - position: absolute; - left: 50%; - top: 50%; - .size(120); - border-radius: 50%; - box-shadow: inset 0 0 0 1px rgba(255,255,255,.1); - margin-left: -60px; - margin-top: -60px; - // .animation(fade 1.2s infinite ease-in-out); -} - -.loader-line-mask { - position: absolute; - left: 50%; - top: 50%; - .size(60,120); - margin-left: -60px; - margin-top: -60px; - overflow: hidden; - .transform-origin(60px 60px); - -webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,1), rgba(0,0,0,0)); - .animation(rotate 1.2s infinite linear); - .loader-line { - .size(120); - border-radius: 50%; - box-shadow: inset 0 0 0 1px rgba(255,255,255,.5); - } -} - -#particles-background, #particles-foreground { - left: -51%; - top: -51%; - .size(202%); - .scale3d(.5, .5, 1); -} - -#particles-background { - background: mix(#3f3251, #002025, 70%); - background-image: -moz-linear-gradient(45deg, #3f3251 2%, #002025 100%); - background-image: -webkit-linear-gradient(45deg, #3f3251 2%, #002025 100%); - background-image: linear-gradient(45deg, #3f3251 2%, #002025 100%); -} - -.keyframes(~'rotate, 0% { transform: rotate(0deg);} 100% { transform: rotate(360deg);}'); - -.keyframes(~'fade, 0% { opacity: 1;} 50% { opacity: 0.25;}'); - -.keyframes(~'fade-in, 0% { opacity: 0;} 100% { opacity: 1;}'); \ No newline at end of file diff --git a/frontend/assets/stylesheets/2form.css b/frontend/assets/stylesheets/2form.css deleted file mode 100644 index e244650..0000000 --- a/frontend/assets/stylesheets/2form.css +++ /dev/null @@ -1,120 +0,0 @@ -body { - background-image: url("/graphics/backgrounds/b.jpg"); - backdrop-filter: blur(5px); - min-height: 100vh; /* set body height minimum 100% to fix footer at the bottom if content is less also */ -} - -h1 { - color: white; - text-align: center; -} - -#description { height: 180px; } - -#markdown { height: 135px; } - -#description, #markdown { - overflow: scroll; - overflow-x: hidden; -} - -#description::-webkit-scrollbar, #markdown::-webkit-scrollbar { - width: 8.5px; -} - -#description::-webkit-scrollbar-corner, #markdown::-webkit-scrollbar-corner { - background: transparent; -} - -.form-group label { - color: black; - /* text-shadow: 0 0 5px silver; */ - font-size: 13px; - font-weight: 600; - /* color: linear-gradient(to right, #f12711, #f5af19); */ - border-radius: 7px; - padding: 4px; - padding-left: 6px; - padding-right: 6px; - background: linear-gradient(to right, #f12711, #f5af19); - filter: contrast(80%); -} - -.form-control, .form-control:focus { - background: transparent; - /* border: 2px solid rgb(46, 140, 177); */ - border: 2px solid #343a40; - color: white; -} - -.form-control:focus { - /* box-shadow: inset 0px 0px 5px 0px rgba(0, 0, 0, 0.432); */ - box-shadow: inset 0px 0px 6px 0px rgba(0, 0, 0, 0.432); -} - -/*#name-err, #title-err, #desc-err, #md-err { // ✔ - font-size: 12px; - color: rgb(255, 255, 255); - border-radius: 20px; - box-shadow: inset 0px 0px 20px 0px rgb(137 11 26); - font-style: italic; - padding-right: 15px; - padding-left: 13px; - padding-bottom: 2px; -}*/ - -.form-group { position: relative; } -#name-err, #title-err, #desc-err, #md-err { - display: none; - /* visibility: hidden; */ - /* float: right; */ - /* text-align: right; */ - font-size: 10px; - color: rgb(255, 255, 255); - /* color: brown; */ - /* border: 1px solid red; */ - border-radius: 20px; - /* padding: 10px; */ - /* background-color: rgb(250, 250, 250); */ - /* box-shadow: inset 0px 0px 20px 0px rgba(80, 9, 9, 0.6); */ - /* box-shadow: inset 0px 0px 20px 0px rgba(218, 18, 18, 0.6); */ - /* box-shadow: inset 0px 0px 20px 0px rgba(218, 18, 18, 0.6); */ - /* box-shadow: inset 0px 0px 20px 0px rgb(137 11 26); */ - font-style: italic; - padding-right: 12px; - padding-left: 9px; - padding-bottom: 2px; - letter-spacing: 2px; - background: brown; - /* text-shadow: rgb(0 0 0 / 24%) 5px 14px 25px; */ - /* margin-top: 16px; */ - margin-top: 1.45%; - /* left: 78%; */ - /* right: 15%; */ - right: 2%; - position: absolute; -} - -/* #form { border: 1px solid;} */ -#form { position: relative; } -/* .container { position: relative; } */ -/* .btn { position: absolute; } */ -.btn-primary { - /* right: 1px; */ - /* right: 0%; */ - float: right; -} -.btn-secondary { - /* right: 68px; */ - right: 6%; - /* float: right; */ - position: absolute; -} - -/* .btn-primary:active #name-err { */ -/* .btn-primary:focus #name-err { */ - /* font-size: 15px; */ - /* padding-top: 2px; - -} */ - diff --git a/frontend/assets/stylesheets/2powered-by.css b/frontend/assets/stylesheets/2powered-by.css deleted file mode 100644 index e43f51b..0000000 --- a/frontend/assets/stylesheets/2powered-by.css +++ /dev/null @@ -1,228 +0,0 @@ -body { - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-family: "proxima-nova-soft", sans-serif; - -webkit-user-select: none; - overflow: hidden; - /* line-height: 50vh; */ - } - body .vertical-centered-box { - position: absolute; - width: 100%; - /* height: 100%; */ - height: 60%; - text-align: center; - /* z-index: -1; */ - } - body .vertical-centered-box:after { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; - margin-right: -0.25em; - /* z-index: -1; */ - } - body .vertical-centered-box .content { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - display: inline-block; - vertical-align: middle; - text-align: left; - font-size: 0; - /* z-index: -1; */ - } - * { - -webkit-transition: all 0.3s; - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - transition: all 0.3s; - } - body { - background: #2c2d44; - /* z-index: -1; */ - } - .loader-circle { - position: absolute; - left: 50%; - top: 50%; - width: 120px; - height: 120px; - border-radius: 50%; - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); - margin-left: -60px; - margin-top: -60px; - } - .loader-line-mask { - position: absolute; - left: 50%; - top: 50%; - width: 60px; - height: 120px; - margin-left: -60px; - margin-top: -60px; - overflow: hidden; - -webkit-transform-origin: 60px 60px; - -moz-transform-origin: 60px 60px; - -ms-transform-origin: 60px 60px; - -o-transform-origin: 60px 60px; - transform-origin: 60px 60px; - -webkit-mask-image: -webkit-linear-gradient(top, #000000, rgba(0, 0, 0, 0)); - -webkit-animation: rotate 1.2s infinite linear; - -moz-animation: rotate 1.2s infinite linear; - -o-animation: rotate 1.2s infinite linear; - animation: rotate 1.2s infinite linear; - } - .loader-line-mask .loader-line { - width: 120px; - height: 120px; - border-radius: 50%; - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5); - } - #particles-background, - #particles-foreground { - left: -51%; - top: -51%; - width: 202%; - height: 202%; - -webkit-transform: scale3d(0.5, 0.5, 1); - -moz-transform: scale3d(0.5, 0.5, 1); - -ms-transform: scale3d(0.5, 0.5, 1); - -o-transform: scale3d(0.5, 0.5, 1); - transform: scale3d(0.5, 0.5, 1); - /* z-index: -1; */ - } - #particles-background { - background: #2c2d44; - background-image: -moz-linear-gradient(45deg, #3f3251 2%, #002025 100%); - background-image: -webkit-linear-gradient(45deg, #3f3251 2%, #002025 100%); - background-image: linear-gradient(45deg, #3f3251 2%, #002025 100%); - /* z-index: -1; */ - } - lesshat-selector { - -lh-property: 0; } - @-webkit-keyframes rotate{ 0% { -webkit-transform: rotate(0deg);} 100% { -webkit-transform: rotate(360deg);}} - @-moz-keyframes rotate{ 0% { -moz-transform: rotate(0deg);} 100% { -moz-transform: rotate(360deg);}} - @-o-keyframes rotate{ 0% { -o-transform: rotate(0deg);} 100% { -o-transform: rotate(360deg);}} - @keyframes rotate{ 0% {-webkit-transform: rotate(0deg);-moz-transform: rotate(0deg);-ms-transform: rotate(0deg);transform: rotate(0deg);} 100% {-webkit-transform: rotate(360deg);-moz-transform: rotate(360deg);-ms-transform: rotate(360deg);transform: rotate(360deg);}} - [not-existing] { - zoom: 1; - } - lesshat-selector { - -lh-property: 0; } - @-webkit-keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - @-moz-keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - @-o-keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - @keyframes fade{ 0% { opacity: 1;} 50% { opacity: 0.25;}} - [not-existing] { - zoom: 1; - } - lesshat-selector { - -lh-property: 0; } - @-webkit-keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - @-moz-keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - @-o-keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - @keyframes fade-in{ 0% { opacity: 0;} 100% { opacity: 1;}} - [not-existing] { - zoom: 1; - } - -/* .msg { */ - /* text-align: center; */ - /* animation */ - /* animation: type 5s steps(23) infinite; - overflow: hidden; - white-space: nowrap; */ - /* float: center; */ -/* } */ -p { - color: white; - /* line-height: 115vh; */ - line-height: 50vh; - /* z-index: -1; */ - /* left: 50%; */ - font-weight: bold; - /* font-family: cascadia code; */ - font-family: '1942 report'; - /* font-family: 'Trixie-Text'; */ - /* font-family: 'recursive mono linear light lta'; */ - /* font-family: recursive mono; */ - font-size: 45px; - /* vertical-align: bottom; */ - /* margin-top: 60vh; */ - /* height: 100%; */ - text-transform: uppercase; - /* text-align: center; */ - /* float: center; */ - /* display: none; */ - visibility: hidden; - - /* animation */ - /* animation: typeText 4s steps(23) infinite; - overflow: hidden; - white-space: nowrap; */ - /* animation: typeText 4.5s steps(23), blinkText 0.9s 5s linear infinite; - overflow: hidden; - white-space: nowrap; */ - animation: - typeText 4s 0.15s steps(23), - blinkText 0.9s 4.15s linear infinite; /* name duration delay timing-function iteration-count */ - overflow: hidden; - white-space: nowrap; - /* animation-delay: -1s; */ -} -@keyframes typeText { - /* visibility: visible; */ - 0% { - width: 0ch; - /* display: inline; */ - visibility: visible; - } - /* 75% { width: 23ch; } */ - 100% { - width: 23ch; - /* display: inline; */ - /* visibility: visible; */ - } - /* 100% { - left: 100%; - margin: 0 -35px 0 35px; - } */ - /* 50%, 100% { - width: 0; - } */ -} -@keyframes blinkText { - 50% { - opacity: 0; - /* display: inline; */ - visibility: visible; - } -} -/* p::after { - content: ''; -} */ -/* svg { */ - /* line-height: 100vh; */ - /* line-height: 100%; */ - /* margin-top: 28.5vh; */ - /* position: absolute; */ - /* bottom: 50%; */ - /* width: 120px; */ - /* height: 120px; */ - /* top: 50% */ -/* } */ - -img { - height: 40px; - width: 40px; - /* filter: invert(1) grayscale(1); */ - /* filter: invert(1) grayscale(1) sepia(1); */ - /* filter: grayscale(1) saturate(1) sepia(1) contrast(0.3); */ - /* filter:grayscale(1); */ - /* filter:saturate(8); */ - /* filter:sepia(100%); */ - margin-top: 27.6vh; - /* line-height: 200vh; */ -} - diff --git a/frontend/assets/stylesheets/form.css b/frontend/assets/stylesheets/form.css index d6d45e2..516bd65 100644 --- a/frontend/assets/stylesheets/form.css +++ b/frontend/assets/stylesheets/form.css @@ -28,10 +28,8 @@ h1 { .form-group label { color: black; - /* text-shadow: 0 0 5px silver; */ font-size: 13px; font-weight: 600; - /* color: linear-gradient(to right, #f12711, #f5af19); */ border-radius: 7px; padding: 4px; padding-left: 6px; @@ -42,87 +40,32 @@ h1 { .form-control, .form-control:focus { background: transparent; - /* border: 2px solid rgb(46, 140, 177); */ border: 2px solid #343a40; color: white; } .form-control:focus { - /* box-shadow: inset 0px 0px 5px 0px rgba(0, 0, 0, 0.432); */ box-shadow: inset 0px 0px 6px 0px rgba(0, 0, 0, 0.432); } -/*#name-err, #title-err, #desc-err, #md-err { // ✔ - font-size: 12px; - color: rgb(255, 255, 255); - border-radius: 20px; - box-shadow: inset 0px 0px 20px 0px rgb(137 11 26); - font-style: italic; - padding-right: 15px; - padding-left: 13px; - padding-bottom: 2px; -}*/ - .form-group { position: relative; } #name-err, #title-err, #desc-err, #md-err { display: none; - /* visibility: hidden; */ - /* float: right; */ - /* text-align: right; */ font-size: 10px; color: rgb(255, 255, 255); - /* color: brown; */ - /* border: 1px solid red; */ border-radius: 20px; - /* padding: 10px; */ - /* background-color: rgb(250, 250, 250); */ - /* box-shadow: inset 0px 0px 20px 0px rgba(80, 9, 9, 0.6); */ - /* box-shadow: inset 0px 0px 20px 0px rgba(218, 18, 18, 0.6); */ - /* box-shadow: inset 0px 0px 20px 0px rgba(218, 18, 18, 0.6); */ - /* box-shadow: inset 0px 0px 20px 0px rgb(137 11 26); */ font-style: italic; padding-right: 12px; padding-left: 9px; padding-bottom: 2px; letter-spacing: 2px; background: brown; - /* text-shadow: rgb(0 0 0 / 24%) 5px 14px 25px; */ - /* margin-top: 16px; */ margin-top: 1.45%; - /* left: 78%; */ - /* right: 15%; */ right: 2%; position: absolute; } -/* #form { - border: 1px solid; */ - /* min-height: auto; */ -/* } */ -/* #form { position: relative; } */ -/* .container { position: relative; } */ -/* .btn { position: absolute; } */ -/* .btn-primary { */ - /* right: 1px; */ - /* right: 0%; */ - /* float: right; -} */ -/* .btn-secondary { */ - /* right: 68px; */ - /* right: 6%; */ - /* float: right; */ - /* position: absolute; -} */ - -/* .btn-primary:active #name-err { */ -/* .btn-primary:focus #name-err { */ - /* font-size: 15px; */ - /* padding-top: 2px; - -} */ - .form-btns { - /* border: 1px solid; */ width: fit-content; float: right; } diff --git a/frontend/assets/stylesheets/index.css b/frontend/assets/stylesheets/index.css index 97a3188..fead31e 100644 --- a/frontend/assets/stylesheets/index.css +++ b/frontend/assets/stylesheets/index.css @@ -21,7 +21,6 @@ body { box-shadow: inset 0px 0px 5px 0px rgba(0, 0, 0, 0.6); } -/* .new:active, .new:visited { color: white; } */ .new:active { color: white; } .card.mt-4 { diff --git a/frontend/assets/stylesheets/powered-by.css b/frontend/assets/stylesheets/powered-by.css index 5f1ed99..675fe58 100644 --- a/frontend/assets/stylesheets/powered-by.css +++ b/frontend/assets/stylesheets/powered-by.css @@ -4,15 +4,12 @@ body { font-family: "proxima-nova-soft", sans-serif; -webkit-user-select: none; overflow: hidden; - /* line-height: 50vh; */ } body .vertical-centered-box { position: absolute; width: 100%; - /* height: 100%; */ height: 60%; text-align: center; - /* z-index: -1; */ } body .vertical-centered-box:after { content: ''; @@ -20,7 +17,6 @@ body { height: 100%; vertical-align: middle; margin-right: -0.25em; - /* z-index: -1; */ } body .vertical-centered-box .content { -webkit-box-sizing: border-box; @@ -30,7 +26,6 @@ body { vertical-align: middle; text-align: left; font-size: 0; - /* z-index: -1; */ } * { -webkit-transition: all 0.3s; @@ -40,7 +35,6 @@ body { } body { background: #2c2d44; - /* z-index: -1; */ } .loader-circle { position: absolute; @@ -90,14 +84,12 @@ body { -ms-transform: scale3d(0.5, 0.5, 1); -o-transform: scale3d(0.5, 0.5, 1); transform: scale3d(0.5, 0.5, 1); - /* z-index: -1; */ } #particles-background { background: #2c2d44; background-image: -moz-linear-gradient(45deg, #3f3251 2%, #002025 100%); background-image: -webkit-linear-gradient(45deg, #3f3251 2%, #002025 100%); background-image: linear-gradient(45deg, #3f3251 2%, #002025 100%); - /* z-index: -1; */ } lesshat-selector { -lh-property: 0; } @@ -127,110 +119,44 @@ body { zoom: 1; } -/* .msg { */ - /* text-align: center; */ - /* animation */ - /* animation: type 5s steps(23) infinite; - overflow: hidden; - white-space: nowrap; */ - /* float: center; */ -/* } */ + @font-face { font-family: hiddenMsgFont; src: url('/fonts/1942 REPORT.TTF'); - /* font-weight: 900; */ } p { color: white; - /* line-height: 115vh; */ line-height: 50vh; - /* z-index: -1; */ - /* left: 50%; */ font-weight: bold; - /* font-family: cascadia code; */ - /* font-family: '1942 report'; */ - /* font-family: 'Trixie-Text'; */ - /* font-family: 'recursive mono linear light lta'; */ - /* font-family: recursive mono; */ font-family: hiddenMsgFont; font-size: 45px; - /* vertical-align: bottom; */ - /* margin-top: 60vh; */ - /* height: 100%; */ text-transform: uppercase; - /* text-align: center; */ - /* float: center; */ - /* display: none; */ letter-spacing: 1px; - /* word-wrap: break-word; */ visibility: hidden; - /* animation */ - /* animation: typeText 4s steps(23) infinite; - overflow: hidden; - white-space: nowrap; */ - /* animation: typeText 4.5s steps(23), blinkText 0.9s 5s linear infinite; - overflow: hidden; - white-space: nowrap; */ animation: typeText 4s 0.15s steps(23), blinkText 0.9s 4.15s linear infinite; /* name duration delay timing-function iteration-count */ overflow: hidden; white-space: nowrap; - /* animation-delay: -1s; */ } @keyframes typeText { - /* visibility: visible; */ 0% { width: 0ch; - /* display: inline; */ visibility: visible; } - /* 75% { width: 23ch; } */ - 100% { - width: 23ch; - /* display: inline; */ - /* visibility: visible; */ - } - /* 100% { - left: 100%; - margin: 0 -35px 0 35px; - } */ - /* 50%, 100% { - width: 0; - } */ + 100% { width: 23ch; } } @keyframes blinkText { 50% { opacity: 0; - /* display: inline; */ visibility: visible; } } -/* p::after { - content: ''; -} */ -/* svg { */ - /* line-height: 100vh; */ - /* line-height: 100%; */ - /* margin-top: 28.5vh; */ - /* position: absolute; */ - /* bottom: 50%; */ - /* width: 120px; */ - /* height: 120px; */ - /* top: 50% */ -/* } */ img { height: 40px; width: 40px; - /* filter: invert(1) grayscale(1); */ - /* filter: invert(1) grayscale(1) sepia(1); */ - /* filter: grayscale(1) saturate(1) sepia(1) contrast(0.3); */ - /* filter:grayscale(1); */ - /* filter:saturate(8); */ - /* filter:sepia(100%); */ margin-top: 27.6vh; - /* line-height: 200vh; */ } diff --git a/frontend/views/1_form_fields.ejs b/frontend/views/1_form_fields.ejs deleted file mode 100644 index d3a6019..0000000 --- a/frontend/views/1_form_fields.ejs +++ /dev/null @@ -1,27 +0,0 @@ -
- - -
- -
- - -
- -
- - -
- -
- - -
- -Cancel - - diff --git a/frontend/views/1new.ejs b/frontend/views/1new.ejs deleted file mode 100644 index 7ccbaf3..0000000 --- a/frontend/views/1new.ejs +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - New Blog - - -
-

New Article

-
- <%- include('_form_fields') %> -
-
-

- <%- include('_footer') %> - - - - diff --git a/frontend/views/1powered-by.ejs b/frontend/views/1powered-by.ejs deleted file mode 100644 index 64306a1..0000000 --- a/frontend/views/1powered-by.ejs +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - Powered by 🌌 - - - - - - - - diff --git a/frontend/views/2_form_fields.ejs b/frontend/views/2_form_fields.ejs deleted file mode 100644 index 41f54b9..0000000 --- a/frontend/views/2_form_fields.ejs +++ /dev/null @@ -1,33 +0,0 @@ -
- - *invalid or smaller username - - -
- -
- - *invalid or smaller title - - -
- -
- - *invalid or smaller description - - -
- -
- - *invalid or smaller markdown - - -
- - -Cancel - - - diff --git a/frontend/views/2powered-by.ejs b/frontend/views/2powered-by.ejs deleted file mode 100644 index 726b1ed..0000000 --- a/frontend/views/2powered-by.ejs +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - Powered by 🌌 - - - - - - -
-
- -
-
-
-
-
-
- - - - -
-

Something is coming..!

-
- - - - - - diff --git a/frontend/views/_footer.ejs b/frontend/views/_footer.ejs index 40246e6..3a0a0c4 100644 --- a/frontend/views/_footer.ejs +++ b/frontend/views/_footer.ejs @@ -4,11 +4,9 @@
diff --git a/frontend/views/_form_fields.ejs b/frontend/views/_form_fields.ejs index 0693949..3a92475 100644 --- a/frontend/views/_form_fields.ejs +++ b/frontend/views/_form_fields.ejs @@ -1,34 +1,29 @@
*invalid or smaller username -
*invalid or smaller title -
*invalid or smaller description -
*invalid or smaller markdown -
- Cancel -
+ diff --git a/frontend/views/edit.ejs b/frontend/views/edit.ejs index 3fc4651..469b2a4 100644 --- a/frontend/views/edit.ejs +++ b/frontend/views/edit.ejs @@ -12,7 +12,6 @@ Edit Blog -

Edit Article

diff --git a/frontend/views/new.ejs b/frontend/views/new.ejs index 4cd493c..5ee635e 100644 --- a/frontend/views/new.ejs +++ b/frontend/views/new.ejs @@ -12,12 +12,10 @@ New Blog -

New Article

- <%- include('_form_fields') %>
diff --git a/frontend/views/powered-by.ejs b/frontend/views/powered-by.ejs index e4db30b..98afc68 100644 --- a/frontend/views/powered-by.ejs +++ b/frontend/views/powered-by.ejs @@ -6,18 +6,9 @@ - - Powered by 🌌 - - - -
@@ -28,19 +19,11 @@
- -

Something is coming..!

- - - - diff --git a/server.js b/server.js index 49a50ae..dfa5d7f 100644 --- a/server.js +++ b/server.js @@ -3,48 +3,27 @@ const mongoose = require('mongoose'); require('dotenv').config(); const favicon = require('serve-favicon'); -// const path = require('path'); const methodOverride = require('method-override'); -// const articleRoute = require('./backend/routes/articles'); const routes = require('./backend/routes'); -// const { readController } = require('./backend/controllers/articles'); const app = express(); app.use(express.json({ limit: "1mb" })); // parse json data coming from frontend app.use(express.urlencoded({ extended: "false" })); // parse data sent thru html form -// app.use(favicon(path.join(__dirname, 'backend', 'favicon.ico'))); // serve req: '/favicon.ico' & set favicon for all pgs app.use(favicon('backend/favicon.ico')); // serve req: '/favicon.ico' & set favicon for all pgs // frontend app.set('view engine','ejs'); -// app.set('views', path.join(__dirname, 'frontend/views')); // set default views directory app.set('views','frontend/views'); // set default views directory app.use(express.static('frontend/assets')); // for creating link for external style and script files to link in ejs files app.use(methodOverride('_method')); // for calling request methods other than get and post thru form -// app.get(/^\/(home)*$/, (_, res) => readController(res,null,'index')); - -// app.use('/articles',articleRoute); app.use('/',routes); -// app.all('*', (_,res) => res.send('

404!
Page not found...

')); - -// app.use((err, req, res, next) => { // express err handler, global err format for printing user defined errs -// const errFormat = { -// statusCode: err.statusCode || 500, -// message: err.message, -// stack: err.stack -// }; -// }); - -// const { HOST:host='localhost', PORT:port=5000 } = process.env; const { HOST:host='localhost', PORT:port=5000, DB_CON:dbUrl } = process.env; -// app.listen(port, () => console.log(`Connection is established at \nhttp://${host}:${port} OR \nhttps://devtrek.herokuapp.com\n`)); -// console.log(host,port,dbUrl); mongoose.connect( dbUrl, {