Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

.env

node_modules/
144 changes: 142 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
# Help Center API Assignment

## Instructions
This is the solution of below assessment. In which I am creating the a full-stack app which help the user to come and see their query solutions.


## <h1 id="help_center"> Index </h1>

- <a href="#assessment">Asssement Instructions</a>
- <a href="#demo">Demo</a>
- <a href="#stack">Tech Stack</a>
- <a href="#env">Environment Variables</a>
- <a href="#runLocally">Run Locally</a>
- <a href="#routersRef">Routers References</a>
- <a href="#features">Features</a>


## <h1 id="assessment"> Asssement Instructions</h1>

1. **Clone the Repository:**
```bash
Expand All @@ -23,5 +37,131 @@
5. **Submit Your Work:**
- Paste the GitHub repository link in the Google form you received after pushing your code.

---
<a href="#help_center">Go Home </a>

## <h2 id="demo" >Demo </h2>


<p text-align=left>
<img src="https://github.com/user-attachments/assets/fb92d2dd-ec39-4431-935a-37c84d9655fd" width="500" height="" alt="help_center_home"/>

https://github.com/user-attachments/assets/49208244-ffc7-432c-9d08-95857b9d9fc3

</p>



<a href="#help_center">Go Home </a>



## <h2 id="stack" >Tech Stack </h2>


**Server:** ReactJS, Chakra UI

**Server:** NodeJS, ExpressJS

**Database:** MongoDB

<a href="#help_center">Go Home </a>


## <h2 id="env">Environment Variables </h2>

To want more info go on `.env.example` file in both folders (frontend and backend).

Rename file `.env.example` -> `.env`and Write your own environment variables.

<a href="#help_center">Go Home </a>


## <h2 id="runLocally" >Run Locally </h2>

Clone the project

```bash
git clone https://github/Nik4Furi/fullstack-assignment
```

Go to the project directory

```bash
cd full-stack-assignment
```

#### Backend
```bash
cd backend
```

Install dependencies

```bash
yarn
```
If yarn is not in your system, can use *npm i* to install dependencies

OR

``` bash
npm i -g yarn

yarn -v
```

Start the server or use "npm run" command

```bash
yarn start (start at the only time)

yarn dev (Run or restart, whenever you save any file(js))
```


#### Frontend

```bash
cd frontend
```

Install dependencies

```bash
yarn
```
If yarn is not in your system, can use *npm i* to install dependencies

OR

``` bash
npm i -g yarn

yarn -v
```

Start the server or use "npm run" command

```bash

