Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#7 #8 #10 created new nodejs server with typescript setup; integrated prisma ORM into new nodejs server; added Readme file to new server #11

Merged
merged 2 commits into from
Sep 11, 2024
Merged
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
393 changes: 129 additions & 264 deletions client-app/src/Components/DonorForm.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
# Keep environment variables out of version control
.env
80 changes: 80 additions & 0 deletions server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Development Setup

Follow these steps to set up your development environment.

## Prerequisites

- **Node.js**: Ensure that Node.js is installed on your system. If it's not installed, download and install it from [Node.js Official Website](https://nodejs.org/).

- **PostgreSQL**: Ensure that PostgreSQL is installed on your system. If it's not installed, download and install it from [PostgreSQL Official Website](https://www.postgresql.org/download/).

> **Note**: During PostgreSQL installation, remember to note down the **username** and **password** you set for the PostgreSQL server. You will need these for setting up your `.env` file.

## Step-by-Step Setup

### 1. Set Up PostgreSQL

#### Option 1: Using the Terminal

- **Windows/Linux/Mac**:
- Open your terminal or command prompt.
- Run `psql` to enter the PostgreSQL command line interface.
- Create a new database with the command:
```sql
CREATE DATABASE dbname;
```
- Replace `dbname` with the name you want to give your database.

#### Option 2: Using pgAdmin

- **pgAdmin**:
- Open pgAdmin and connect to your PostgreSQL server.
- Right-click on 'Databases', then select 'Create' -> 'Database'.
- Enter the desired name for your database in the 'Database Name' field and save.

### 2. Create Environment Variables

Create a `.env` file in the root directory of your project and define the necessary environment variables:

```plaintext
DATABASE_URL="postgresql://username:password@localhost:5432/dbname"
```

Replace `username`, `password`, and `dbname` with your PostgreSQL username, password, and the name of the database you created.

### 3. Install Dependencies

Run the following command in your project directory to install required dependencies:

npm install

This command installs all the packages defined in your `package.json` file (both dependencies and devDependencies).

### 4. Run Migrations

To synchronize your database schema with your Prisma model and update the Prisma Client, run:

npx prisma migrate dev

This command applies all pending migrations to your database and updates the Prisma Client to ensure it matches the new schema. This is crucial for keeping all developers' environments in sync with the latest database schema.

### 5. Start the Development Server

Start your development server by running:

npm run dev

This command starts the server using `nodemon`, which will automatically restart the server if any changes are detected in your source files.

### 6. Access the Server

Once the server is running, it will be accessible at:

http://localhost:5000

You can access your API endpoints via this URL using a web browser or tools like Postman for testing API requests.

## Additional Information

- **Keeping Schema in Sync**: It is important to run migrations whenever changes are made to your Prisma models. This keeps your database schema in sync with your application's data model (relevant commands will be added here soon).
- **Environment Variables**: Ensure that your `.env` file is never committed to your version control system. Add it to your `.gitignore` file to prevent it from being uploaded to shared repositories.
33 changes: 33 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node dist/index.js",
"dev": "nodemon src/index.ts",
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@prisma/client": "^5.19.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.20.0",
"joi": "^17.13.3",
"morgan": "^1.10.0"
},
"devDependencies": {
"@types/cookie-parser": "^1.4.7",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/morgan": "^1.9.9",
"@types/node": "^22.5.4",
"nodemon": "^3.1.4",
"prisma": "^5.19.1",
"ts-node": "^10.9.2",
"typescript": "^5.6.2"
}
}
16 changes: 16 additions & 0 deletions server/prisma/migrations/20240911050348_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- CreateTable
CREATE TABLE "Donor" (
"id" SERIAL NOT NULL,
"firstName" VARCHAR(50) NOT NULL,
"lastName" VARCHAR(50) NOT NULL,
"contact" VARCHAR(10),
"email" VARCHAR(100) NOT NULL,
"addressLine1" VARCHAR(50),
"addressLine2" VARCHAR(50),
"state" VARCHAR(15),
"city" VARCHAR(15),
"zipcode" VARCHAR(20) NOT NULL,
"emailOptIn" BOOLEAN NOT NULL,

CONSTRAINT "Donor_pkey" PRIMARY KEY ("id")
);
3 changes: 3 additions & 0 deletions server/prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
28 changes: 28 additions & 0 deletions server/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model Donor {
id Int @id @default(autoincrement())
firstName String @db.VarChar(50)
lastName String @db.VarChar(50)
contact String? @db.VarChar(10)
email String @db.VarChar(100)
addressLine1 String? @db.VarChar(50)
addressLine2 String? @db.VarChar(50)
state String? @db.VarChar(15)
city String? @db.VarChar(15)
zipcode String @db.VarChar(20)
emailOptIn Boolean
}
3 changes: 3 additions & 0 deletions server/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
# Keep environment variables out of version control
.env
55 changes: 55 additions & 0 deletions server/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import createError from 'http-errors';
import express, { Request, Response, NextFunction } from 'express';
import path from 'path';
import cookieParser from 'cookie-parser';
import logger from 'morgan';
import cors from 'cors';