yarn dev
```

<a href="#help_center">Go Home </a>





## <h2 id="routersRef">Routers Reference </h2>

For more info see `backend.md` file

<a href="#help_center">Go Home </a>

## <h2 id="features">Features </h2>

Full-filling all requirements mentioned in `frontend.md` and *backend.md* 😄


<a href="#help_center">Go Home </a>
12 changes: 6 additions & 6 deletions backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,28 @@ The objective of this assignment is to create a RESTful API that allows users to

**Project Requirements:**

1. **Set up the project:**
1. **Set up the project:**
- Create a new Node.js project using Express.js.
- Set up a basic server with a single endpoint to check if the server is running (e.g., `GET /ping`).
- Set up a basic server with a single endpoint to check if the server is running (e.g., `GET /ping`).

2. **Create a Card Model:**
2. **Create a Card Model:**
- Design a model for a card. Each card should have the following fields (You can chooose any ORM and database):
- `id` (string): A unique identifier for the card.
- `title` (string): The title of the card (e.g., "Branches").
- `description` (string): A brief description of what the card represents (e.g., "Abstract Branches lets you manage, version, and document your designs in one place.").

3. **Build the API Endpoints:**
3. **Build the API Endpoints:**
- **Create a card:** Create an endpoint to add a new card to the help center.
- `POST /cards`: This should accept the card details (title, description, link) in the request body and create a new card.
- **Get all cards:** Create an endpoint to retrieve all the cards.
- `GET /cards`: This should return a list of all cards in the help center.
- **Get a specific card:** Create an endpoint to retrieve the details of a single card by its title.
- `GET /cards/:title`: This should return the details of a specific card.

4. **Error Handling:**
4. **Error Handling:**
- Implement error handling for cases such as trying to access a non-existent card, validation errors, and server errors.


### Submission:
### Submission:
- Provide the source code in a GitHub repository and on the submission of the form, paste the github link.
- Include a README file with instructions on how to set up and run the project locally.
8 changes: 8 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Server Specific Stuffs
SERVER = http://localhost
PORT = 8000


# Database Specific Stuffs
MONGO_URI = mongodb://127.0.0.1:27017/full-stack-ass
88 changes: 88 additions & 0 deletions backend/CardController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
const CardModel = require("./CardModel");

//------------ Handle the card related logic here
function CardController() {

return {

//--------- Creating a new card , POST '/cards'

async create_card(req, res) {
try {
// console.log('req.body',req.body);
const { title, description, link } = req.body;

if (!title || !description || !link) return res.status(404).json({ success: false, msg: "All fields are required" })

//Check this card is exist
const isCardExist = await CardModel.findOne({ title });

if (isCardExist) return res.status(400).json({ success: false, msg: "Card already exist" })

//o/w create a new card
await CardModel.create({ title, description, link });

return res.status(201).json({ success: true, msg: "Creating a new card successfully" })


} catch (error) { return res.status(500).json({ success: false, msg: error?.message }) }
},


//--------Fetch all cards, 'GET /cards'

async fetch_all_cards(req, res) {
try {
const cards = await CardModel.find();
return res.status(201).json({ success: true, msg: "Fetch all cards successfully", cards })


} catch (error) { return res.status(500).json({ success: false, msg: error?.message }) }
},

//--------Fetch a new card by title, 'GET /cards/:title'

async fetch_card(req, res) {
try {
let { title } = req.params;
if (!title) return res.status(400).json({ success: false, msg: "Title is required to processed further" });

title = title.toLowerCase();

const isCardExist = await CardModel.findOne({ title });

if (!isCardExist) return res.status(500).json({ success: false, msg: "Card not found" });

return res.status(201).json({ success: true, msg: "Fetch card details successfully", card: isCardExist });


} catch (error) { return res.status(500).json({ success: false, msg: error?.message }) }
},
//--------Searching the card data, 'GET /search'

async search_card(req, res) {
try {
let { q } = req.query;
if (!q) return res.status(400).json({ success: false, msg: "Query is required to search card" });

q = q.toLowerCase();

const isCardExist = await CardModel.find({
$or: [
{ title: { $regex: q, $options: 'i' } }, // Case-insensitive search on title
{ description: { $regex: q, $options: 'i' } } // Case-insensitive search on description
]
})

if (!isCardExist || isCardExist.length == 0) return res.status(500).json({ success: false, msg: "Card not found" });

return res.status(201).json({ success: true, msg: "Fetch card details successfully", card: isCardExist });


} catch (error) { return res.status(500).json({ success: false, msg: error?.message }) }
},

}
}

module.exports = CardController;
13 changes: 13 additions & 0 deletions backend/CardModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

const mongoose = require('mongoose')


const CardSchema = new mongoose.Schema({
title: { type: String, required: true ,lowercase:true},
description: { type: String, required: true},
link: { type: String, required: true }
}, { timestamps: true })

const CardModel = mongoose.model('Card', CardSchema)

module.exports = CardModel;
17 changes: 17 additions & 0 deletions backend/CardRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const routers = require('express').Router();


//-------------- Controllers Specific Stuffs
const CardController = require('./CardController');



//-------------Creating all routes here

routers.post('/cards',CardController().create_card); //Creating a new card, 'POST /cards'
routers.get('/cards',CardController().fetch_all_cards); //Fetch all cards, 'GET /cards'
routers.get('/search',CardController().search_card); //Searching the card data, 'GET /search'
routers.get('/cards/:title',CardController().fetch_card); //Fetch a new card by title, 'GET /cards/:title'


module.exports = routers;
9 changes: 9 additions & 0 deletions backend/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

const mongoose = require('mongoose');

//Now connect the database
const mongo_uri = process.env.MONGO_URI || "mongodb://127.0.0.1:27107/full-stack-ass";

mongoose.connect(mongo_uri).
then(() => console.info("Connection to database")).
catch((err) => console.error("Error to connect database: ",err?.message))
20 changes: 20 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "backend",
"version": "1.0.0",
"description": "Creating the assessment solution where our focus to solve backend.md",
"main": "server",
"license": "MIT",
"scripts": {
"start" : "node server",
"dev" : "nodemon server -e js,ejs"
},
"devDependencies": {
"dotenv": "^16.4.5",
"nodemon": "^3.1.4"
},
"dependencies": {
"cors": "^2.8.5",
"express": "^4.19.2",
"mongoose": "^8.5.4"
}
}
31 changes: 31 additions & 0 deletions backend/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

//-------- -Create the express server
const express = require('express')
const app = express();

//-------------- Connect to database
require('dotenv').config();
require('./db')

//------------ Accessing the cors
const cors = require('cors')
app.use(cors());

//------- Handle the body
app.use(express.json())
app.use(express.urlencoded({extended:true}))


//----------- Creating the welcoming routes
app.get('/ping',(req,res)=>{
return res.status(200).json({success:true,msg:"Welcome in full-stack development assessment solution"})
})

//------------- Routes Specific Stuffs
const routes = require('./CardRoutes');
app.use('/',routes);

const Port = process.env.PORT || 8000 ;
const Server = process.env.SERVER || 'http://localhost';

app.listen(Port,()=> console.info(`Application listen at ${Server}:${Port}`));
Loading