// import indexRouter from './routes/index';
// import usersRouter from './routes/users';
// import donorsListRouter from './routes/donor-details/donorsList';
// import donorModuleRouter from './routes/demo/donorModule';
// import submitFormRouter from './routes/demo/submitForm';
// import emailRouter from './routes/email-service/emailService';
// import adminRouter from './routes/adminRoutes';
import donorRouter from './routes/donorRoutes';

const app = express();

app.use(cors({ origin: 'http://localhost:3000' }));

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// app.use('/', indexRouter);
// app.use('/users', usersRouter);
// app.use('/donorsList', donorsListRouter);
// app.use('/donor-module', donorModuleRouter);
// app.use('/email-service', emailRouter);
// app.use('/submit-form', submitFormRouter);
// app.use('/admin', adminRouter);
app.use('/donor', donorRouter);

app.use((req: Request, res: Response, next: NextFunction) => {
next(createError(404));
});

app.use((err: any, req: Request, res: Response, next: NextFunction) => {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});

const port = process.env.PORT || 5000; // Use environment variable or default to 3001
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});

export default app;
5 changes: 5 additions & 0 deletions server/src/prismaClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// prismaClient.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();
export default prisma;
28 changes: 28 additions & 0 deletions server/src/routes/adminRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Router, Request, Response } from 'express';
import prisma from '../prismaClient'; // Import Prisma client

const router = Router();

router.post('/', async (req: Request, res: Response) => {
try {
const newAdmin = await prisma.admin.create({
data: req.body
});
res.status(201).json(newAdmin);
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Error creating admin' });
}
});

router.get('/', async (req: Request, res: Response) => {
try {
const admins = await prisma.admin.findMany();
res.json(admins);
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Error fetching admins' });
}
});

export default router;
30 changes: 30 additions & 0 deletions server/src/routes/donorRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Router, Request, Response } from 'express';
import prisma from '../prismaClient'; // Import Prisma client
import { donorValidator } from '../validators/donorValidator'

const router = Router();

router.post('/', donorValidator, async (req: Request, res: Response) => {
try {
const newDonor = await prisma.donor.create({
data: req.body
});
console.log('New donor created:', newDonor);
res.status(201).json(newDonor);
} catch (error) {
console.error('Error creating donor:', error);
res.status(500).json({ message: 'Error creating donor' });
}
});

router.get('/', async (req: Request, res: Response) => {
try {
const donors = await prisma.donor.findMany();
res.json(donors);
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Error fetching donors' });
}
});

export default router;
14 changes: 14 additions & 0 deletions server/src/schemas/donorSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Joi from 'joi';

export const donorSchema = Joi.object({
firstName: Joi.string().required(),
lastName: Joi.string().required(),
contact: Joi.string().regex(/^[0-9]{10}$/).allow(''), // Allows empty string or 10-digit number
email: Joi.string().email().required(),
addressLine1: Joi.string().required(),
addressLine2: Joi.string().allow(''),
state: Joi.string().required(),
city: Joi.string().required(),
zipcode: Joi.string().regex(/^[0-9]{5}$/), // 5-digit US ZIP code
emailOptIn: Joi.boolean().required()
});
10 changes: 10 additions & 0 deletions server/src/validators/donorValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Request, Response, NextFunction } from 'express';
import { donorSchema } from '../schemas/donorSchema';

export const donorValidator = (req: Request, res: Response, next: NextFunction) => {
const { error } = donorSchema.validate(req.body);
if (error) {
return res.status(400).json({ message: error.details[0].message });
}
next();
};
17 changes: 17 additions & 0 deletions server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */

/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"module": "commonjs", /* Specify what module code is generated. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */

/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["src/**/*"], // Include all files in the src directory
"exclude": ["node_modules"] // Exclude the node_modules directory
}
Loading